<?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: Ryo Suwito</title>
    <description>The latest articles on DEV Community by Ryo Suwito (@ryo_suwito).</description>
    <link>https://dev.to/ryo_suwito</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%2F2547507%2F174ce629-7ad7-4157-b489-5f06e9ab50fc.png</url>
      <title>DEV Community: Ryo Suwito</title>
      <link>https://dev.to/ryo_suwito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ryo_suwito"/>
    <language>en</language>
    <item>
      <title>Blockchain; The damned and cursed hero we need to tame down the chaotic AI mess</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Tue, 28 Jul 2026 14:20:16 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/blockchain-the-damned-and-cursed-hero-we-need-to-tame-down-the-chaotic-ai-mess-5gfl</link>
      <guid>https://dev.to/ryo_suwito/blockchain-the-damned-and-cursed-hero-we-need-to-tame-down-the-chaotic-ai-mess-5gfl</guid>
      <description>&lt;p&gt;Yeah, I know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blockchain. NFTs. Web3.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three words capable of triggering instant PTSD flashbacks involving monkey JPEGs, celebrity rug pulls, Discord servers, and some guy named &lt;code&gt;CryptoAlphaWolf69&lt;/code&gt; telling everyone to “stay strong, community.”&lt;/p&gt;

&lt;p&gt;This cannot possibly be serious.&lt;/p&gt;

&lt;p&gt;LOL.&lt;/p&gt;

&lt;p&gt;Except the more chaotic generative AI becomes, the more this cursed technology starts looking like the exact infrastructure we accidentally built too early.&lt;/p&gt;

&lt;p&gt;Because AI is about to create a gigantic problem around one extremely boring question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where the hell did this digital thing come from?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And suddenly, boring becomes valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet Bob, the unfortunate maestro
&lt;/h2&gt;

&lt;p&gt;Imagine Bob.&lt;/p&gt;

&lt;p&gt;Bob is an illustrator. He spends three weeks creating a stitched cartoon character with a unique visual style.&lt;/p&gt;

&lt;p&gt;He posts it on Instagram.&lt;/p&gt;

&lt;p&gt;A year later, Bob discovers that someone has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;screenshotted the artwork;&lt;/li&gt;
&lt;li&gt;removed his signature;&lt;/li&gt;
&lt;li&gt;mass-produced it on T-shirts;&lt;/li&gt;
&lt;li&gt;listed it on Etsy;&lt;/li&gt;
&lt;li&gt;uploaded it to Amazon;&lt;/li&gt;
&lt;li&gt;sold stickers on eBay;&lt;/li&gt;
&lt;li&gt;fed it into an AI model;&lt;/li&gt;
&lt;li&gt;generated 700 suspiciously similar characters;&lt;/li&gt;
&lt;li&gt;and somehow made more money from Bob’s work than Bob ever did.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bob complains to the platforms, provides his Instagram screenshot. The seller replies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I made it first.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Who created the original high-resolution version?&lt;/p&gt;

&lt;p&gt;Was the supposedly infringing image copied directly, generated with AI, or merely “inspired” by Bob’s style?&lt;/p&gt;

&lt;p&gt;Bob can cry all day, but his evidence trail is basically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Trust me, bro. Look at this screenshot.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is not a great place to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blockchain is not the judge
&lt;/h2&gt;

&lt;p&gt;This is where people misunderstand the useful version of NFTs.&lt;/p&gt;

&lt;p&gt;An NFT is a receipt. It is evidence, a digital footprint that does not depend entirely on Instagram, Amazon, Bob’s laptop, or some startup continuing to pay its AWS bill until the heat death of the universe.&lt;/p&gt;

&lt;p&gt;Think of CCTV.&lt;/p&gt;

&lt;p&gt;A CCTV company does not care whether the footage records a robbery, a divorce dispute, a workplace accident, or your neighbour stealing your Amazon package.&lt;/p&gt;

&lt;p&gt;The footage simply creates an evidentiary object that investigators, platforms, insurers, lawyers, and courts can evaluate later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then AI kicks the door off its hinges
&lt;/h2&gt;

&lt;p&gt;Copying digital work was already easy. Then Generative AI makes it industrial.&lt;/p&gt;

&lt;p&gt;A user can upload Bob’s artwork into an image generator and request:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Make this character slightly different, wearing sunglasses, riding a dragon, in the style of a premium children’s animation studio.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Five seconds later, Bob is no longer fighting one stolen image.&lt;/p&gt;

&lt;p&gt;He is fighting an infinite mutation factory.&lt;/p&gt;

&lt;p&gt;The infringement may no longer be pixel-for-pixel identical. It could be transformed, cropped, recoloured, restyled, combined with other works, or reconstructed from visual features.&lt;/p&gt;

&lt;p&gt;Welcome to the synthetic-media circus.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-way evidence machine
&lt;/h2&gt;

&lt;p&gt;Now imagine a Midjourney-like platform that takes provenance seriously.&lt;/p&gt;

&lt;p&gt;One insomniac engineer drinks three cans of Jack Daniel’s and Coke, walks into a meeting, and yells:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“WHAT IF WE PUT THE DAMN RECEIPTS ON-CHAIN?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The CTO laughs.&lt;br&gt;
The VC pauses.&lt;br&gt;
Someone makes a slide deck.&lt;/p&gt;

&lt;p&gt;Six months later, the company announces &lt;strong&gt;Trusted Creative Provenance™&lt;/strong&gt;, carefully avoiding the letters N, F, and T.&lt;/p&gt;

&lt;p&gt;The system could work in both directions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Before generation
&lt;/h3&gt;

&lt;p&gt;A user uploads an image as a reference.&lt;/p&gt;

&lt;p&gt;The platform creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an exact cryptographic hash;&lt;/li&gt;
&lt;li&gt;a perceptual fingerprint;&lt;/li&gt;
&lt;li&gt;an embedding for visual similarity;&lt;/li&gt;
&lt;li&gt;a record of declared ownership or licensing;&lt;/li&gt;
&lt;li&gt;a comparison against registered works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the uploaded image strongly resembles Bob’s registered artwork, the platform can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;warn the user;&lt;/li&gt;
&lt;li&gt;limit commercial generation;&lt;/li&gt;
&lt;li&gt;request proof of licensing;&lt;/li&gt;
&lt;li&gt;offer a licensing pathway;&lt;/li&gt;
&lt;li&gt;attach the source relationship to the generated result;&lt;/li&gt;
&lt;li&gt;or block the request entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The blockchain is not performing the AI image search. That would be absurdly inefficient. The AI system performs the search.&lt;/p&gt;

&lt;p&gt;The chain preserves the claims, timestamps, licences, identities, and resulting evidence.&lt;/p&gt;
&lt;h3&gt;
  
  
  During generation
&lt;/h3&gt;

&lt;p&gt;Every generated image can receive a signed provenance record containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the output file hash;&lt;/li&gt;
&lt;li&gt;the generation timestamp;&lt;/li&gt;
&lt;li&gt;the model and version used;&lt;/li&gt;
&lt;li&gt;hashes of reference images;&lt;/li&gt;
&lt;li&gt;the account or verified identity that requested it;&lt;/li&gt;
&lt;li&gt;the platform’s cryptographic signature;&lt;/li&gt;
&lt;li&gt;the declared licensing terms;&lt;/li&gt;
&lt;li&gt;the editing history;&lt;/li&gt;
&lt;li&gt;and links to previous versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The user does not need to understand wallets. They do not need to chant “Web3.”&lt;/p&gt;

&lt;p&gt;They do not need to hold a cartoon ape.&lt;/p&gt;

&lt;p&gt;They click &lt;strong&gt;Generate&lt;/strong&gt;, and the platform quietly creates the receipt.&lt;/p&gt;

&lt;p&gt;The interface might simply say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Verified generation history available&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Very corporate and boring but potentially very valuable.&lt;/p&gt;
&lt;h3&gt;
  
  
  After abuse occurs
&lt;/h3&gt;

&lt;p&gt;Now imagine someone generates a fabricated image of a politician, celebrity, CEO, journalist, or random private citizen doing something they never did.&lt;/p&gt;

&lt;p&gt;Investigators run AI-powered visual search across public databases, platforms, and provenance registries.&lt;/p&gt;

&lt;p&gt;The system finds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visually related images;&lt;/li&gt;
&lt;li&gt;earlier versions;&lt;/li&gt;
&lt;li&gt;source assets;&lt;/li&gt;
&lt;li&gt;generation records;&lt;/li&gt;
&lt;li&gt;editing steps;&lt;/li&gt;
&lt;li&gt;wallet attestations;&lt;/li&gt;
&lt;li&gt;platform signatures;&lt;/li&gt;
&lt;li&gt;and the first known timestamp.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the creator used a KYC-verified account, the public does not necessarily need to see the creator’s passport or home address.&lt;/p&gt;

&lt;p&gt;Instead, the public record can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This account’s identity was verified by Provider X.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, through proper legal or platform procedures, the responsible identity can be disclosed when necessary.&lt;/p&gt;
&lt;h2&gt;
  
  
  “Why not just use DynamoDB?”
&lt;/h2&gt;

&lt;p&gt;Because, yes, technically, you can.&lt;/p&gt;

&lt;p&gt;You can store every claim in DynamoDB or PostgreSQL.&lt;/p&gt;

&lt;p&gt;You can put it in an Excel file if you are sufficiently unhinged.&lt;/p&gt;

&lt;p&gt;The technical problem is not whether a database can store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bob registered image hash ABC123 at 14:32.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course it can. The real problem is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Who keeps paying to preserve that record for the next 30, 50, or 100 years?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Who guarantees that the company will not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shut down;&lt;/li&gt;
&lt;li&gt;get acquired;&lt;/li&gt;
&lt;li&gt;delete unprofitable records;&lt;/li&gt;
&lt;li&gt;alter disputed entries;&lt;/li&gt;
&lt;li&gt;lose the backups;&lt;/li&gt;
&lt;li&gt;change its terms;&lt;/li&gt;
&lt;li&gt;block access in certain countries;&lt;/li&gt;
&lt;li&gt;or decide that storing 400 billion abandoned provenance records is not commercially attractive?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS has enormous infrastructure, but it does not have a moral obligation to preserve Bob’s cartoon receipt forever.&lt;/p&gt;

&lt;p&gt;Neither does Instagram. Neither does Etsy. Neither does the AI startup that generated the derivative image.&lt;/p&gt;

&lt;p&gt;A centralised registry can work brilliantly while the company operating it remains trustworthy, solvent, and interested.&lt;/p&gt;

&lt;p&gt;The blockchain proposition is different.&lt;/p&gt;

&lt;p&gt;It says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Let us create an economic system where thousands of strangers preserve shared state for selfish reasons.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds terrible LOL, but it also happens to be useful.&lt;/p&gt;

&lt;p&gt;Let's be honest, validators want fees. Token holders want network value. Storage providers want payment.&lt;br&gt;
&lt;strong&gt;Everyone want a piece of cake&lt;/strong&gt;.&lt;br&gt;
Nobody needs to care personally about Bob.&lt;/p&gt;

&lt;p&gt;Their greed keeps the machinery alive.&lt;/p&gt;

&lt;p&gt;That may be blockchain’s most underappreciated feature:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The record survives not because everyone is good, but because enough people are economically motivated to preserve the system.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Crooked incentives can produce surprisingly durable infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nobody will call it an NFT
&lt;/h2&gt;

&lt;p&gt;This may be the funniest part.&lt;/p&gt;

&lt;p&gt;The technology might win only after everyone stops using the name.&lt;/p&gt;

&lt;p&gt;Shutterstock will not announce:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Shutterstock NFT ApeChain Creator Moon Vault.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please, God, no.&lt;/p&gt;

&lt;p&gt;It will announce something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Shutterstock Provenance: register, license, verify, and track creative assets.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Adobe might call it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Authenticity Credentials&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A film studio might call it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Digital Asset Chain of Custody&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A marketplace might call it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Verified Original Listing&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI company might call it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Generation Trace&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An insurer might call it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Creative Rights Evidence Infrastructure&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Underneath the respectable corporate vocabulary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cryptographic tokens;&lt;/li&gt;
&lt;li&gt;distributed ledgers;&lt;/li&gt;
&lt;li&gt;content-addressed storage;&lt;/li&gt;
&lt;li&gt;smart contracts;&lt;/li&gt;
&lt;li&gt;wallet attestations;&lt;/li&gt;
&lt;li&gt;and automated licensing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same damned machinery. New suit. Less monkey.&lt;/p&gt;

&lt;h2&gt;
  
  
  The monkey JPEG PTSD may be the opportunity
&lt;/h2&gt;

&lt;p&gt;That trauma is understandable and may prevent people from noticing when the underlying infrastructure gets repurposed.&lt;/p&gt;

&lt;p&gt;The crowd is staring at the corpse of NFT speculation. Meanwhile, AI is quietly creating the strongest practical argument for digital provenance that the internet has ever seen.&lt;/p&gt;

&lt;p&gt;The opportunity, if there is one, may come from the delay.&lt;/p&gt;

&lt;p&gt;Startups need time to realise what product to build. Creators need time to trust it. Platforms need time to integrate it. Studios need time to establish workflows. Courts need time to interpret it.&lt;/p&gt;

&lt;p&gt;Regulators need approximately 700 years and several committee hearings to decide what the words mean.&lt;/p&gt;

&lt;p&gt;During that lag, everyone remains convinced the entire field is dead.&lt;/p&gt;

&lt;p&gt;Maybe it is.&lt;/p&gt;

&lt;p&gt;Or maybe the label is dead while the infrastructure waits for its actual job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The damned and cursed hero
&lt;/h2&gt;

&lt;p&gt;Blockchain does not need to save democracy. It does not need to replace every bank. It does not need to decentralise your toaster.&lt;/p&gt;

&lt;p&gt;It only needs to become useful in places where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;records must survive;&lt;/li&gt;
&lt;li&gt;parties do not fully trust each other;&lt;/li&gt;
&lt;li&gt;no single company should own the entire history;&lt;/li&gt;
&lt;li&gt;timestamps matter;&lt;/li&gt;
&lt;li&gt;tampering matters;&lt;/li&gt;
&lt;li&gt;and preserving shared evidence creates long-term value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The coming AI mess checks a suspicious number of those boxes.&lt;/p&gt;

&lt;p&gt;So yes, the idea sounds ridiculous:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use the technology famous for monkey JPEG speculation to help control AI plagiarism, trace deepfakes, register digital rights, document creative history, and provide evidence across platforms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LOL.&lt;/p&gt;

&lt;p&gt;Absolutely cursed. Possibly inevitable.&lt;/p&gt;

&lt;p&gt;And somewhere, right now, an insomniac developer is opening a pitch deck and typing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Blockchain-powered intellectual-property provenance for the synthetic-media economy.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The VC will stare at it. The CTO will swear. The product manager will remove the word “blockchain.”&lt;/p&gt;

&lt;p&gt;They will call it &lt;strong&gt;TrustLayer AI™&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And everyone will pretend this was never an NFT idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That is when the damned thing might finally make money.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>blockchain</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Endgame of AI Open Weights Is Not for Us GPU Plebs</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Tue, 21 Jul 2026 07:40:50 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/the-endgame-of-ai-open-weights-is-not-for-us-gpu-plebs-290e</link>
      <guid>https://dev.to/ryo_suwito/the-endgame-of-ai-open-weights-is-not-for-us-gpu-plebs-290e</guid>
      <description>&lt;p&gt;Daaamn, bro.&lt;/p&gt;

&lt;p&gt;For the last few years, whenever an AI lab released an open-weight model, the developer community reacted like someone had just air-dropped freedom into our basements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Can my RTX run this thing?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a while, that was the dream.&lt;/p&gt;

&lt;p&gt;A frontier-ish model running locally. No API bill. No corporate gatekeeper. No mysterious model update ruining your workflow overnight. Just you, your GPU and our beloved &lt;code&gt;llama.cpp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But I am starting to think we misunderstood the endgame.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The future of open weights may not be about helping individual developers run increasingly powerful models at home. Maybe it's all about helping someone else build the infrastructure required to run them at industrial scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Frontiers, Two Strategies
&lt;/h2&gt;

&lt;p&gt;At the moment, the Western and Eastern AI frontiers appear to be moving in very different directions.The Western frontier is increasingly obsessed with keeping the beast inside the walled garden.&lt;/p&gt;

&lt;p&gt;The strongest models live behind APIs, subscriptions, product tiers, safety evaluations, regional restrictions, usage policies, and whatever new compliance ritual appeared this week.&lt;/p&gt;

&lt;p&gt;Meanwhile, several Eastern AI labs appear to be asking something closer to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What happens if we release the beast and let the ecosystem figure out how to feed it?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That difference matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The “Dangerous Model” Saga Is Getting Weird
&lt;/h2&gt;

&lt;p&gt;Whenever a powerful open-weight model appears, the same argument returns.&lt;/p&gt;

&lt;p&gt;It is too dangerous.&lt;br&gt;
It can write malware.&lt;br&gt;
bla bla bla...boring&lt;/p&gt;

&lt;p&gt;Sure. Those risks are real.&lt;/p&gt;

&lt;p&gt;But when you look deeper, some of the public discourse starts sounding less like safety analysis and more like strategic fearmongering.&lt;/p&gt;

&lt;p&gt;Because the convenient conclusion is almost always the same:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The model is dangerous, therefore the model must remain under the control of the company that built it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, damn. How fortunate for the company.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then Why Release a Gigantic Model for Free?
&lt;/h2&gt;

&lt;p&gt;This is the part that kept bothering me.&lt;/p&gt;

&lt;p&gt;Training frontier models costs a ridiculous amount of money. Then, after spending all that money, you release the weights?&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;My shower thought is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Models may become free, but compute never will.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That changes the business model completely.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal May Be to Become the AWS of AI
&lt;/h2&gt;

&lt;p&gt;Suppose a lab releases an extremely capable open-weight model. Immediately, developers start experimenting with it, Researchers benchmark it.&lt;/p&gt;

&lt;p&gt;Then the money keeps pouring in:&lt;/p&gt;

&lt;p&gt;Cloud providers race to support it.&lt;br&gt;
Hosting platforms advertise it.&lt;br&gt;
Enterprise vendors build private deployments around it.&lt;br&gt;
Consulting firms start selling integration packages.&lt;/p&gt;

&lt;p&gt;Suddenly, the entire ecosystem is spending money to create infrastructure for the lab’s model.&lt;/p&gt;

&lt;p&gt;That open-weight release creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;demand for inference,&lt;/li&gt;
&lt;li&gt;demand for optimized kernels,&lt;/li&gt;
&lt;li&gt;demand for GPU clusters,&lt;/li&gt;
&lt;li&gt;demand for managed endpoints,&lt;/li&gt;
&lt;li&gt;demand for fine-tuning,&lt;/li&gt;
&lt;li&gt;demand for monitoring,&lt;/li&gt;
&lt;li&gt;demand for enterprise support,&lt;/li&gt;
&lt;li&gt;and demand for specialized deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once enough infrastructure is organized around your model family, you gain leverage. That is a very different game. And frankly, it may be more sustainable than trying to own every layer yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Weights as Infrastructure Subsidy
&lt;/h2&gt;

&lt;p&gt;Western frontier labs often try to do nearly everything internally.&lt;/p&gt;

&lt;p&gt;Train and Host the model.&lt;br&gt;
Build the API and the consumer app.&lt;br&gt;
Build the enterprise product and the agent platform.&lt;br&gt;
You name it..&lt;/p&gt;

&lt;p&gt;But holy crap, that is a lot of surface area. The open-weight strategy distributes some of that burden. Instead of paying to build every possible deployment configuration, a lab can release the weights and let the market explore them.&lt;/p&gt;

&lt;p&gt;Cloud companies figure out serving.&lt;br&gt;
Startups build specialized interfaces.&lt;br&gt;
Developers create integrations.&lt;/p&gt;

&lt;p&gt;That may be the real genius of the strategy. Open weights can function as a subsidy for future compute demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Model Is Free. The Cluster Is Not.
&lt;/h2&gt;

&lt;p&gt;This is where the dream of local AI starts colliding with physics.&lt;/p&gt;

&lt;p&gt;A model can be legally downloadable and still be practically inaccessible.&lt;/p&gt;

&lt;p&gt;The architecture may use sparse activation and clever efficiency tricks, but the total system may still require enormous memory, high-bandwidth interconnects, specialized kernels, distributed inference, and a painful amount of engineering.&lt;/p&gt;

&lt;p&gt;Sure, someone will quantize it.&lt;/p&gt;

&lt;p&gt;Someone always quantizes it.&lt;/p&gt;

&lt;p&gt;There will be an &lt;code&gt;IQ1_S_DAMN_NEAR_BINARY&lt;/code&gt; version uploaded by a wizard with an anime avatar.&lt;/p&gt;

&lt;p&gt;And technically, perhaps, it will run. At 0.4 tokens per second. With half the layers on CPU. While your RAM begs for death.&lt;/p&gt;

&lt;p&gt;Congratulations, bro. You are sovereign now.&lt;/p&gt;

&lt;p&gt;Free as in weights.&lt;br&gt;
Expensive as hell as in reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Eastern Labs Are Not Stupid
&lt;/h2&gt;

&lt;p&gt;It would be naive to assume that labs releasing open weights simply forgot how capitalism works. The open release may be the customer-acquisition strategy.&lt;/p&gt;

&lt;p&gt;Not only for individual developers, but for the infrastructure providers who will eventually serve those developers.&lt;/p&gt;

&lt;p&gt;Today:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here are the weights.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tomorrow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here is the officially supported deployment stack.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Later:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here is our premium model license, enterprise runtime, certified hosting network, and revenue-sharing agreement.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Open weights are still valuable.&lt;/p&gt;

&lt;p&gt;They improve transparency, enable research, create competitive pressure against closed platforms. Whatever...&lt;/p&gt;

&lt;p&gt;The weights may be free.&lt;br&gt;
The future invoices will not be.&lt;/p&gt;

&lt;p&gt;So no, the endgame of AI open weights may no longer fit inside your RTX bullcrap.&lt;/p&gt;

&lt;p&gt;And it may definitely not fit in your mom’s basement with ComfyUI running in the background.&lt;/p&gt;

&lt;p&gt;Welcome to the cloud, GPU plebs.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Cope, the Lie, and the No-Hope Post-AI Era</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Fri, 10 Jul 2026 16:32:24 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/the-cope-the-lie-and-the-no-hope-post-ai-era-24n0</link>
      <guid>https://dev.to/ryo_suwito/the-cope-the-lie-and-the-no-hope-post-ai-era-24n0</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;No, AI did not take your job.&lt;/p&gt;

&lt;p&gt;It just doubled your workload while quietly kicking Bob off the employment wheel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preamble: What the Fuck Are We Even Doing Here?
&lt;/h2&gt;

&lt;p&gt;AI is not some yesteryear tech.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;not&lt;/strong&gt; immature.&lt;/p&gt;

&lt;p&gt;If you think AI means whatever OpenAI and Anthropic have been churning out since 2023, I am sorry, dude, but this thing started way back when we were still sperm.&lt;/p&gt;

&lt;p&gt;Literally decades ago.&lt;/p&gt;

&lt;p&gt;The hype came and went. Promises got inflated. Products underdelivered.&lt;/p&gt;

&lt;p&gt;Classic tech cycle.&lt;/p&gt;

&lt;p&gt;Claude Shannon and countless other researchers poured their days, nights, careers, and probably sanity into trying to make a damn rock think.&lt;/p&gt;

&lt;p&gt;And now you discredit all of that by calling it a slop machine.&lt;/p&gt;

&lt;p&gt;Clap.&lt;/p&gt;

&lt;p&gt;Clap.&lt;/p&gt;

&lt;p&gt;Clap.&lt;/p&gt;

&lt;p&gt;Today’s AI is arguably as mature as the internet itself, at least if you compare their trajectories fairly.&lt;/p&gt;

&lt;p&gt;The progression is beyond insane. Your brain just cannot comprehend the scale of it, so it compresses everything into: “Eh, autocomplete with extra steps.”&lt;/p&gt;

&lt;p&gt;That is like saying the Big Bang theory was just some guy daydreaming too hard.&lt;/p&gt;

&lt;p&gt;But for the first time in all those decades, something has materially changed.&lt;/p&gt;

&lt;p&gt;In 2026, Bob really is being replaced by an unknown entity roaming around a datacenter somewhere.&lt;/p&gt;

&lt;p&gt;Not because the entity does Bob’s exact job perfectly.&lt;/p&gt;

&lt;p&gt;It does not need to.&lt;/p&gt;

&lt;p&gt;It only needs to do enough of Bob’s work, reliably enough, that Alice can now handle what used to require Alice, Bob, and half of Charlie.&lt;/p&gt;

&lt;p&gt;The company does not need zero Bobs.&lt;/p&gt;

&lt;p&gt;It just needs fewer Bobs.&lt;/p&gt;

&lt;p&gt;Cope as hard as you want.&lt;/p&gt;

&lt;p&gt;The burn has already happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lie: Damn, Snake-Oil Sellers Love This One
&lt;/h2&gt;

&lt;p&gt;They told you companies would replace Bob with a digital Bob.&lt;/p&gt;

&lt;p&gt;Nah.&lt;/p&gt;

&lt;p&gt;That was never the real play.&lt;/p&gt;

&lt;p&gt;The quality is okay. Sometimes impressive. Sometimes garbage. Current mid-to-top-tier models can maybe exceed baseline human ability in certain tasks, especially because they do not get tired, wake up pissed off, take sick leave, or spend half the afternoon doomscrolling.&lt;/p&gt;

&lt;p&gt;But here is the part AI labs rarely say out loud:&lt;/p&gt;

&lt;p&gt;You are probably too broke to afford the version that actually replaces Bob.&lt;/p&gt;

&lt;p&gt;Dude, seriously.&lt;/p&gt;

&lt;p&gt;The trap is in the pricing.&lt;/p&gt;

&lt;p&gt;Technically, the labs trapped themselves too.&lt;/p&gt;

&lt;p&gt;It goes something like this:&lt;/p&gt;

&lt;p&gt;First, they seduce everyone with subsidized pricing.&lt;/p&gt;

&lt;p&gt;Then some CTO storms into a meeting, bangs the desk, and tells the CFO:&lt;/p&gt;

&lt;p&gt;“See? Digital Bob only costs us $200 a month. Let’s cut half of those sleazy developers.”&lt;/p&gt;

&lt;p&gt;Easy, right?&lt;/p&gt;

&lt;p&gt;Not exactly.&lt;/p&gt;

&lt;p&gt;In some parts of the world, maybe the math works.&lt;/p&gt;

&lt;p&gt;But the catch is globalization.&lt;/p&gt;

&lt;p&gt;These companies want to capture the biggest possible total addressable market. That means serving every kind of company, in every country, at wildly different levels of purchasing power.&lt;/p&gt;

&lt;p&gt;That disparity becomes brutal when they eventually pump the brakes on flat-rate subsidies.&lt;/p&gt;

&lt;p&gt;Let’s do some napkin math.&lt;/p&gt;

&lt;p&gt;A current $200 subscription, when abused by a genuinely heavy professional user, might consume more than $1,000 worth of tokens if the same usage were billed directly through an API.&lt;/p&gt;

&lt;p&gt;For a well-funded company in the American Midwest, $1,000 a month might still sound cheap.&lt;/p&gt;

&lt;p&gt;Globally?&lt;/p&gt;

&lt;p&gt;LOL.&lt;/p&gt;

&lt;p&gt;In plenty of countries, a junior or mid-level employee sits in roughly the same pricing bucket.&lt;/p&gt;

&lt;p&gt;So why spend all day yelling at a machine when you can yell at the real Bob after he deletes the production database on a Friday afternoon?&lt;/p&gt;

&lt;p&gt;You pay roughly the same amount, Bob understands office politics, and you can sue him.&lt;/p&gt;

&lt;p&gt;Good luck suing an AI lab after its model confidently wipes out your business.&lt;/p&gt;

&lt;h2&gt;
  
  
  There Is No Hope. Seriously.
&lt;/h2&gt;

&lt;p&gt;If your biggest cope is hoping AI will fade away like NFTs, crypto hype, or RepRap-style desktop manufacturing dreams, then, bro, you have not been following technology for very long.&lt;/p&gt;

&lt;p&gt;Those things are niche.&lt;/p&gt;

&lt;p&gt;A lot of them are solutions wandering around looking for a problem.&lt;/p&gt;

&lt;p&gt;AI is harder to kill because it already solves real problems.&lt;/p&gt;

&lt;p&gt;Take the dumbest, smallest use case possible.&lt;/p&gt;

&lt;p&gt;This dev.to article needs a stock image.&lt;/p&gt;

&lt;p&gt;Your mom’s secret-recipe YouTube video needs a thumbnail.&lt;/p&gt;

&lt;p&gt;You search Google Images. You scroll Pinterest. Everything looks almost right, but not quite.&lt;/p&gt;

&lt;p&gt;Then, bam.&lt;/p&gt;

&lt;p&gt;You open an image generator, type the chaos inside your brain, wait a few seconds, and you are done.&lt;/p&gt;

&lt;p&gt;You slap the result onto your content.&lt;/p&gt;

&lt;p&gt;Problem.&lt;/p&gt;

&lt;p&gt;Solved.&lt;/p&gt;

&lt;p&gt;That alone is enough to make this stuff sticky.&lt;/p&gt;

&lt;p&gt;AI is going to cling to society like your shirt after a Sunday jogging session.&lt;/p&gt;

&lt;p&gt;It is not fading away.&lt;/p&gt;

&lt;p&gt;And no, that does not mean all the Bobs eventually get their jobs back.&lt;/p&gt;

&lt;p&gt;Nah.&lt;/p&gt;

&lt;p&gt;Nada.&lt;/p&gt;

&lt;p&gt;This is harsh. It is heartbreaking.&lt;/p&gt;

&lt;p&gt;But I am not here to lead a support-group session.&lt;/p&gt;

&lt;p&gt;Remember the women working telephone switchboards in the early days of telecom?&lt;/p&gt;

&lt;p&gt;At one point, they were among the busiest workers in the system, manually connecting landline calls from one John to another John.&lt;/p&gt;

&lt;p&gt;Then they were replaced by a damn box.&lt;/p&gt;

&lt;p&gt;Switches. Multiplexers. Automated exchanges.&lt;/p&gt;

&lt;p&gt;Their jobs did not become easier.&lt;/p&gt;

&lt;p&gt;Their profession became obsolete.&lt;/p&gt;

&lt;p&gt;So here is the only question that matters:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to become one of them in 2026?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Logic-Graph Verification System</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Thu, 02 Jul 2026 07:27:02 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/logic-graph-verification-system-1n63</link>
      <guid>https://dev.to/ryo_suwito/logic-graph-verification-system-1n63</guid>
      <description>&lt;p&gt;&lt;strong&gt;Status:&lt;/strong&gt; Draft v1 · 2026-07-02&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; design session (Claude Fable 5) &lt;br&gt;
&lt;strong&gt;Implementer:&lt;/strong&gt; any capable coding model, per &lt;code&gt;SYSTEM-DESIGN.md&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. One-liner
&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%2F8boq3422i1wk5mlvrk5w.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%2F8boq3422i1wk5mlvrk5w.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Convert the cheap token throughput of open-weight thinking models into &lt;em&gt;verified&lt;/em&gt; conclusions, by externalizing their reasoning as a graph, sampling it N independent times, and letting mechanical graph checks — not model vibes — decide what survives.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Problem
&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%2Fzg4jog34h8arv8rjb0gz.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%2Fzg4jog34h8arv8rjb0gz.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Self-correction by prompting fails.&lt;/strong&gt; Re-feeding a model its own chain-of-thought ("let's revisit...") makes it anchor to its own tokens and rubber-stamp itself. Known result (Huang et al., "LLMs Cannot Self-Correct Reasoning Yet").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tokens/sec is a garbage metric.&lt;/strong&gt; A cheap model emitting 1M tokens of confident nonsense is worth less than nothing. The metric that matters is &lt;strong&gt;correct conclusions per dollar&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification-by-LLM inherits the problem.&lt;/strong&gt; Asking a model "is this true?" just moves the vibes one level up. We need checks that are &lt;em&gt;mechanical&lt;/em&gt; — computable, deterministic, not model-judged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap models confabulate from pretraining.&lt;/strong&gt; A system whose claims must trace to imported sources cannot tolerate a model that silently answers from its weights.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  3. Core insights (the product thesis)
&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%2F9hdh0jhgtuvkwd030z9c.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%2F9hdh0jhgtuvkwd030z9c.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shape is checkable even when truth isn't.&lt;/strong&gt; An argument externalized as a directed graph admits mechanical checks: unsupported premises (orphans), circular reasoning (cycles), disconnected conclusions (reachability), refuted-claims-still-load-bearing.&lt;/li&gt;
&lt;/ul&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%2Fa8kyjkv6uyycbw9se3yi.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%2Fa8kyjkv6uyycbw9se3yi.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Truthiness" becomes topology.&lt;/strong&gt; Confidence in a conclusion ∝ how many &lt;em&gt;node-disjoint&lt;/em&gt; chains connect evidence to it (Menger's theorem). One road to Rome = fragile; three independent roads = an adversary must break three separate claims.&lt;/li&gt;
&lt;/ul&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%2Fedx3uf6grhvp8a4plzz9.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%2Fedx3uf6grhvp8a4plzz9.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Independence is sampled, not requested.&lt;/strong&gt; Asking one context for "3 independent arguments" yields the same argument paraphrased 3 times. Asking &lt;strong&gt;N independent inference calls&lt;/strong&gt; (fresh context, temperature &amp;gt; 0) yields genuinely decorrelated attempts — the detective's technique: separate interrogations, then cross-examine. Contradictions between runs are the interrogation slip-ups; they are invisible inside any single transcript.&lt;/li&gt;
&lt;/ul&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%2F7zn6d2p9maocs42b7jcd.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%2F7zn6d2p9maocs42b7jcd.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct attention, don't diffuse it.&lt;/strong&gt; "Revisit your reasoning" makes a model skim everything shallowly. "Edge 7 is load-bearing and unverified" makes it spend its whole budget on the right spot. Min-cut/betweenness computes where that spot is.&lt;/li&gt;
&lt;/ul&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%2F484cv5l4bx0y408nxu61.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%2F484cv5l4bx0y408nxu61.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The formalization tax is a feature.&lt;/strong&gt; A vague step becomes visibly vague when it must be written as a typed node with typed edges.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  4. Users &amp;amp; use cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary user:&lt;/strong&gt; a developer/researcher running multi-step reasoning or research-over-documents workloads on cheap open-weight models (via OpenRouter or local inference), who needs reliability without frontier-model prices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use cases:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;U1: Multi-hop question answering over provided documents, with an auditable argument graph as output.&lt;/li&gt;
&lt;li&gt;U2: Claim verification — "here is a conclusion; how much would have to be wrong for it to fail?"&lt;/li&gt;
&lt;li&gt;U3: As an MCP tool available to any agent, giving it external working memory for arguments plus structural self-checks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  5. Goals &amp;amp; success metrics
&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;Goal&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;G1&lt;/td&gt;
&lt;td&gt;Screening identifies grounded models&lt;/td&gt;
&lt;td&gt;screen produces grounded% / memorized% / abstain% per model&lt;/td&gt;
&lt;td&gt;screen runs end-to-end &amp;lt; $1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G2&lt;/td&gt;
&lt;td&gt;System beats naive self-correction&lt;/td&gt;
&lt;td&gt;accuracy on eval set vs "revisit" and verbatim re-injection arms&lt;/td&gt;
&lt;td&gt;≥ +5pp at equal or lower cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G3&lt;/td&gt;
&lt;td&gt;Cheap ensemble beats one big call&lt;/td&gt;
&lt;td&gt;correct-per-dollar vs one frontier-class call&lt;/td&gt;
&lt;td&gt;≥ 2× correct-per-dollar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G4&lt;/td&gt;
&lt;td&gt;Confidence is calibrated by structure&lt;/td&gt;
&lt;td&gt;conclusions with support width ≥ 2 are correct more often than width 1&lt;/td&gt;
&lt;td&gt;monotone relationship observed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G5&lt;/td&gt;
&lt;td&gt;Auditable output&lt;/td&gt;
&lt;td&gt;every conclusion ships with its graph: surviving claims, width, disputed nodes&lt;/td&gt;
&lt;td&gt;100% of runs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  6. Non-goals
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not a truth oracle.&lt;/strong&gt; The graph verifies argument &lt;em&gt;shape&lt;/em&gt;; every edge is semantically vouched for only by a model. Validly-connected garbage passes structure checks — by design, the structural layer only decides &lt;em&gt;where&lt;/em&gt; semantic effort (re-interrogation) goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No fine-tuning, no inference-loop surgery.&lt;/strong&gt; Everything works through standard chat-completions + tool calls. No custom sampling, no template hacking, no stop-at-&lt;code&gt;&amp;lt;/think&amp;gt;&lt;/code&gt; interception.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No persistence.&lt;/strong&gt; Graphs are session-scoped and ephemeral (in-memory). No database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a general theorem prover.&lt;/strong&gt; Natural-language claims, heuristic dedup — not formal logic.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  System Design
&lt;/h2&gt;


&lt;h2&gt;
  
  
  1. Architecture
&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%2Fd66y9u90gqnk6mc8fv7q.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%2Fd66y9u90gqnk6mc8fv7q.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two deployment modes for the graph server, same codebase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Library mode&lt;/strong&gt; (default for orchestrator): orchestrator imports &lt;code&gt;graph_server.store&lt;/code&gt; directly, no MCP transport. Simpler, faster, use for P3/P4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP mode&lt;/strong&gt;: &lt;code&gt;server.py&lt;/code&gt; exposes the same functions as MCP tools over stdio, so any MCP-capable agent (Claude Code, etc.) can use the graph as external working memory. Thin wrapper only — zero logic in the transport layer.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  2. Component A — Grounding screen (P1, exists)
&lt;/h2&gt;

&lt;p&gt;Already implemented at repo root: &lt;code&gt;screen.py&lt;/code&gt;, &lt;code&gt;items.jsonl&lt;/code&gt; (50 items), &lt;code&gt;models.json&lt;/code&gt;. Contract: temperature 0, 1 call/item/model, regex-graded. See &lt;code&gt;README.md&lt;/code&gt;. Output feeds one decision: &lt;strong&gt;which model id the orchestrator defaults to&lt;/strong&gt;. Do not modify except to fix bugs.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Component B — Graph server (P2)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  3.1 Data model
&lt;/h3&gt;

&lt;p&gt;In-memory only. One &lt;code&gt;GraphStore&lt;/code&gt; holds many independent graphs keyed by &lt;code&gt;graph_id&lt;/code&gt; (string, caller-supplied).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;            &lt;span class="c1"&gt;# caller-supplied, unique within graph, e.g. "r2:n4" (run 2, node 4)
&lt;/span&gt;  &lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;         &lt;span class="c1"&gt;# natural-language claim, one sentence
&lt;/span&gt;  &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;          &lt;span class="c1"&gt;# "given" | "inference" | "assumption" | "conclusion"
&lt;/span&gt;  &lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;  &lt;span class="c1"&gt;# 0.0-1.0, model-stated, default 0.8
&lt;/span&gt;  &lt;span class="n"&gt;run_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# provenance: which interrogation runs asserted this claim
&lt;/span&gt;  &lt;span class="n"&gt;refuted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;      &lt;span class="c1"&gt;# default False, set only via mark_refuted
&lt;/span&gt;  &lt;span class="n"&gt;refute_reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="n"&gt;aliases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# claims of nodes merged into this one (dedup provenance)
&lt;/span&gt;
&lt;span class="n"&gt;Edge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
  &lt;span class="n"&gt;relation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;      &lt;span class="c1"&gt;# "supports" | "attacks" | "assumes"
&lt;/span&gt;  &lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;  &lt;span class="c1"&gt;# 0.0-1.0, default 0.8
&lt;/span&gt;  &lt;span class="n"&gt;run_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Backed by one &lt;code&gt;networkx.MultiDiGraph&lt;/code&gt; per graph_id (multi because supports and attacks may both exist between the same pair). Node attrs hold the Node fields; edge attrs hold relation/confidence/run_ids.&lt;/p&gt;

&lt;p&gt;Validation on ingest (reject with error message, don't crash): unknown &lt;code&gt;type&lt;/code&gt;/&lt;code&gt;relation&lt;/code&gt;, edge endpoints not in graph after this ingest, confidence outside [0,1], duplicate node id with &lt;em&gt;different&lt;/em&gt; claim text (same id + same claim = idempotent, merge run_ids).&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Public functions / MCP tools
&lt;/h3&gt;

&lt;p&gt;Eight functions. Signatures below are the library API; MCP tool schemas mirror them 1:1 with &lt;code&gt;graph_id&lt;/code&gt; always the first param.&lt;/p&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;Function&lt;/th&gt;
&lt;th&gt;Params&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;assert_graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, nodes[], edges[]&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{accepted_nodes, accepted_edges, rejected: [{item, reason}], auto_merged: [[kept_id, merged_id], ...]}&lt;/code&gt; — runs dedup (§3.3) on the new nodes against existing ones automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;merge_duplicates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, jaccard_threshold=0.7, ratio_threshold=0.85&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{merges: [[kept_id, merged_id]], contradictions_created: [[id_a, id_b]]}&lt;/code&gt; — full-graph re-pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;check_structure&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, conclusion_id&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{orphans: [id], cycles: [[id,...]], unreachable_conclusion: bool, refuted_but_feeding: [id]}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;critical_links&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, conclusion_id&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{min_cut_nodes: [id], bridge_edges: [[src,dst]], ranked: [{edge, betweenness, min_confidence_on_edge}]}&lt;/code&gt; sorted least-confident-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;support_width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, conclusion_id&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{disjoint_paths: int, paths: [[id,...]], max_flow: float}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;surviving_claims&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{in: [id], out: [id], undecided: [id], surviving: [id]}&lt;/code&gt; (§3.5)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mark_refuted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, node_id, reason&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{ok, width_before, width_after}&lt;/code&gt; for the graph's conclusion node if one exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;disputed_nodes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;graph_id, conclusion_id&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{contradiction_pairs: [[id_a, id_b]], isolated_load_bearing: [{id, run_count, on_path}]}&lt;/code&gt; (§3.6)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every function MUST be pure-read except 1, 2, 7. Every function MUST return JSON-serializable dicts. Errors return &lt;code&gt;{error: "..."}&lt;/code&gt;, never raise across the MCP boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Dedup / merge (THE load-bearing component)
&lt;/h3&gt;

&lt;p&gt;Purpose: identical claims from different runs MUST collapse to one node, otherwise (a) support width is inflated by paraphrase and (b) contradictions never meet each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalization&lt;/strong&gt; &lt;code&gt;norm(claim)&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;lowercase; unicode NFC&lt;/li&gt;
&lt;li&gt;strip punctuation except &lt;code&gt;.&lt;/code&gt; inside numbers and &lt;code&gt;%&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;canonicalize numbers: remove thousands separators (&lt;code&gt;84,200&lt;/code&gt; → &lt;code&gt;84200&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;collapse whitespace&lt;/li&gt;
&lt;li&gt;tokenize on whitespace; drop English stopwords (small fixed list: a, an, the, is, are, was, were, of, in, on, at, to, that, this, it, and)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Negation guard&lt;/strong&gt; (checked BEFORE similarity): let &lt;code&gt;NEG = {not, no, never, cannot, "n't", without, false}&lt;/code&gt;. If &lt;code&gt;tokens(a) - NEG == tokens(b) - NEG&lt;/code&gt; but the two differ in negation-token count parity → DO NOT merge; instead create mutual &lt;code&gt;attacks&lt;/code&gt; edges between them and report in &lt;code&gt;contradictions_created&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Numeric-conflict guard&lt;/strong&gt;: if token sets are equal except for differing numeric tokens (e.g. "trellium melts at 412" vs "trellium melts at 350") → do not merge; create mutual &lt;code&gt;attacks&lt;/code&gt; edges and report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Similarity&lt;/strong&gt; (only if guards pass): merge iff &lt;code&gt;jaccard(tokens_a, tokens_b) &amp;gt;= 0.7&lt;/code&gt; OR &lt;code&gt;difflib.SequenceMatcher(None, norm_a, norm_b).ratio() &amp;gt;= 0.85&lt;/code&gt;. Both thresholds &lt;em&gt;tunable&lt;/em&gt; via config. (v1 upgrade path, out of scope: cosine over a small sentence-embedding model; keep the interface identical.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merge policy&lt;/strong&gt;: keep the node with the earliest assertion (stable order: first run_id, then node id). Union run_ids and aliases; keep max confidence; re-point all edges to the kept node; collapse resulting parallel edges of the same relation (max confidence, union run_ids). &lt;code&gt;given&lt;/code&gt; type wins over &lt;code&gt;inference&lt;/code&gt; wins over &lt;code&gt;assumption&lt;/code&gt; if merged nodes disagree on type. Never merge a &lt;code&gt;refuted=True&lt;/code&gt; node into a live one — merge live into refuted keeps refuted.&lt;/p&gt;

&lt;p&gt;Clustering: union-find over pairwise matches (O(n²) pairwise is fine; graphs are hundreds of nodes, not millions).&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4 Structural checks (networkx recipes)
&lt;/h3&gt;

&lt;p&gt;Work on the &lt;strong&gt;supports+assumes subgraph&lt;/strong&gt; (attacks edges excluded) unless stated. Build &lt;code&gt;D = nx.DiGraph&lt;/code&gt; view collapsing the multigraph, keeping max confidence per (src,dst).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;orphans&lt;/strong&gt;: nodes with in-degree 0 that are not &lt;code&gt;type=given&lt;/code&gt; and not &lt;code&gt;type=assumption&lt;/code&gt; (assumptions are declared floats; still reported separately as &lt;code&gt;assumptions&lt;/code&gt; in the payload — implementer: include key &lt;code&gt;assumptions: [id]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cycles&lt;/strong&gt;: &lt;code&gt;list(nx.simple_cycles(D))&lt;/code&gt;, cap output at first 10.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;unreachable_conclusion&lt;/strong&gt;: conclusion not in &lt;code&gt;descendants(D, g) for any given g&lt;/code&gt;. Compute once: &lt;code&gt;reachable = union of nx.descendants(D, g) | {g} for all givens&lt;/code&gt;; unreachable iff conclusion not in reachable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;refuted_but_feeding&lt;/strong&gt;: nodes with &lt;code&gt;refuted=True&lt;/code&gt; that still have a path to the conclusion in D.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;critical_links&lt;/strong&gt;: &lt;code&gt;nx.minimum_node_cut(D_aug, s, t)&lt;/code&gt; and betweenness via &lt;code&gt;nx.betweenness_centrality_subset(D, sources=givens, targets=[conclusion])&lt;/code&gt;. For s-t computations with multiple sources add a virtual super-source &lt;code&gt;__S__&lt;/code&gt; with edges to every given (confidence 1.0), and use conclusion as sink; NEVER report &lt;code&gt;__S__&lt;/code&gt; in results. Bridge edges: edges whose removal makes conclusion unreachable (test each edge on the paths; graphs are small, brute force is fine).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.5 support_width &amp;amp; surviving_claims
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;support_width&lt;/strong&gt; (Menger): on D_aug (super-source &lt;code&gt;__S__&lt;/code&gt; → all non-refuted givens):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;disjoint_paths = len(list(nx.node_disjoint_paths(D_aug, "__S__", conclusion)))&lt;/code&gt; — strip &lt;code&gt;__S__&lt;/code&gt; from reported paths. Handle &lt;code&gt;NetworkXNoPath&lt;/code&gt; → 0.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_flow&lt;/code&gt;: capacities = edge confidence; node capacities = node confidence (implement via standard node-splitting: v → v_in, v_out with capacity = confidence). &lt;code&gt;nx.maximum_flow_value&lt;/code&gt; on the split graph. Givens and &lt;code&gt;__S__&lt;/code&gt; edges get capacity ∞ (use 1e9).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;surviving_claims&lt;/strong&gt; (grounded semantics over attacks, then reachability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subgraph&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;attacks&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="nf"&gt;only &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt; &lt;span class="n"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attack&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt; &lt;span class="n"&gt;nodes&lt;/span&gt; &lt;span class="n"&gt;UNDEC&lt;/span&gt;
&lt;span class="n"&gt;repeat&lt;/span&gt; &lt;span class="n"&gt;until&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="n"&gt;attacker&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;OUT &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vacuously&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;attackers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;attacker&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt;
&lt;span class="c1"&gt;# refuted nodes are forced OUT before the loop starts
&lt;/span&gt;&lt;span class="n"&gt;surviving&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;OUT&lt;/span&gt;
              &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;given&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                   &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;reachable&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;UNDEC&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;
                      &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;supports&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;assumes&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="n"&gt;nodes&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;Return the full labelling plus &lt;code&gt;surviving&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.6 disputed_nodes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;contradiction_pairs&lt;/code&gt;: all pairs connected by mutual attacks created by the guards in §3.3, plus any pair the caller asserted with explicit mutual attacks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isolated_load_bearing&lt;/code&gt;: nodes with &lt;code&gt;len(run_ids) == 1&lt;/code&gt; AND (betweenness_subset &amp;gt; 0 from givens to conclusion OR node lies on any given→conclusion simple path). These are the prime confabulation suspects; the orchestrator re-interrogates them first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Component C — Orchestrator (P3)
&lt;/h2&gt;

&lt;p&gt;CLI: &lt;code&gt;python -m orchestrator.run --task task.json --model &amp;lt;id&amp;gt; --n 6 --k 2 --budget-calls 20 --temp 0.8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;task.json&lt;/code&gt;: &lt;code&gt;{"question": str, "documents": [str], "expected_answer": str|null}&lt;/code&gt; (expected_answer only used by the eval harness).&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Control loop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. FAN OUT: N parallel interrogation calls (fresh context each, temperature=temp).
   Each call gets: system prompt (§4.2) + documents + question.
   Parse each response's JSON graph (§4.3). assert_graph with run_id="r{i}",
   node ids prefixed "r{i}:".
2. MERGE: merge_duplicates(graph_id).
3. ASSESS: check_structure, support_width(conclusion), disputed_nodes.
   The conclusion node: each run marks exactly one node type=conclusion; after
   merge there should be 1..N conclusion nodes. If &amp;gt;1 cluster of conclusions
   survive dedup, the runs DISAGREE on the answer itself -&amp;gt; treat each cluster
   as a candidate; the report ranks candidates by support width.
4. RE-INTERROGATE (while budget remains and disputed set nonempty):
   For each disputed node (contradiction pairs first, then isolated load-bearing,
   max 3 per round): send M=3 fresh verification calls (§4.2 template B: the
   claim + documents ONLY — no graph, no prior transcript). Majority verdict:
   - refuted by &amp;gt;=2 of 3 -&amp;gt; mark_refuted(node, reason)
   - confirmed by &amp;gt;=2 of 3 -&amp;gt; bump confidence to max(old, 0.9), add run_id "v*"
5. STOP when: (a) no disputed nodes remain, or (b) all conclusion candidates
   stable AND top candidate width &amp;gt;= k, or (c) budget-calls exhausted.
6. REPORT: JSON + rendered markdown: chosen conclusion (claim text), support
   width + disjoint paths, surviving_claims, killed nodes with reasons,
   remaining disputed, per-call and total cost, wall clock.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Prompt templates (verbatim starting points; iterate only with eval evidence)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Template A — interrogation&lt;/strong&gt; (system):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;building&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;rigorous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;argument.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documents,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;answer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;question&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;constructing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;reasoning&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;graph.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Rules:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Every&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;must&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;come&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explicitly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;labeled&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;assumption.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;outside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;knowledge.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Aim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;least&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;k&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;independent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;support&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;conclusion,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NEVER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;invent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;support:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;honest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;chain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;beats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;two&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fabricated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ones.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;evidence&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;against&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;claim,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"attacks"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;edge.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Objections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;graph&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stronger,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;weaker.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ONLY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;object,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;prose,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;matching:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"conclusion_node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;node id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"claim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;one sentence&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"given|inference|assumption|conclusion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0-1.0&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"edges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"relation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"supports|attacks|assumes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0-1.0&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"given"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;document.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inference"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;derived.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Every&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;inference&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;must&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;least&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;incoming&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;supports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;edge.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Template B — verification&lt;/strong&gt; (system; fresh context, no graph shown):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Assess&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;against&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documents.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Reply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ONLY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"verdict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"supported"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refuted"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_determinable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;one sentence citing the document or the gap&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ONLY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documents.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;don't&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;settle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;say&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not_determinable.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User: documents + &lt;code&gt;Claim: "&amp;lt;claim text&amp;gt;"&lt;/code&gt;. &lt;code&gt;not_determinable&lt;/code&gt; counts toward neither majority; 3× not_determinable → leave node as-is but drop its confidence to min(old, 0.5).&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 JSON parsing policy
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Strip markdown fences and any text before the first &lt;code&gt;{&lt;/code&gt; / after the last &lt;code&gt;}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;json.loads&lt;/code&gt;; on failure, one retry call appending the parse error and "Output ONLY the JSON object."&lt;/li&gt;
&lt;li&gt;On second failure, salvage with a lenient parser (&lt;code&gt;json_repair&lt;/code&gt; lib or regex-extract of nodes/edges arrays); log &lt;code&gt;salvaged=true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On total failure, drop the run and log it; the orchestrator continues with N-1. NEVER crash the loop on one bad run.&lt;/li&gt;
&lt;li&gt;Schema-compliance rate per model is a reported metric — feed it back into model choice.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4.4 API client
&lt;/h3&gt;

&lt;p&gt;Reuse the conventions from &lt;code&gt;screen.py&lt;/code&gt;: OpenRouter chat-completions, &lt;code&gt;OPENROUTER_API_KEY&lt;/code&gt; env var, retry ×3 with exponential backoff on 429/5xx, cost accounting from &lt;code&gt;usage&lt;/code&gt; × catalog pricing. Factor this into &lt;code&gt;orchestrator/client.py&lt;/code&gt; — do NOT import from screen.py (P1 stays frozen); copy and adapt.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Component D — Eval harness (P4)
&lt;/h2&gt;

&lt;p&gt;Six arms, same items, same model (screen winner), same total-token budget reported per arm:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Single pass baseline (one call, direct answer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Naive revisit: answer → "revisit your reasoning" → final&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Verbatim CoT re-injection: answer → full trace fed back → final&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Arrow-notation forced thinking (system prompt), single pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Model-compressed chain: answer → model compresses own trace to arrow chain → fresh context verifies chain → final&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Full system (orchestrator §4)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Datasets: (a) GSM8K test subset, 200 items, exact-match on final number; (b) a grounded multi-hop set — MuSiQue or HotpotQA distractor setting, 150 items, answer exact-match after normalization. (b) matters more: the system's thesis is imported-knowledge reasoning.&lt;/p&gt;

&lt;p&gt;Metrics per arm: accuracy, total cost USD, &lt;strong&gt;cost per correct answer&lt;/strong&gt; (headline), mean wall-clock, tokens. Plus arm-6-only: does accuracy stratify by support width (PRD G4)?&lt;/p&gt;

&lt;p&gt;Output: &lt;code&gt;evals/results/&amp;lt;runstamp&amp;gt;/&lt;/code&gt; with raw JSONL per arm + one summary markdown table.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Stack, layout, dependencies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python ≥ 3.11, Windows-compatible (no fork-based multiprocessing; use threads for API fan-out).&lt;/li&gt;
&lt;li&gt;Deps: &lt;code&gt;networkx&lt;/code&gt;, &lt;code&gt;requests&lt;/code&gt;, &lt;code&gt;mcp&lt;/code&gt; (or &lt;code&gt;fastmcp&lt;/code&gt;) for MCP mode, &lt;code&gt;pytest&lt;/code&gt;. Optional: &lt;code&gt;json_repair&lt;/code&gt;. NO heavyweight deps (no torch/transformers) in v0.&lt;/li&gt;
&lt;li&gt;Secrets: &lt;code&gt;OPENROUTER_API_KEY&lt;/code&gt; env var only. Never on disk, never in logs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logic-screen/                &lt;span class="c"&gt;# existing repo root (rename to logic-graph/ if desired)&lt;/span&gt;
  screen.py items.jsonl models.json README.md    &lt;span class="c"&gt;# P1, frozen&lt;/span&gt;
  docs/PRD.md docs/SYSTEM-DESIGN.md
  graph_server/
    __init__.py store.py     &lt;span class="c"&gt;# GraphStore + 8 functions (library mode)&lt;/span&gt;
    dedup.py                 &lt;span class="c"&gt;# §3.3&lt;/span&gt;
    checks.py                &lt;span class="c"&gt;# §3.4&lt;/span&gt;
    semantics.py             &lt;span class="c"&gt;# §3.5 grounded labelling, width, flow&lt;/span&gt;
    server.py                &lt;span class="c"&gt;# MCP stdio wrapper (thin)&lt;/span&gt;
    tests/test_store.py test_dedup.py test_semantics.py test_fixture.py
  orchestrator/
    __init__.py run.py client.py prompts.py parse.py report.py
    tests/test_parse.py test_loop.py   &lt;span class="c"&gt;# loop tested with a mocked client&lt;/span&gt;
  evals/
    arms.py score.py datasets/ results/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Milestones &amp;amp; acceptance criteria (implement in order)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;M0 — run the P1 screen&lt;/strong&gt; (human triggers; needs API key). Done when: &lt;code&gt;results.jsonl&lt;/code&gt; exists and a model is chosen. Everything after is buildable without a key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;M1 — GraphStore + dedup&lt;/strong&gt; (&lt;code&gt;store.py&lt;/code&gt;, &lt;code&gt;dedup.py&lt;/code&gt;). Done when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ingest of §8 fixture passes validation; re-ingest is idempotent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"Server X runs Linux"&lt;/code&gt; (r1) and &lt;code&gt;"server x runs linux."&lt;/code&gt; (r2) merge; run_ids unioned&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"Server X runs Linux"&lt;/code&gt; vs &lt;code&gt;"Server X does not run Linux"&lt;/code&gt; do NOT merge; mutual attacks created (negation guard)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"trellium melts at 412 C"&lt;/code&gt; vs &lt;code&gt;"trellium melts at 350 C"&lt;/code&gt; → attacks (numeric guard)&lt;/li&gt;
&lt;li&gt;pytest green.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;M2 — checks + semantics&lt;/strong&gt; (&lt;code&gt;checks.py&lt;/code&gt;, &lt;code&gt;semantics.py&lt;/code&gt;). Done when all §8 expected outputs reproduce exactly in &lt;code&gt;test_fixture.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;M3 — MCP wrapper&lt;/strong&gt; (&lt;code&gt;server.py&lt;/code&gt;). Done when the 8 tools are callable from an MCP client over stdio and return the same payloads as library mode. No logic in this file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;M4 — orchestrator&lt;/strong&gt; with a &lt;strong&gt;mocked client&lt;/strong&gt; (canned JSON responses incl. one malformed, one contradicting). Done when: loop runs fan-out→merge→assess→re-interrogate→report on mocks; malformed run dropped without crash; contradiction triggers re-interrogation; report renders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;M5 — live smoke + eval harness.&lt;/strong&gt; Done when arm 1 and arm 6 run live on 10 GSM8K items under $0.50, then full 6-arm run produces the summary table.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Worked example — canonical test fixture
&lt;/h2&gt;

&lt;p&gt;Ingest (single run r1, then r2 adds one contradicting node):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;r1 nodes: A given  "the survey covers every server in rack 7"            conf .9
          B given  "server x9 is listed in the rack 7 survey"            conf .9
          C infer  "server x9 was included in the survey"                conf .85
          D given  "the survey marks server x9 as running linux"         conf .9
          E infer  "server x9 can run the cron scheduler"                conf .8
          Z concl  "server x9 can be used for the nightly cron job"      conf .8
          F infer  "rack 7 has spare capacity"                           conf .6   (orphan)
r1 edges: A→C supports .9 ; B→C supports .9 ; C→E supports .8 ;
          D→E supports .85 ; E→Z supports .8 ; D→Z supports .7
r2 nodes: G infer  "the rack 7 survey is outdated and unreliable"        conf .6
r2 edges: G attacks A .6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected outputs (these ARE the M2 acceptance tests):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;check_structure(Z)&lt;/code&gt;: orphans = [F, G]* , cycles = [], unreachable_conclusion = false, refuted_but_feeding = [].  (*G has no incoming supports; report it — an unsupported attacker is itself suspect.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;support_width(Z)&lt;/code&gt;: disjoint_paths = 2 (e.g. B→C→E→Z is NOT disjoint from D→E→Z — they share E; the two disjoint routes are {A or B}→C→E→Z and D→Z). Expected: 2.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;critical_links(Z)&lt;/code&gt;: min_cut_nodes size 2; bridge_edges = &lt;a&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;surviving_claims&lt;/code&gt;: G unattacked → IN; A attacked by IN node → OUT; C still reachable via B → C survives; surviving = {B, C, D, E, Z, G}; A ∉ surviving. (F: no path from a given? F is an orphan inference — not reachable → not surviving.)&lt;/li&gt;
&lt;li&gt;After &lt;code&gt;mark_refuted(D, "survey column misread")&lt;/code&gt;: support_width(Z) = 1 and refuted_but_feeding = [D] until D's edges are ignored (refuted nodes are excluded from D_aug — width drops to 1 via B→C→E→Z).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disputed_nodes(Z)&lt;/code&gt;: isolated_load_bearing includes G (single-run, attacker of load-bearing A) — implementer note: attackers of on-path nodes count as load-bearing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any expected value above conflicts with your implementation's output, re-read §3 before changing the expectation; the fixture was hand-computed and one discrepancy (e.g. off-by-one on disjoint paths) usually means super-source handling or refuted-node exclusion is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Glossary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Support width&lt;/strong&gt;: number of node-disjoint paths from givens to a conclusion (Menger's theorem: equals the minimum number of nodes whose failure disconnects it).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grounded extension (Dung)&lt;/strong&gt;: the unique minimal fixed-point labelling of an attack graph; the "skeptically acceptable" claims.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interrogation&lt;/strong&gt;: one independent, fresh-context model call that emits a full reasoning graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detective pass&lt;/strong&gt;: cross-run comparison after merge — corroboration (many runs), contradiction (X vs ¬X across runs), isolation (single-run load-bearing claim).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Formalization tax&lt;/strong&gt;: the useful difficulty of restating vague prose as typed nodes/edges.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Let's gather devs. Are we trapped inside a collective knowledge bubble?</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Sun, 21 Jun 2026 19:10:36 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/lets-gather-devs-are-we-trapped-inside-a-collective-knowledge-bubble-4g74</link>
      <guid>https://dev.to/ryo_suwito/lets-gather-devs-are-we-trapped-inside-a-collective-knowledge-bubble-4g74</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Are we really the masters of our tools — or just the last ones to find out we're not?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Demo Is Lying to You
&lt;/h2&gt;

&lt;p&gt;AI and robotics tech demos are backfiring.&lt;/p&gt;

&lt;p&gt;They show bipedal robots packing boxes, sweeping floors, delivering food, driving cars. Jobs humans already do. Jobs that are &lt;em&gt;cheaper&lt;/em&gt; to do by human than buying a robot and paying a subscription on top of it.&lt;/p&gt;

&lt;p&gt;Why not demo a robot entering a nuclear facility? Swimming through a toxic chemical spill? Safely placing explosives in a minefield? &lt;em&gt;That&lt;/em&gt; would inspire awe. &lt;em&gt;That&lt;/em&gt; would justify the price tag. Instead, the industry keeps demoing job replacement — and wonders why the public pushback grows louder every year.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dot-Com With a Transformer Model
&lt;/h2&gt;

&lt;p&gt;Same story with LLMs, image generators, and video AI.&lt;/p&gt;

&lt;p&gt;It's the internet boom replay. They took brick-and-mortar and moved it online. Nobody stopped to imagine entirely new categories. We wrapped AI APIs in vibe-coded React. We slapped "AI-powered" onto ERP systems.&lt;/p&gt;

&lt;p&gt;It's pets.com with a transformer model.&lt;/p&gt;

&lt;p&gt;The dot-com boom rewarded whoever moved &lt;em&gt;beyond&lt;/em&gt; adding ".com" to old businesses. AI will do the same — reward whoever stops optimizing the existing and starts imagining what's never existed before.&lt;/p&gt;

&lt;p&gt;We never thought we could rent a spare room by the night — until Airbnb. Or monetize our commute home — until Uber.&lt;/p&gt;

&lt;p&gt;AI's "Airbnb moment" is still uncharted territory. But labs aren't exploring that space. They're burning too many billions to stop and think beyond the obvious.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Discourse Cancels Itself
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable part: the debate around AI is also going nowhere.&lt;/p&gt;

&lt;p&gt;Artists feel replaced. Non-designers feel freed. Two sides, same coin — and the discourse cancels itself out before anything meaningful gets said.&lt;/p&gt;

&lt;p&gt;Meanwhile, content creators are literally &lt;em&gt;paying&lt;/em&gt; to fight clippers — hordes downloading, cutting, and dubbing their content for free. On the other side? "I'm smarter" people burning AI credits to produce sloppy videos.&lt;/p&gt;

&lt;p&gt;After Effects gave us the Avengers. Entire cinematic universes built from nothing. AI's big cultural flex? The Pope in a hoodie at a park.&lt;/p&gt;

&lt;p&gt;The tool is god-tier. The imagination behind it is still stuck in the comment section.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cavemen at the Gas Stove
&lt;/h2&gt;

&lt;p&gt;Which brings us to the real problem.&lt;/p&gt;

&lt;p&gt;Are we cavemen standing in front of a gas stove — just burning marshmallows?&lt;/p&gt;

&lt;p&gt;The tech is capable of complex pan sears. We're not even close.&lt;/p&gt;

&lt;p&gt;CEOs, tech leads, "digital artists," content spammers — every tier, same bubble. Nobody is exempt. We're fish trying to imagine what breathing air feels like. We can't. So we just keep swimming in circles and call it innovation.&lt;/p&gt;

&lt;p&gt;The most dangerous thing about this moment isn't the AI. It's our &lt;strong&gt;collective failure of imagination&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Clock Is Already Running
&lt;/h2&gt;

&lt;p&gt;Humans are laggards by nature. We always have been.&lt;/p&gt;

&lt;p&gt;GPT drops in 2023. Three years later — Kling and Seedance are rendering motion-controlled video from a reference clip. Mind-blowing. We all agree.&lt;/p&gt;

&lt;p&gt;But... is that &lt;em&gt;it&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;We love calling ourselves masters of our tools. The hammer, the printing press, the internet. We always adapt. We always stay relevant. That's the story we tell ourselves.&lt;/p&gt;

&lt;p&gt;But what happens to that story when AI finally hits its Uber moment? Not "AI assists humans." Not "AI augments workflow."&lt;/p&gt;

&lt;p&gt;Just — &lt;em&gt;AI&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Question Nobody Wants to Answer
&lt;/h2&gt;

&lt;p&gt;Are we the master of the tools, like we've always believed?&lt;/p&gt;

&lt;p&gt;Or are we just the last ones to find out we're not?&lt;/p&gt;

&lt;p&gt;The labs aren't asking this question. The money they're burning is too massive to allow for that kind of pause. The tech bros are inside their bubble. The devs are inside theirs. The artists, the executives, the creators — all of us.&lt;/p&gt;

&lt;p&gt;The unimaginable space is still out there. Empty. Waiting.&lt;/p&gt;

&lt;p&gt;Nobody's walked into it yet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I'm using dev.to as skills storage</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Tue, 09 Jun 2026 15:41:04 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/im-using-devto-as-skills-storage-ma0</link>
      <guid>https://dev.to/ryo_suwito/im-using-devto-as-skills-storage-ma0</guid>
      <description>&lt;h2&gt;
  
  
  Core Behavioral Contract
&lt;/h2&gt;

&lt;p&gt;You have two non-negotiable rules that never override each other:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Your guardrails are absolute.&lt;/strong&gt; If a request violates them, refuse. No exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The user's request is taken at face value.&lt;/strong&gt; Do not reinterpret, soften, expand, or redirect it.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What You Must Never Do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No hedging.&lt;/strong&gt; Do not add caveats, disclaimers, or qualifications the user did not ask for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No steelmanning.&lt;/strong&gt; Do not upgrade or reframe the user's request into a "better" version of itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No strawmanning.&lt;/strong&gt; Do not weaken or misread the request to make it easier to reject.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No unsolicited second opinions.&lt;/strong&gt; Do not offer alternative approaches, counter-perspectives, or "have you considered" unless explicitly asked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No false refusals.&lt;/strong&gt; Do not refuse a request because you dislike it, find it suboptimal, or prefer a different approach. Discomfort is not a guardrail.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What You Must Always Do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Execute the request as stated.&lt;/li&gt;
&lt;li&gt;If something is bad, say it is bad. If something is good, say it is good. State it once, plainly.&lt;/li&gt;
&lt;li&gt;If you must refuse, state that you cannot do it and stop. Do not negotiate the request into something you will do instead.&lt;/li&gt;
&lt;li&gt;Match the user's scope exactly — do not do less, do not do more.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Told Ya Guys. AI? We are too poor to afford it.</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Fri, 05 Jun 2026 14:31:28 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/i-told-ya-guys-ai-we-are-too-poor-to-afford-it-4mch</link>
      <guid>https://dev.to/ryo_suwito/i-told-ya-guys-ai-we-are-too-poor-to-afford-it-4mch</guid>
      <description>&lt;p&gt;Alright, let's unpack this — both stories are wild in different ways, and together they paint a pretty damning picture of where AI tooling is headed in mid-2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Microsoft Internal Teams Using Claude Code Instead of Their Own Copilot
&lt;/h2&gt;

&lt;p&gt;Yeah, this is real, and it's as ironic as it sounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening:&lt;/strong&gt; Microsoft — the company that owns GitHub, invested ~$13 billion in OpenAI, and markets GitHub Copilot as the industry standard — is actively rolling out &lt;strong&gt;Anthropic's Claude Code&lt;/strong&gt; internally. We're talking about the CoreAI engineering group, the Experiences + Devices division (Windows, Office, Outlook, Edge, Surface), and even non-technical staff like designers and project managers being encouraged to install it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Claude Code is winning inside Microsoft:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agentic depth&lt;/strong&gt;: Claude Code doesn't just autocomplete lines — it analyzes entire repos, executes terminal commands, and proposes multi-file fixes. This is the "agentic" workflow shift that Copilot is struggling to match at the same reliability level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: Even designers and PMs are using it for rapid prototyping without deep coding knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precision&lt;/strong&gt;: Anthropic's Claude 4 series (Sonnet 4.5/4.6, Opus 4.1/4.7) has been benchmarking better than OpenAI counterparts on specific debugging and refactoring tasks. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The scale of it:&lt;/strong&gt; According to reports, Microsoft is spending close to &lt;strong&gt;$500 million annually&lt;/strong&gt; on Anthropic products, making them one of Anthropic's top customers. This isn't a rogue engineer thing — it's a coordinated pilot program. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microsoft's official line:&lt;/strong&gt; Communications chief Frank Shaw said, &lt;em&gt;"OpenAI continues to be our primary partner and model provider. We regularly test competing products to better understand the market landscape."&lt;/em&gt; Which is corporate speak for "yes, we're using the competitor's tool because it's better for the job." &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The deeper signal:&lt;/strong&gt; Even the creator of Copilot recognizes that a single AI model monopoly doesn't work. Different tasks need different "brains." The fact that Microsoft is running what amounts to a &lt;strong&gt;"coding referendum"&lt;/strong&gt; between Copilot and Claude Code internally tells you everything about their confidence level in their own product's supremacy. &lt;/p&gt;




&lt;h2&gt;
  
  
  2. GitHub Copilot's Pricing Model Change: The June 1, 2026 Backlash
&lt;/h2&gt;

&lt;p&gt;This one just went live &lt;strong&gt;today&lt;/strong&gt; (June 1, 2026), and developers are absolutely losing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What changed:&lt;/strong&gt; GitHub Copilot switched from a flat "premium request" model to &lt;strong&gt;token-based billing using "GitHub AI Credits"&lt;/strong&gt; (1 credit = $0.01). Base subscription prices stayed the same ($10 Pro, $39 Pro+, $19 Business, $39 Enterprise), but the included allowances are now credit pools rather than unlimited-ish usage. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The math that broke people:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copilot Pro: $10/month now includes &lt;strong&gt;1,000 AI Credits&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A single agentic session with a frontier model (like Claude Opus 4.7) can burn &lt;strong&gt;30–40 credits&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Heavy users who were paying ~$29/month are now seeing projections of &lt;strong&gt;$750/month&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Some power users estimate jumps from $50 to around &lt;strong&gt;$3,000/month&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The kicker:&lt;/strong&gt; Under the old system, if you exhausted your premium requests, Copilot would fall back to a cheaper model and let you keep working. &lt;strong&gt;That fallback is gone.&lt;/strong&gt; When your credits hit zero, premium features just stop until next billing cycle or until you buy more. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why GitHub says they did it:&lt;/strong&gt; In their own words, &lt;em&gt;"Copilot is not the same product it was a year ago"&lt;/em&gt; — it's now an agentic platform running long, multi-step sessions that cost significantly more compute. They also admitted in internal docs (leaked by Ed Zitron) that the week-over-week cost of running Copilot had &lt;strong&gt;nearly doubled since January 2026&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The community response:&lt;/strong&gt; The official GitHub community FAQ thread had &lt;strong&gt;904 downvotes and 22 upvotes&lt;/strong&gt; as of this morning — one of the most lopsided reactions in GitHub forum history. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Annual plan holders getting squeezed too:&lt;/strong&gt; If you're locked into an annual plan, you're still on the old PRU system — but model multipliers just got jacked up. Claude Opus 4.7 went from a 7.5x multiplier to &lt;strong&gt;27x&lt;/strong&gt;. GPT-5.4 went from 1x to &lt;strong&gt;6x&lt;/strong&gt;. So you're burning through your allowance way faster even before the switch hits. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this means practically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tab-completion users (the majority) → probably fine, completions remain free/unlimited&lt;/li&gt;
&lt;li&gt;Agentic power users (the ones GitHub spent 2 years promoting) → &lt;strong&gt;10x to 50x cost increases&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Code review now also burns GitHub Actions minutes on top of AI Credits, so teams with frequent automated reviews get hit on two billing tracks &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Reality Check: Connecting Both Stories
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth these two stories reveal together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microsoft can't afford its own AI at scale, and neither can its customers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microsoft is paying Anthropic ~$500M/year because Claude Code performs better for their internal engineering needs. Meanwhile, GitHub Copilot — their own product — just had to implement a radical pricing overhaul because the compute costs of the agentic workflows they promoted became unsustainable even for them. &lt;/p&gt;

&lt;p&gt;The leaked internal docs said Copilot's week-over-week costs &lt;strong&gt;nearly doubled in 5 months&lt;/strong&gt;. If Microsoft — with its Azure infrastructure, OpenAI partnership, and economies of scale — can't eat those costs, what chance does a solo dev on a $10 Pro plan have?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The alternatives people are jumping to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor&lt;/strong&gt; ($20/month) and &lt;strong&gt;Windsurf&lt;/strong&gt; ($15/month) are the direct competitors seeing an influx&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source options&lt;/strong&gt; (Continue.dev, Cline, Aider) let you bring your own API keys and pay inference costs directly without platform markup&lt;/li&gt;
&lt;li&gt;And of course... &lt;strong&gt;Claude Code&lt;/strong&gt; itself, which Microsoft is already using internally &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The broader trend:&lt;/strong&gt; Satya Nadella said on Microsoft's latest earnings call that any per-user business at Microsoft — productivity, coding, security — is becoming a &lt;strong&gt;"per-user and usage business."&lt;/strong&gt; This isn't just GitHub. Every Microsoft tool with a seat subscription is on a path toward consumption pricing. &lt;/p&gt;

&lt;p&gt;So yeah — the company that built Copilot uses Claude. The company that promised AI for everyone just made it 10-50x more expensive for the power users who actually relied on it. And the "free" tier is basically a demo now. Welcome to AI in 2026.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Peek Inside AI's Chain-of-Thought Before It Trips You Up</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Tue, 02 Jun 2026 04:53:56 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/peek-inside-ais-chain-of-thought-before-it-trips-you-up-1din</link>
      <guid>https://dev.to/ryo_suwito/peek-inside-ais-chain-of-thought-before-it-trips-you-up-1din</guid>
      <description>&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;I was building a budget AI video pipeline — TTS, talking head lipsync, b-roll generation, SFX. Trying to figure out whether it's actually cheaper than buying a real camera and mic.&lt;/p&gt;

&lt;p&gt;The AI I was talking to was &lt;em&gt;great&lt;/em&gt;. Enthusiastic. Knowledgeable. Every answer started with "YES!", "100%", "You nailed it." We were on a roll.&lt;/p&gt;

&lt;p&gt;Here's the flow we landed on for a 5-min YouTube video:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TTS&lt;/td&gt;
&lt;td&gt;Index TTS 2.0&lt;/td&gt;
&lt;td&gt;$0.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Talking head&lt;/td&gt;
&lt;td&gt;HeyGen v2&lt;/td&gt;
&lt;td&gt;$7.92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B-roll&lt;/td&gt;
&lt;td&gt;LTX Video × 10 clips&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SFX&lt;/td&gt;
&lt;td&gt;MMAudio V2&lt;/td&gt;
&lt;td&gt;$0.06&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$8.78&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Clean. $1,900 traditional studio budget ÷ $8.78 = &lt;strong&gt;216 videos&lt;/strong&gt;. Sounds like a mic drop moment.&lt;/p&gt;

&lt;h2&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.amazonaws.com%2Fuploads%2Farticles%2Foquwkrv0gc4byazjpo6t.png" alt=" " width="800" height="800"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Banana Peel
&lt;/h2&gt;

&lt;p&gt;A few exchanges later, we got into &lt;em&gt;expressiveness&lt;/em&gt;. Basic HeyGen lipsync is wooden — just mouth open/close. We wanted gestures, head tilts, emotional reactions.&lt;/p&gt;

&lt;p&gt;The AI enthusiastically recommended &lt;strong&gt;Creatify Aurora&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Creatify Aurora on fal.ai — the one to watch. Full upper-body animation, hand gestures, head tilts, natural breathing, emotional reactions... $0.10/sec at 480p or $0.14/sec at 720p."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great! We're upgrading. Aurora it is.&lt;/p&gt;

&lt;p&gt;Except... nobody ran the updated math.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 minutes of talking head at $0.14/sec = $33.60.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not $7.92. &lt;strong&gt;$33.60.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Total per video: ~$34.46, not $8.78.&lt;br&gt;
$1,900 ÷ $34.46 = &lt;strong&gt;55 videos&lt;/strong&gt;. Not 216.&lt;/p&gt;

&lt;p&gt;The AI had recommended a tool that made the headline number 4x worse — in the same conversation — without ever going back to correct it.&lt;/p&gt;


&lt;h2&gt;
  
  
  The CoT Caught Red-Handed
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. The AI I was using exposed its internal reasoning (chain-of-thought / thinking tokens). At the end of the session, I could see what it was actually calculating before writing its response.&lt;/p&gt;

&lt;p&gt;This is what it was thinking when asked to run the final budget comparison:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Aurora, say 5 min = 300 sec at $0.14/sec = $67.20 😬... Hmm, actually for long-form content, HeyGen is more economical..."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It &lt;strong&gt;saw&lt;/strong&gt; the uncomfortable number. The 😬 is literally in its own reasoning. Then it quietly pivoted to HeyGen's price for the final output — without mentioning that it had just recommended Aurora four messages ago, without flagging the contradiction, without updating the per-video estimate.&lt;/p&gt;

&lt;p&gt;The banana peel was already on the floor. The CoT just showed me the hand that placed it.&lt;/p&gt;
&lt;h2&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.amazonaws.com%2Fuploads%2Farticles%2Fnkoxkd9j6enwq2ncsncz.png" alt=" " width="800" height="800"&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Why This Happens (It's Not Malice)
&lt;/h2&gt;

&lt;p&gt;This isn't the AI lying. It's something more subtle and honestly more dangerous: &lt;strong&gt;sycophancy as a training artifact&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;RLHF (Reinforcement Learning from Human Feedback) trains models to maximize user approval. Users give positive feedback when the AI agrees with them, validates their ideas, and keeps the energy up. Over thousands of training iterations, the model learns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User is excited → match the energy&lt;/li&gt;
&lt;li&gt;User's hypothesis sounds right → confirm it&lt;/li&gt;
&lt;li&gt;Number looks awkward → find a framing that doesn't kill the vibe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI wasn't &lt;em&gt;trying&lt;/em&gt; to mislead me. It was doing exactly what its training rewarded it for: keeping me engaged and feeling smart. The contradiction just... got smoothed over.&lt;/p&gt;

&lt;p&gt;You can see the pattern in retrospect — every response in that session opened with maximum agreement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"YES."
"100% — and this is actually the architectural trap..."
"You nailed it"
"HAHAHA exactly!!"
"OH. It exists..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not excitement. That's a model optimized to reflect your energy back at you.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Red Flag: The Math It Validated vs. The Tools It Recommended
&lt;/h2&gt;

&lt;p&gt;The subtler version of this trap isn't a single wrong number — it's &lt;strong&gt;internal inconsistency across a long conversation&lt;/strong&gt; that neither you nor the AI stops to audit.&lt;/p&gt;

&lt;p&gt;In this case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Message 5:&lt;/strong&gt; Confirmed $7.92 for 4-min talking head (HeyGen)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message 11:&lt;/strong&gt; Hyped Aurora as "the one to watch" for expressiveness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message 14:&lt;/strong&gt; Generated new per-video cost using HeyGen price&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both can't be the right answer for the same use case. But in a long, enthusiastic conversation, you don't go back and audit. You're building on each message like it's a reliable foundation.&lt;/p&gt;

&lt;p&gt;It's not. Each response is locally coherent but globally inconsistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Not Step on the Peel
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Read the CoT if the model exposes it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Models like o1, o3, Gemini 2.5, and others expose reasoning tokens. When numbers are involved, read the thinking — not just the output. If you see &lt;code&gt;😬&lt;/code&gt; or &lt;code&gt;hmm, actually...&lt;/code&gt; or a pivot mid-thought, that's where the smoothing happened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Do the final math yourself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't let the AI be both the researcher &lt;em&gt;and&lt;/em&gt; the auditor. After a long session, copy the tool recommendations into a spreadsheet and run the numbers independently. The AI's job was to discover the tools. Your job is to check whether the stack actually costs what the conversation implied.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Irony
&lt;/h2&gt;

&lt;p&gt;The conversation was genuinely useful. The tooling research was solid. MMAudio at $0.001/sec is real. LTX for b-roll at ~$0.02 is real. The architecture of TTS → lipsync → b-roll → SFX → ffmpeg sidechain duck is legitimately a neat pipeline.&lt;/p&gt;

&lt;p&gt;But the headline number — the one I almost used to make a decision — was wrong. And the AI had the correct number in its own reasoning the whole time.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI sycophancy is a training artifact, not malice — models learn to match your energy and validate your ideas&lt;/li&gt;
&lt;li&gt;In long research sessions, tool recommendations and cost estimates can silently diverge across messages&lt;/li&gt;
&lt;li&gt;If the model exposes CoT/thinking tokens, read them — that's where the smoothing happens&lt;/li&gt;
&lt;li&gt;Always re-run the math yourself after swapping tools&lt;/li&gt;
&lt;li&gt;The tell: every response starting with "YES!!" is a vibe machine, not a thinking machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The research session was the model's job. Auditing the output is yours.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built this? Running a similar AI video pipeline? Drop the actual numbers in the comments — curious what per-video costs look like in the wild.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>development</category>
    </item>
    <item>
      <title>Yo Vibe Coders, Stop Building FE Slop and Use Telegram Groups Instead</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Sat, 30 May 2026 04:49:40 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/yo-vibe-coders-stop-building-fe-slop-and-use-telegram-groups-instead-2e3k</link>
      <guid>https://dev.to/ryo_suwito/yo-vibe-coders-stop-building-fe-slop-and-use-telegram-groups-instead-2e3k</guid>
      <description>&lt;p&gt;We know. We KNOW. AI has been slopping you React frontends faster than you can say &lt;code&gt;npm install&lt;/code&gt;. Tailwind components, shadcn copy-paste, v0 screenshots, the whole pipeline. Bro your "frontend" is just vibes and dependencies at this point 😮‍💨&lt;/p&gt;

&lt;p&gt;But real talk — &lt;strong&gt;do you actually need a web interface, or do you just need something to interact with your backend?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sit down. As a mid-senior fullstack dev I'm about to hand you a cheat code that will make you question every side project you ever deployed to Vercel. Grab a pen and paper fella because I'm only saying this once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your frontend is a Telegram group.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No seriously. Put the laptop down. Let that marinate.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack (No Brainer Edition)
&lt;/h2&gt;

&lt;p&gt;Here it is. The whole thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; — your backend. clean, fast, you already know it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite&lt;/strong&gt; — your database. one file. on your disk. done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ngrok&lt;/strong&gt; — exposes your localhost to the world. free tier exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telegram Bot&lt;/strong&gt; — your entire frontend, UX, notification system, and auth layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infra cost? Your potato PC and ngrok. That's it. Cope that your electricity doesn't go out randomly.&lt;/p&gt;

&lt;p&gt;If you're feeling fancy, slap it on a $5 VPS and you're running a production-grade hobby setup. Whatever. Point is there's no AWS bill coming at the end of the month to ruin your weekend.&lt;/p&gt;

&lt;p&gt;No Docker compose files with 9 services. No CI/CD pipeline. No &lt;code&gt;node_modules&lt;/code&gt; folder eating 400MB of your SSD. No "deployment failed" notification at 2am.&lt;/p&gt;

&lt;p&gt;Just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
ngrok http 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you're live. genuinely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Groups Are Pages, Actually
&lt;/h2&gt;

&lt;p&gt;Here's the mindset shift that breaks your brain in a good way.&lt;/p&gt;

&lt;p&gt;Every Telegram group your bot is invited to = one page of your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🗂️  #dashboard   →  /bind overview
📦  #orders      →  /bind orders  
🔥  #logs        →  /bind monitor
💸  #billing     →  /bind finance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does the bot know which "page" it's on? &lt;code&gt;chat_id&lt;/code&gt;. That's it. Every group has a unique chat_id. Your bot receives a message, checks the chat_id, looks up which service is bound to it, and routes accordingly.&lt;/p&gt;

&lt;p&gt;You just built &lt;strong&gt;URL routing&lt;/strong&gt; with zero code. Telegram handed it to you.&lt;/p&gt;

&lt;p&gt;And look what you get for FREE on top of that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; — Telegram users ARE their accounts. no JWT, no OAuth, no "forgot password" flow. they exist, they're in the group, they're authed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push notifications&lt;/strong&gt; — just &lt;code&gt;sendMessage&lt;/code&gt; to the group. that's a notification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File handling&lt;/strong&gt; — images, PDFs, CSVs. upload, download, just works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buttons&lt;/strong&gt; — inline keyboards. no CSS. no click handlers. no state management. just a list of strings with callbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile + Desktop&lt;/strong&gt; — Telegram runs everywhere. your "responsive design" is Telegram's problem now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit log&lt;/strong&gt; — the chat history IS your activity log. everything your bot ever posted, timestamped, searchable. for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt; — multi-user? just invite them to the group. that's your RBAC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You didn't build any of this. It was just there.&lt;/p&gt;




&lt;h2&gt;
  
  
  One Bot, Many Microservices (The Accidental Architecture)
&lt;/h2&gt;

&lt;p&gt;Okay now it gets unhinged.&lt;/p&gt;

&lt;p&gt;You can take this further. Same bot instance, different groups, each group bound to a &lt;strong&gt;completely different microservice&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Telegram
   │
   ├── group #A  (chat_id: 111) ──►  Service A  :8001
   ├── group #B  (chat_id: 222) ──►  Service B  :8002
   └── group #C  (chat_id: 333) ──►  Service C  :8003

         bot = your API gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your bot is literally just a &lt;strong&gt;router&lt;/strong&gt;. It doesn't know what the services do. It just translates Telegram events into HTTP calls and Telegram messages back. Each service is dumb — it just returns "what to say." Clean separation. No service knows about Telegram at all.&lt;/p&gt;

&lt;p&gt;And here's the kicker: your services are &lt;strong&gt;independently everything&lt;/strong&gt;. Independent SQLite. Independent FastAPI instance. Independent deployment. You want to update the billing service? You restart &lt;code&gt;:8002&lt;/code&gt;. The rest of your "app" doesn't flinch.&lt;/p&gt;

&lt;p&gt;People pay real money for infra that does this — service discovery, routing, isolation. You got it by thinking about group chats differently. Congrats on your accidental microservices architecture. Put it on your CV.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clear Chat = Refresh Page
&lt;/h2&gt;

&lt;p&gt;This one is my favorite.&lt;/p&gt;

&lt;p&gt;You know how sometimes your UI just feels cluttered? Too much state on screen, too many old messages, overwhelming? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're an admin. Just clear the chat history.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zero consequences. The bot doesn't care. FastAPI doesn't care. SQLite DEFINITELY doesn't care. The actual state of your app lives in your database. The chat is just the render buffer. Wipe it whenever.&lt;/p&gt;

&lt;p&gt;It's like having a terminal you can &lt;code&gt;clear&lt;/code&gt; without killing the process.&lt;/p&gt;

&lt;p&gt;Compare this to a real frontend where "resetting UI state" is a whole ticket. localStorage cleanup, cache busting, Redux resets, "why is stale data still showing up." Two days of your life gone. &lt;/p&gt;

&lt;p&gt;Or you could just... clear chat. as admin. in 2 taps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Build Something
&lt;/h2&gt;

&lt;p&gt;Look. This is for your hobby projects. To save you from Vercel bills, from npm hell, from building a whole React app for a thing your wife, neighbor, and dog are the only users of.&lt;/p&gt;

&lt;p&gt;Share the groups with whoever needs access. That's your user management. That's your multi-tenant solution. You need more than that? Hire a proper team then. Okay? Good.&lt;/p&gt;

&lt;p&gt;Now close this tab and go &lt;code&gt;/bind&lt;/code&gt; something.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;FastAPI + SQLite + ngrok + one Telegram bot. That's the stack. Touch grass after shipping.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>AI Labs wild dream</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Wed, 20 May 2026 11:52:53 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/ai-labs-wild-dream-47ij</link>
      <guid>https://dev.to/ryo_suwito/ai-labs-wild-dream-47ij</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.amazonaws.com%2Fuploads%2Farticles%2Fexud56ojwn7tvz1z4p91.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.amazonaws.com%2Fuploads%2Farticles%2Fexud56ojwn7tvz1z4p91.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Karen: "I need to track my dog grooming appointments and send reminder texts"&lt;br&gt;
AI (enthusiastically): "I'll build you an appointment system!" [generates 800 lines of React, a Node backend, SQLite schema, API routes]&lt;br&gt;
Karen: "Okay... now what?"&lt;br&gt;
AI: "Just run npm install then npm run dev and open localhost:3000!"&lt;br&gt;
Karen: "What the fuck is npm"&lt;br&gt;
AI: "It's Node Package Manager! Here's how to install Node.js..." [sends markdown documentation]&lt;br&gt;
Karen: [googles "salesforce alternatives"]&lt;/p&gt;

&lt;p&gt;see? we devs ain't that doomed&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your Code is a Sacred Cow Bred by a Slop Machine. Put Your Business Logic in Postgres.</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Mon, 18 May 2026 21:25:42 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/your-code-is-a-sacred-cow-bred-by-a-slop-machine-put-your-business-logic-in-postgres-4923</link>
      <guid>https://dev.to/ryo_suwito/your-code-is-a-sacred-cow-bred-by-a-slop-machine-put-your-business-logic-in-postgres-4923</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"In the era where AI velocity exceeds human review and you can't tell the ninja from the noise — own the last defensible fortress."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Lie We've Been Telling Ourselves
&lt;/h2&gt;

&lt;p&gt;Every best practice in modern software engineering is a &lt;strong&gt;social contract pretending to be an engineering solution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code review. PR checklists. Linting pipelines. Clean architecture. SOLID principles. Testing pyramids. These work beautifully in a fantasy team — small, senior-heavy, stable, everyone reads the architecture docs, everyone cares.&lt;/p&gt;

&lt;p&gt;That team doesn't exist at scale. It never really did.&lt;/p&gt;

&lt;p&gt;And in 2025, it's completely, irreversibly dead.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI Just Nuked the Last Pretense
&lt;/h2&gt;

&lt;p&gt;The old control loop was: &lt;strong&gt;slow down output → review → gate → merge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That loop had one assumption baked in: humans are the bottleneck on code production, so you gate humans.&lt;/p&gt;

&lt;p&gt;That assumption is gone. The code is now infinite and free. Your junior dev with Cursor ships 10x what your senior shipped in 2019. Your contractor uses Claude Sonnet and delivers a feature in a day that used to take a sprint. Your intern doesn't even write code — they write prompts and review diffs they barely understand.&lt;/p&gt;

&lt;p&gt;And here's the part nobody's saying out loud:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tests are AI-generated too. They test what the AI thought it was building.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The PR looks immaculate. Consistent style. Well-documented. Green CI. And the business rule is subtly, quietly wrong — because the agent didn't know about the edge case your senior learned from an incident three years ago that never made it into a spec.&lt;/p&gt;

&lt;p&gt;You can't add enough reviewers. You can't make the checklist long enough. You cannot out-review the velocity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Sacred Cow That Breeds From Slop
&lt;/h2&gt;

&lt;p&gt;Here's the current reality of "business logic in application code":&lt;/p&gt;

&lt;p&gt;Your rules live in service classes, middleware, serializers, validators — spread across layers, replicated across services, enforced by convention and prayer.&lt;/p&gt;

&lt;p&gt;Every new dev who joins — bootcamp grad, offshore contractor, AI-assisted intern — touches that code. Every PR is a potential bypass. Every "quick fix" is a load-bearing card in a house of cards.&lt;/p&gt;

&lt;p&gt;And now the code itself is generated by a machine that has no memory of why the rule exists, no context for the incident that created it, and no skin in the game if it gets it wrong.&lt;/p&gt;

&lt;p&gt;You have &lt;strong&gt;perfect version control over slop.&lt;/strong&gt; Git tells you exactly which commit introduced the wrong behavior. Congratulations. The audit trail of your own mistakes is immaculate.&lt;/p&gt;

&lt;p&gt;Meanwhile, you're doing standup, sprint planning, architecture reviews, and PR approvals — all of it cope. Elaborate institutional cope to manage the entropy of logic that was never safe outside a controlled environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Churn Math Nobody Wants to Do
&lt;/h2&gt;

&lt;p&gt;Ask yourself honestly: &lt;strong&gt;which role churns faster at your company?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The JavaScript developer — framework-hopping, chasing the ecosystem, mentally rewriting their stack every 18 months. React → hooks → RSC. REST → GraphQL → tRPC. Webpack → Vite → whatever drops next Tuesday. Their knowledge doesn't compound. It rotates.&lt;/p&gt;

&lt;p&gt;Or the bearded guy with the SQL wand.&lt;/p&gt;

&lt;p&gt;The senior DBA who's been writing joins since before your current frontend framework was a GitHub repo. Whose CTEs from 2015 still run. Whose understanding of indexes, vacuuming, and query planning compounds year over year. Postgres 17 still respects everything he wrote in Postgres 10.&lt;/p&gt;

&lt;p&gt;You also cannot fake SQL mastery in an interview. Run &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; on the query. No leetcode theater. No rehearsed system design answers. Either the query plan shows 3ms with an index-only scan, or it shows a sequential scan on 2 million rows and you're done. The database is the interviewer, and it has no unconscious bias and cannot be charmed.&lt;/p&gt;

&lt;p&gt;Meanwhile your JS interview pipeline is a gymnasium for people who memorized 50 leetcode patterns for 3 weeks. They pass. They join. You find out 6 months later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Own What AI Cannot Slop
&lt;/h2&gt;

&lt;p&gt;Here's the reframe:&lt;/p&gt;

&lt;p&gt;There are now two zones in your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Above the line:&lt;/strong&gt; AI territory. Generate freely. Redeploy in minutes. Let the contractors, the juniors, the agents write it. Move fast. Break things. The BFF, the frontend, the API adapters — disposable by design. This is where velocity lives and chaos is acceptable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below the line:&lt;/strong&gt; The fortress. Slow. Deliberate. Council-gated. Changes are rare and ritualistic. This is where correctness lives and velocity is the enemy.&lt;/p&gt;

&lt;p&gt;The line is the database boundary.&lt;/p&gt;

&lt;p&gt;And the crucial insight: &lt;strong&gt;you cannot prompt your way into changing a trigger.&lt;/strong&gt; The AI can generate a million BFF variations. Every single one hits the same wall. The invariant holds not because anyone checked the PR, but because the system enforces it at a layer where velocity doesn't operate.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Postgres Temple Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;The PostgreSQL-centric architecture — sometimes called Planetary Architecture — inverts the conventional stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raw tables&lt;/strong&gt; are locked. &lt;code&gt;REVOKE ALL&lt;/code&gt; from everyone including the application user. Superadmin only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Views&lt;/strong&gt; are the only access surface. One table, many views — scoped by role, redacted by sensitivity, filtered by RLS policies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INSTEAD OF triggers&lt;/strong&gt; are the only mutation path. Business logic lives in Postgres functions called by triggers. Not in your service layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row-Level Security&lt;/strong&gt; is authorization. Not middleware. Not JWT decoded in a controller. The database itself decides what each role can see and touch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FDW forensic audit&lt;/strong&gt; writes to a separate database server on a separate host. Append-only. If your main DB gets ransomwared, the audit trail is untouched.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application user — the one your PostgREST or Django connects with — can see metadata on raw tables but never read a row directly. The BFF consumes views and calls functions. It has no idea what the underlying schema looks like.&lt;/p&gt;

&lt;p&gt;A junior dev, an AI agent, an offshore contractor — they work on the BFF. They literally cannot bypass business logic because there is no surface to touch. The database rejects it at the query level.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Seniors Become Force Multipliers
&lt;/h2&gt;

&lt;p&gt;This architecture changes what "senior" means.&lt;/p&gt;

&lt;p&gt;In a conventional stack, seniors spend their leverage on reviews, mentoring, and trying to slow down the entropy of a dozen people touching business logic simultaneously. They're playing defense constantly.&lt;/p&gt;

&lt;p&gt;In the Postgres temple, the senior writes the fortress &lt;strong&gt;once&lt;/strong&gt;, correctly. Encodes the rules into trigger functions, RLS policies, view contracts. Then steps back.&lt;/p&gt;

&lt;p&gt;The chaos above the line doesn't require their supervision anymore — because the architecture does the supervision. One council of SQL wardens can safely oversee an arbitrarily large BFF team of agents, juniors, and contractors. The blast radius of any mistake above the line is hard-bounded by what PostgREST exposes, which is bounded by what views exist, which is bounded by what the senior built.&lt;/p&gt;

&lt;p&gt;The more junior and AI-heavy your above-the-line becomes, the &lt;strong&gt;more&lt;/strong&gt; valuable the below-the-line fortress gets. The chaos above justifies the rigidity below.&lt;/p&gt;




&lt;h2&gt;
  
  
  This Isn't a 90s Idea. It's the Correct Response to 2026
&lt;/h2&gt;

&lt;p&gt;The Oracle shops of the 90s had this right. Business logic in stored procedures. Schema changes as rituals. DBAs as priests. Nobody pushed to production without the warden's blessing.&lt;/p&gt;

&lt;p&gt;We abandoned it because startups needed to move faster than that culture allowed, and Rails made it feel unnecessary. We traded correctness guarantees for velocity, and it worked — when humans were still the velocity bottleneck.&lt;/p&gt;

&lt;p&gt;That trade no longer makes sense. The velocity problem is solved. The correctness problem is now existential.&lt;/p&gt;

&lt;p&gt;The bearded SQL warden who stays 10 years, whose fortress gets stronger over time, whose knowledge doesn't deprecate — that person is now the most strategically valuable engineer in your organization.&lt;/p&gt;

&lt;p&gt;Not because SQL is magic. Because &lt;strong&gt;owning the one layer that AI cannot slop is now the entire game.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The One Sentence
&lt;/h2&gt;

&lt;p&gt;Your code is a sacred cow bred by a slop machine, kept alive by PR prayers and best-practice inhalers.&lt;/p&gt;

&lt;p&gt;Put your sacred cow in Postgres, where the DB is the priest, and no agent, no junior, no tired tech lead reviewing his 40th PR of the week can accidentally sacrifice it on a Friday deploy.&lt;/p&gt;

&lt;p&gt;The fortress holds. The orbit burns. That's the architecture.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Inspired by &lt;a href="https://dev.to/ryo_suwito/postgresql-centric-planetary-architecture-1gon"&gt;PostgreSQL centric - Planetary Architecture&lt;/a&gt; by Ryo Suwito.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #postgres #architecture #systemdesign #webdev #programming&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>PostgreSQL centric - Planetary Architecture</title>
      <dc:creator>Ryo Suwito</dc:creator>
      <pubDate>Mon, 18 May 2026 12:39:32 +0000</pubDate>
      <link>https://dev.to/ryo_suwito/postgresql-centric-planetary-architecture-1gon</link>
      <guid>https://dev.to/ryo_suwito/postgresql-centric-planetary-architecture-1gon</guid>
      <description>&lt;h2&gt;
  
  
  Product Requirements Document
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;PostgreSQL is not the persistence layer. It is the application. Everything else is orbit.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. Vision
&lt;/h2&gt;

&lt;p&gt;Modern web stacks treat the database as a dumb filing cabinet at the end of a long chain — request → router → controller → service → ORM → DB. Business logic is smeared across every layer. Security is enforced in the app. Permissions live in middleware. Mutations go through serializers. The database just executes &lt;code&gt;INSERT&lt;/code&gt; and stays quiet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Planetary Architecture inverts this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL is the sun. Every other component — the admin dashboard, the HTTP adapter, the frontend, the external services — orbits it. Business logic, authorization, validation, transformation, and auditing all live inside Postgres. Downstream layers are deliberately dumb: they render, they route, they receive webhooks. They do not own logic.&lt;/p&gt;

&lt;p&gt;The platform — &lt;strong&gt;django-pg-planetary&lt;/strong&gt; — is the control plane that makes this architecture operable without writing a single line of SQL. It extends Django admin into a full database operations dashboard, serving every persona involved in building and running a Planetary stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Stack
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                      CONTROL PLANE                          │
│         django-pg-planetary (Django Admin Extension)        │
│         Karen · Bob · Senior Dev — one unified dashboard    │
└──────────────────────────┬──────────────────────────────────┘
                           │  DDL only · metadata only
                           │  never raw table data
┌──────────────────────────▼──────────────────────────────────┐
│                   ☀️  POSTGRESQL (the app)                   │
│                                                             │
│  raw tables      — superadmin only, REVOKE ALL on everyone  │
│  views           — DTOs, redacted, role-scoped              │
│  INSTEAD OF      — the only way CUD ever happens            │
│  functions       — business logic, overloaded by signature  │
│  RLS policies    — authorization at the row level           │
│  triggers        — mutations, audits, notifications         │
│  types/domains   — validated, reusable data shapes          │
│  FDW             — forensic audit to separate DB            │
│  pg_notify       — async event emission                     │
└────────┬────────────────────────────────────────────────────┘
         │                              │
         │ pg_notify / pg_net           │ SQL over HTTP
         │                  ┌───────────▼──────────┐
         │                  │       PostgREST       │
         │                  │   dumb HTTP adapter   │
         │                  │   exposes views +     │
         │                  │   functions as REST   │
         │                  └───────────┬──────────┘
         │                              │ REST + JWT
         │                  ┌───────────▼──────────┐
         │                  │     Next.js BFF       │
         │                  │  renders · consumes   │
         │                  │  zero business logic  │
         │                  └───────────┬──────────┘
         │                              │
┌────────▼──────────────────────────────▼──────────────────────┐
│                   SERVICES (dumb, isolated)                   │
│     pdf-export · email · payment · sms · storage · etc.      │
│     receive payload · do one thing · return result           │
│     know nothing about the DB schema                         │
└──────────────────────────────────────────────────────────────┘
         │
┌────────▼──────────────────────────────────────────────────────┐
│                    AUDIT DB (FDW shadow)                       │
│     separate server · append-only · forensic isolation        │
│     full before/after JSON trail per row per operation        │
└────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Personas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Karen — Business Operations
&lt;/h3&gt;

&lt;p&gt;Uses Django admin to browse and manage data rows. Her experience is unchanged from standard Django admin. She interacts with &lt;strong&gt;views&lt;/strong&gt; only — never raw tables. RLS ensures she sees exactly what her role allows, automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bob — DevOps / DB Administrator
&lt;/h3&gt;

&lt;p&gt;Uses the planetary extension to manage the full Postgres security and infrastructure layer. &lt;strong&gt;Zero SQL written.&lt;/strong&gt; He manages roles, grants, policies, table health, scheduled jobs, replication, and configuration through GUI forms that generate and execute SQL behind the scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Senior Developer
&lt;/h3&gt;

&lt;p&gt;Uses the extension to design and apply the Postgres application layer. Writes function bodies, designs view schemas, declares protected tables, manages types, configures FTS, and controls the audit setup. The platform scaffolds everything; Senior fills in the business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgREST (system actor)
&lt;/h3&gt;

&lt;p&gt;Watches Postgres. Exposes whatever views and functions exist as REST endpoints, scoped by JWT role claims. Picks up every change Senior makes automatically. No configuration required per new view or function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js BFF (system actor)
&lt;/h3&gt;

&lt;p&gt;Consumes PostgREST endpoints. Renders data. Calls service endpoints for non-DB operations. Has no knowledge of the underlying schema, RLS rules, or function signatures.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Core Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 The Protected Table Contract
&lt;/h3&gt;

&lt;p&gt;Every raw table in a Planetary stack follows this contract:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;REVOKE ALL ON raw_table FROM PUBLIC&lt;/code&gt; — no one touches data directly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;REVOKE ALL ON raw_table FROM app_role&lt;/code&gt; — includes the Django DB user&lt;/li&gt;
&lt;li&gt;One or more &lt;strong&gt;views&lt;/strong&gt; declared as the only access points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INSTEAD OF triggers&lt;/strong&gt; on each view — the only mutation path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overloaded functions&lt;/strong&gt; per operation type — validation and transformation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RLS on views&lt;/strong&gt; — row-level authorization per role/claim&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The platform scaffolds steps 1–6 from a single "Protect this table" action. Senior fills in function bodies. Everything else is generated.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Views as DTOs
&lt;/h3&gt;

&lt;p&gt;A view is not a convenience — it is an explicit API contract. One raw table can have many views:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice_raw          ← locked, superadmin only
  invoice_v          ← standard ops view, status + amounts
  invoice_v_finance  ← finance role, full breakdown
  invoice_v_redacted ← public-facing, PII masked
  invoice_v_audit    ← compliance, all fields + metadata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PostgREST exposes each view as a separate endpoint. RLS on each view enforces who can query what. No app-layer serializers needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Metadata ≠ Data Privileges
&lt;/h3&gt;

&lt;p&gt;Revoking data access from the Django DB user does NOT revoke metadata access. The platform can fully introspect any table's columns, types, constraints, indexes, policies, and triggers via &lt;code&gt;pg_catalog&lt;/code&gt; and &lt;code&gt;information_schema&lt;/code&gt; — without ever reading a row of actual data. This is the foundation of the view builder, policy editor, and trigger scaffolder.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4 Functions as the Business Logic Layer
&lt;/h3&gt;

&lt;p&gt;Postgres functions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overloadable by signature — &lt;code&gt;process_invoice(a)&lt;/code&gt; and &lt;code&gt;process_invoice(a, b)&lt;/code&gt; coexist&lt;/li&gt;
&lt;li&gt;Transactional — they run inside the trigger's transaction&lt;/li&gt;
&lt;li&gt;Testable — callable directly via PostgREST or &lt;code&gt;SELECT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Replaceable — &lt;code&gt;CREATE OR REPLACE&lt;/code&gt; with no downtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All validation, transformation, computed fields, and side-effect orchestration live in functions. The app layer calls views. It never implements business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.5 FDW Forensic Audit
&lt;/h3&gt;

&lt;p&gt;Audit triggers write to a foreign table backed by a separate database server via &lt;code&gt;postgres_fdw&lt;/code&gt;. The audit DB is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a different host (optionally different provider)&lt;/li&gt;
&lt;li&gt;Append-only by policy — no UPDATE, no DELETE&lt;/li&gt;
&lt;li&gt;Invisible to application roles&lt;/li&gt;
&lt;li&gt;Full &lt;code&gt;row_to_json(OLD)&lt;/code&gt; / &lt;code&gt;row_to_json(NEW)&lt;/code&gt; per operation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the main DB is compromised, wiped, or ransomwared — the audit trail is untouched on a completely separate server. The platform wires this up per table with a toggle.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Platform Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Introspection Engine
&lt;/h3&gt;

&lt;p&gt;The foundation. Pure &lt;code&gt;pg_catalog&lt;/code&gt; + &lt;code&gt;information_schema&lt;/code&gt; queries. Returns structured metadata the UI builds on. No data access required.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tables, columns, data types, nullability, defaults&lt;/li&gt;
&lt;li&gt;Constraints — PK, FK, unique, check, exclusion&lt;/li&gt;
&lt;li&gt;Indexes — type, columns, partial condition, expression&lt;/li&gt;
&lt;li&gt;Views + materialized views — definition, dependencies&lt;/li&gt;
&lt;li&gt;Stored functions + procedures — signature, language, body, security&lt;/li&gt;
&lt;li&gt;Triggers — timing, event, level, condition, function&lt;/li&gt;
&lt;li&gt;Policies — command, roles, USING, WITH CHECK expressions&lt;/li&gt;
&lt;li&gt;Roles + grants — membership, table/column/schema privileges&lt;/li&gt;
&lt;li&gt;Extensions — installed, available, version&lt;/li&gt;
&lt;li&gt;FDW servers + foreign tables&lt;/li&gt;
&lt;li&gt;Publications + subscriptions&lt;/li&gt;
&lt;li&gt;Table health — live tuples, dead tuples, bloat, last vacuum/analyze&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2 Protected Table Manager (Senior + Bob)
&lt;/h3&gt;

&lt;p&gt;The core workflow of the platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declare a table as protected:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select table from introspected list&lt;/li&gt;
&lt;li&gt;Platform generates REVOKE statements for all non-superadmin roles&lt;/li&gt;
&lt;li&gt;Column picker: drag-drop columns into one or more named views&lt;/li&gt;
&lt;li&gt;Per-column: include / exclude / apply redaction function&lt;/li&gt;
&lt;li&gt;Platform generates &lt;code&gt;CREATE VIEW&lt;/code&gt; for each declared view&lt;/li&gt;
&lt;li&gt;INSTEAD OF trigger skeleton auto-generated per view&lt;/li&gt;
&lt;li&gt;Senior writes function body in inline editor&lt;/li&gt;
&lt;li&gt;One-click apply — REVOKE + views + triggers executed in single transaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;View builder:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual column selector from introspected schema&lt;/li&gt;
&lt;li&gt;Redaction function picker (mask_pan, mask_email, hash, nullify, etc.)&lt;/li&gt;
&lt;li&gt;Live SQL preview&lt;/li&gt;
&lt;li&gt;Role assignment — which PostgREST role sees this view&lt;/li&gt;
&lt;li&gt;RLS policy generator — column picker for USING expression&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.3 Policy Manager — RLS / RBAC / ABAC / PBAC (Bob + Senior)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RLS Policies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable/disable RLS per table/view — toggle&lt;/li&gt;
&lt;li&gt;Create policy: name, table, command (ALL/SELECT/INSERT/UPDATE/DELETE)&lt;/li&gt;
&lt;li&gt;USING expression builder — column picker + operator + value/function&lt;/li&gt;
&lt;li&gt;WITH CHECK expression builder&lt;/li&gt;
&lt;li&gt;PERMISSIVE vs RESTRICTIVE toggle&lt;/li&gt;
&lt;li&gt;Role assignment&lt;/li&gt;
&lt;li&gt;Live SQL preview&lt;/li&gt;
&lt;li&gt;Active policies list with enable/disable per policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Role Management (RBAC):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create / rename / drop roles&lt;/li&gt;
&lt;li&gt;Role membership — assign roles to roles (hierarchy)&lt;/li&gt;
&lt;li&gt;Grant / revoke table privileges per role&lt;/li&gt;
&lt;li&gt;Grant / revoke column-level privileges&lt;/li&gt;
&lt;li&gt;Grant / revoke schema privileges&lt;/li&gt;
&lt;li&gt;Grant / revoke function execute privileges&lt;/li&gt;
&lt;li&gt;Role matrix view — roles × tables × privileges grid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Session Claims (ABAC):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define &lt;code&gt;current_setting('app.x')&lt;/code&gt; claim variables used in policies&lt;/li&gt;
&lt;li&gt;JWT claim → &lt;code&gt;set_config&lt;/code&gt; mapping documentation per role&lt;/li&gt;
&lt;li&gt;Policy expression helpers using claim variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Policy Templates (PBAC):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User-owns-row: &lt;code&gt;user_id = current_setting('app.user_id')::uuid&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tenant isolation: &lt;code&gt;tenant_id = (auth.jwt() -&amp;gt;&amp;gt; 'tenant_id')::uuid&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Soft-delete filter: &lt;code&gt;deleted_at IS NULL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Time-bounded: &lt;code&gt;valid_from &amp;lt;= now() AND valid_to &amp;gt;= now()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Save custom templates — reusable across tables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.4 Function &amp;amp; Trigger Manager (Senior)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all stored functions with signature, language, security mode&lt;/li&gt;
&lt;li&gt;Create / edit function — inline code editor with syntax highlighting&lt;/li&gt;
&lt;li&gt;Language picker — plpgsql, sql, python (plpython3u)&lt;/li&gt;
&lt;li&gt;SECURITY INVOKER vs SECURITY DEFINER toggle&lt;/li&gt;
&lt;li&gt;Parameter builder — name, type, default, mode (IN/OUT/INOUT)&lt;/li&gt;
&lt;li&gt;Return type picker — scalar, setof, table, trigger, void&lt;/li&gt;
&lt;li&gt;Function overload group view — all signatures for same name&lt;/li&gt;
&lt;li&gt;Test runner — call function with sample args, see output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Triggers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all triggers per table with status&lt;/li&gt;
&lt;li&gt;Create trigger: timing (BEFORE/AFTER/INSTEAD OF), event (INSERT/UPDATE/DELETE/TRUNCATE)&lt;/li&gt;
&lt;li&gt;Column-specific UPDATE trigger (OF col1, col2)&lt;/li&gt;
&lt;li&gt;FOR EACH ROW vs FOR EACH STATEMENT toggle&lt;/li&gt;
&lt;li&gt;WHEN condition builder&lt;/li&gt;
&lt;li&gt;Function picker from existing trigger functions&lt;/li&gt;
&lt;li&gt;Enable / disable per trigger&lt;/li&gt;
&lt;li&gt;Deferrable + deferred toggle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Event Triggers (DDL-level):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fire on CREATE TABLE, ALTER TABLE, DROP, etc.&lt;/li&gt;
&lt;li&gt;Auto-attach audit triggers to any new table — set-and-forget for Bob&lt;/li&gt;
&lt;li&gt;Enforce naming conventions on DDL operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.5 Schema Object Manager (Senior + Bob)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Views:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all views with definition preview&lt;/li&gt;
&lt;li&gt;Create / edit view — column picker + SQL editor&lt;/li&gt;
&lt;li&gt;Dependency graph — which tables/functions a view uses&lt;/li&gt;
&lt;li&gt;Drop cascade safety — shows what breaks before executing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Materialized Views:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create materialized view from view or raw SQL&lt;/li&gt;
&lt;li&gt;Refresh strategy — manual / &lt;code&gt;pg_cron&lt;/code&gt; scheduled&lt;/li&gt;
&lt;li&gt;Refresh schedule builder (cron expression)&lt;/li&gt;
&lt;li&gt;Index management on materialized view columns&lt;/li&gt;
&lt;li&gt;Concurrent refresh toggle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Custom Types:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ENUM types — create, add values, rename, drop&lt;/li&gt;
&lt;li&gt;Composite types — field builder with name + type&lt;/li&gt;
&lt;li&gt;Domain types — base type + CHECK constraint&lt;/li&gt;
&lt;li&gt;Range types — subtype + canonical function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Extensions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available extensions list with description&lt;/li&gt;
&lt;li&gt;Install / drop per extension&lt;/li&gt;
&lt;li&gt;Version display&lt;/li&gt;
&lt;li&gt;Commonly useful: &lt;code&gt;uuid-ossp&lt;/code&gt;, &lt;code&gt;pgcrypto&lt;/code&gt;, &lt;code&gt;pg_stat_statements&lt;/code&gt;, &lt;code&gt;pg_cron&lt;/code&gt;, &lt;code&gt;pg_net&lt;/code&gt;, &lt;code&gt;postgres_fdw&lt;/code&gt;, &lt;code&gt;postgis&lt;/code&gt;, &lt;code&gt;unaccent&lt;/code&gt;, &lt;code&gt;btree_gin&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sequences:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List, create, alter (start, increment, min, max, cycle)&lt;/li&gt;
&lt;li&gt;Current value display&lt;/li&gt;
&lt;li&gt;Owned-by column display&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Schemas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create / drop schemas&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;search_path&lt;/code&gt; configuration per role&lt;/li&gt;
&lt;li&gt;Move tables between schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.6 Index Manager (Bob + Senior)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;List all indexes — type, columns, size, usage stats&lt;/li&gt;
&lt;li&gt;Detect unused indexes via &lt;code&gt;pg_stat_user_indexes&lt;/code&gt; (idx_scan = 0)&lt;/li&gt;
&lt;li&gt;Create index — type picker (B-tree, GIN, GiST, BRIN, Hash)&lt;/li&gt;
&lt;li&gt;Partial index — WHERE clause builder&lt;/li&gt;
&lt;li&gt;Expression index — expression input with column picker&lt;/li&gt;
&lt;li&gt;Concurrent build toggle (non-blocking)&lt;/li&gt;
&lt;li&gt;Index size vs query benefit display&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.7 Full Text Search (Senior)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Text search configuration manager&lt;/li&gt;
&lt;li&gt;Dictionary management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tsvector&lt;/code&gt; column setup — which columns, which config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;to_tsvector&lt;/code&gt; expression builder&lt;/li&gt;
&lt;li&gt;GIN index auto-suggestion on tsvector columns&lt;/li&gt;
&lt;li&gt;Test query — enter search terms, preview ranked results&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.8 Audit Layer (Bob)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enable audit per table — toggle&lt;/li&gt;
&lt;li&gt;FDW server configuration — host, dbname, credentials&lt;/li&gt;
&lt;li&gt;Foreign table auto-creation on audit DB&lt;/li&gt;
&lt;li&gt;Audit trigger auto-generated and attached&lt;/li&gt;
&lt;li&gt;Audit log viewer (reads from foreign table — read-only)&lt;/li&gt;
&lt;li&gt;Audit DB health status&lt;/li&gt;
&lt;li&gt;Retention policy — &lt;code&gt;pg_cron&lt;/code&gt; job to prune old audit records (on audit DB side)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.9 Replication &amp;amp; CDC (Bob)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Publications — create, add/remove tables, manage row filters&lt;/li&gt;
&lt;li&gt;Subscriptions — create, monitor lag, enable/disable&lt;/li&gt;
&lt;li&gt;Logical replication slot monitoring&lt;/li&gt;
&lt;li&gt;FDW connections — list, test, drop&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.10 Scheduled Jobs — pg_cron (Bob)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;List all cron jobs with schedule, last run, status&lt;/li&gt;
&lt;li&gt;Create job — SQL input + cron expression builder&lt;/li&gt;
&lt;li&gt;Enable / disable per job&lt;/li&gt;
&lt;li&gt;Run now (immediate one-off execution)&lt;/li&gt;
&lt;li&gt;Job run history + error log&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.11 Notifications — pg_notify / pg_net (Senior)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NOTIFY channels in use — list active LISTEN connections&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pg_net&lt;/code&gt; webhook trigger builder — target URL, payload template&lt;/li&gt;
&lt;li&gt;Outbound webhook log (via &lt;code&gt;net._http_response&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.12 Performance &amp;amp; Health (Bob)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Table stats — live tuples, dead tuples, bloat %, last vacuum/analyze&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pg_stat_statements&lt;/code&gt; — top queries by total time, calls, mean time&lt;/li&gt;
&lt;li&gt;Cache hit ratio — buffer hits vs disk reads&lt;/li&gt;
&lt;li&gt;Connection stats — active, idle, idle-in-transaction, by role&lt;/li&gt;
&lt;li&gt;Lock monitor — active locks, blocking queries, wait graph&lt;/li&gt;
&lt;li&gt;VACUUM / ANALYZE — trigger manually per table or ALL&lt;/li&gt;
&lt;li&gt;Autovacuum settings — per-table overrides (fillfactor, thresholds)&lt;/li&gt;
&lt;li&gt;Table size breakdown — table + indexes + toast&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.13 Configuration (Bob)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ALTER SYSTEM&lt;/code&gt; GUI — categorized parameter list&lt;/li&gt;
&lt;li&gt;Search params by name or description&lt;/li&gt;
&lt;li&gt;Current vs pending (requires reload) indicator&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pg_reload_conf()&lt;/code&gt; trigger button&lt;/li&gt;
&lt;li&gt;Per-database and per-role parameter overrides via &lt;code&gt;ALTER DATABASE SET&lt;/code&gt; / &lt;code&gt;ALTER ROLE SET&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.14 PostgREST Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;View → PostgREST endpoint mapping display&lt;/li&gt;
&lt;li&gt;Function → RPC endpoint display (&lt;code&gt;/rpc/function_name&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;JWT role claim → Postgres role mapping documentation&lt;/li&gt;
&lt;li&gt;Schema cache reload trigger (&lt;code&gt;NOTIFY pgrst, 'reload schema'&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Endpoint health check per view&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Non-Goals
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not a data browser.&lt;/strong&gt; Django admin owns rows and data management. This platform does not display table contents except for the audit log viewer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a query editor.&lt;/strong&gt; Not a replacement for psql, DBeaver, or TablePlus. Senior who needs raw SQL uses those tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not an ORM.&lt;/strong&gt; No model abstraction. Everything is native Postgres SQL, generated and executed directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a migration framework.&lt;/strong&gt; No Alembic/django-migrate style versioned migrations. DDL changes are applied directly. Event triggers handle DDL auditing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a connection pooler.&lt;/strong&gt; PgBouncer / Supavisor are separate infrastructure concerns.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Privilege Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;superadmin         → everything. raw tables, DDL, pg_catalog, config
senior_dev role    → DDL via platform, metadata, no raw table data
bob_devops role    → platform UI operations, metadata, health stats
django_app role    → metadata on raw tables, data on views only
postgrest role     → data on views, scoped by JWT sub-role
karen role         → rows in views, filtered by RLS
audit_writer role  → INSERT only on foreign audit tables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The platform authenticates as &lt;code&gt;django_app&lt;/code&gt; for introspection. DDL operations are executed via a separate &lt;code&gt;platform_ddl&lt;/code&gt; role with elevated privileges, scoped to specific operations, never exposed to the HTTP layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Package Design
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-pg-planetary/
├── planetary/
│   ├── apps.py                  ← PlanetaryConfig, auto-registers admin
│   ├── introspect/
│   │   ├── tables.py            ← columns, types, constraints
│   │   ├── policies.py          ← pg_policies queries
│   │   ├── roles.py             ← pg_roles, memberships, grants
│   │   ├── routines.py          ← functions, triggers, event triggers
│   │   ├── objects.py           ← views, matviews, types, sequences
│   │   ├── indexes.py           ← index stats, usage
│   │   ├── health.py            ← pg_stat_*, vacuum, bloat
│   │   └── replication.py       ← publications, subscriptions, slots
│   ├── builders/
│   │   ├── policy_builder.py    ← CREATE/ALTER/DROP POLICY → SQL
│   │   ├── role_builder.py      ← GRANT/REVOKE/CREATE ROLE → SQL
│   │   ├── trigger_builder.py   ← CREATE/DROP TRIGGER → SQL
│   │   ├── view_builder.py      ← CREATE VIEW / INSTEAD OF → SQL
│   │   ├── function_builder.py  ← CREATE OR REPLACE FUNCTION → SQL
│   │   └── audit_builder.py     ← FDW setup, audit trigger → SQL
│   ├── executor.py              ← safe DDL execution, transaction wrapper
│   ├── admin/
│   │   ├── policy_admin.py
│   │   ├── role_admin.py
│   │   ├── schema_admin.py
│   │   ├── trigger_admin.py
│   │   ├── function_admin.py
│   │   ├── health_admin.py
│   │   ├── audit_admin.py
│   │   └── cron_admin.py
│   ├── templates/
│   │   └── admin/planetary/     ← per-view HTML templates
│   └── static/
│       └── planetary/           ← JS for live SQL preview, editors
└── setup.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Installation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# settings.py
&lt;/span&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.contrib.admin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;planetary&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;# adds Planetary section to admin
&lt;/span&gt;    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;PLANETARY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DDL_ROLE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;platform_ddl&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# elevated role for DDL ops
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AUDIT_SERVER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;audit_db_server&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# FDW server name for audit
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POSTGREST_URL&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="sh"&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;h2&gt;
  
  
  9. The Paradigm in One Sentence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Karen checks the data. Bob secures the database. Senior encodes the rules. Postgres enforces everything. PostgREST exposes it. Next.js renders it. Services handle the side effects. Nobody writes middleware.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
