<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Notes by Mo Tawfik Khalifa</title><link>https://tawfik.tv/notes</link>
<description>Building products, live systems, real-time worlds and AI.</description><language>en-gb</language><item><title>3D product animation for industrial equipment: films, interactive 3D, AR and a website that sells</title><link>https://tawfik.tv/notes/3d-product-animation-industrial-equipment</link><guid>https://tawfik.tv/notes/3d-product-animation-industrial-equipment</guid>
<pubDate>Sun, 18 Oct 2026 09:00:00 +0000</pubDate><description>3D product animation for industrial equipment shows how a unit works inside. One model gives you the films, a 3D viewer, AR and stills for every product page.</description>
<content:encoded><![CDATA[<p>3D product animation for industrial equipment is a film or an interactive model, built from the unit&rsquo;s drawings, that shows what a camera cannot: the inside, how it works and how it comes apart. Build the model once and the same files give you the films, a 3D viewer on the product page, an AR model a buyer stands in their own yard, and stills for datasheets and tenders.</p>
<p>Buyers look for this. In <a href="https://ads.google.com/home/tools/keyword-planner/">Google Keyword Planner</a>, &ldquo;3d animation services&rdquo;, &ldquo;3d rendering services&rdquo; and &ldquo;website for manufacturers&rdquo; each get 1,000 to 10,000 searches a month across the US, the UK, the UAE and Saudi Arabia (my pull, 18 October 2026). Top-of-page bids for &ldquo;industrial marketing agency&rdquo; and &ldquo;manufacturing marketing agency&rdquo; run $54 and $66 a click.</p>
<p>I built the whole set for an industrial process-equipment distributor serving plants across the Gulf: Blender films, seven interactive equipment families, a TEMA type explorer, an AR model, and 40 product pages in English and Arabic. Here is what each piece is, what it costs on the market, and how to keep it fast on a phone.</p>
<h2>What is 3D product animation for industrial equipment?</h2>
<p>It is engineering-accurate 3D, lit and filmed like a product shoot, then cut three ways: films, stills and real-time models.</p>
<p>The centrepiece for the client is E-101, a TEMA AES shell-and-tube exchanger I modelled in Blender: 1,148 copper-nickel tubes, class 300 flanges, a cover davit, saddles on concrete piers and a stencilled tag. Its 240-frame film walks up to the unit at night, unbolts the channel, swings it clear, draws the tube bundle onto timber cribs and runs an eddy current probe down the tubes. On the client&rsquo;s site it plays as you scroll, with labels that track the parts.</p>
<p><a href="https://tawfik.tv/notes/3d-product-animation-industrial-equipment">Open the interactive diagram on tawfik.tv</a></p>

<h2>What is technical animation: cutaways, exploded views and how it works?</h2>
<p>Technical animation (also called mechanical or equipment animation) explains a machine instead of selling a mood. Three moves do most of the work:</p>
<ul>
<li><strong>Cutaway.</strong> Slice the unit to show what a photo hides. I cut a reformer furnace open to show the tubes glowing inside, and cut a three-phase separator in half so gas, oil and water separate in front of you.</li>
<li><strong>Exploded view.</strong> Take it apart in order. The plate exchanger&rsquo;s nuts spin off, the pressure plate rolls back and 40 plates unfurl.</li>
<li><strong>How it works.</strong> Show the physics. In the reverse osmosis rack, the membrane layers turn sea green as water reaches them.</li>
</ul>
<p>Every family on the client&rsquo;s site has its own control, and no two repeat. Pick one:</p>
<p><a href="https://tawfik.tv/notes/3d-product-animation-industrial-equipment">Open the interactive diagram on tawfik.tv</a></p>

<aside class="cta"><p>Want your equipment line explained like this? I build the 3D, the films and the controls.</p><div><a class="cbtn" href="https://tawfik.tv/book" data-cta="after-demo">Book a 30-minute call</a><a class="cbtn ghost" href="mailto:m@tawfik.tv?subject=3D%20for%20industrial%20equipment" data-cta="after-demo">Email me</a></div></aside>

<h2>3D animation services or 3D rendering services: which do you need?</h2>
<p><strong>3D rendering</strong> gives you still images: datasheet covers, tender documents, catalogue pages. <strong>3D animation</strong> gives you motion: a how-it-works film, a cutaway, a trade show loop. <strong>Real-time 3D</strong> runs in the browser and the visitor controls it.</p>
<p>You rarely need to choose. The model is the expensive part, so build it to an engineering standard once and render stills, films and web versions from the same file. Every image on this page comes from one set of Blender scenes.</p>
<h2>What is a 3D product viewer, and when do you need a product configurator?</h2>
<p>A <strong>3D product viewer</strong> puts a model on the page that buyers can turn and zoom. A <strong>product configurator</strong> goes further: each choice changes the product, and the page shows the result and the spec. I wrote up the tools behind both in <a href="https://tawfik.tv/notes/threejs-website">three.js website</a>.</p>
<p>For the client I built a TEMA type explorer in three.js: pick a front head, shell and rear head and an X-ray bundle model redraws, then the choice fills the enquiry form. Here is a lighter version as a general arrangement drawing. Its quote button carries your spec.</p>
<p><a href="https://tawfik.tv/notes/3d-product-animation-industrial-equipment">Open the interactive diagram on tawfik.tv</a></p>

<aside class="cta"><p>Need a configurator for your product range? Send me the options and the rules between them.</p><div><a class="cbtn" href="https://tawfik.tv/book" data-cta="after-demo">Book a 30-minute call</a><a class="cbtn ghost" href="mailto:m@tawfik.tv?subject=Product%20configurator" data-cta="after-demo">Email me</a></div></aside>

<p>For building products, I built a <a href="https://tawfik.tv/building-product-configurator">3D building product configurator</a> where you tap a part of a building and get the products that fit, the spec and the quantities.</p>
<h2>What is web AR, and can a buyer see the unit in their own yard?</h2>
<p>Web AR opens the phone&rsquo;s camera from a link and stands a 3D model in the room or the yard, at real size, with no app. On Android it runs through <a href="https://developers.google.com/ar/develop/scene-viewer">Scene Viewer</a>, on iPhone through <a href="https://developer.apple.com/augmented-reality/quick-look/">AR Quick Look</a>. Google&rsquo;s free <a href="https://modelviewer.dev/docs/">model-viewer</a> puts both behind one button.</p>
<p>E-101 ships as a 1.2 MB glTF file with Draco-compressed meshes. Nothing loads until you ask:</p>
<p><a href="https://tawfik.tv/notes/3d-product-animation-industrial-equipment">Open the interactive diagram on tawfik.tv</a></p>

<aside class="cta"><p>Want your units in a buyer's yard from a link? I make the AR files from your drawings or CAD.</p><div><a class="cbtn" href="https://tawfik.tv/book" data-cta="after-demo">Book a 30-minute call</a><a class="cbtn ghost" href="mailto:m@tawfik.tv?subject=Web%20AR%20for%20equipment" data-cta="after-demo">Email me</a></div></aside>

<h2>Can you turn BIM or CAD files into an interactive 3D product or plant?</h2>
<p>Yes. BIM to 3D is how I won <a href="https://tawfik.tv/projects/seven-al-hamra">SEVEN Al Hamra</a> in Riyadh: I took the construction team&rsquo;s Revit, IFC and Navisworks models, about 650 MB, and turned them into a real-time replica people walked through before the building opened. The <a href="https://tawfik.tv/worlds/rvt">browser version</a> is a 74 MB download. People search for Revit to web or an IFC viewer online; a viewer shows the file as it is, while I rebuild it for speed.</p>
<p>Equipment works the same way from STEP or IGES CAD, GA drawings and datasheets. Standard equipment needs no CAD: E-101 is built from standard dimensions. If you want the model tied to live plant data, that is a <a href="https://tawfik.tv/notes/what-is-a-digital-twin">digital twin</a>.</p>
<h2>What should a website for manufacturers and distributors do?</h2>
<p>Answer the engineer first, then let the 3D sell. The rules I used for the client&rsquo;s site:</p>
<ol>
<li><strong>Text first, 3D beside it.</strong> Each product page opens with a two-line answer, specs at a glance and the scope, with the film beside it on a laptop and after the facts on a phone.</li>
<li><strong>A product finder.</strong> Search all 40 products from one box.</li>
<li><strong>A quote button on every product,</strong> which carries the product name into the enquiry.</li>
<li><strong>Client letters tied to products.</strong> Each reference letter shows on the product pages it talks about, not on a testimonial wall.</li>
<li><strong>One URL per product, line and service,</strong> with a sitemap, unique titles and real HTML text that search engines can read.</li>
<li><strong>Bilingual Arabic and English.</strong> Arabic pages live under /ar/ with <a href="https://developers.google.com/search/docs/specialty/international/localized-versions">hreflang</a> pointing each page at its twin. The Arabic is formal Modern Standard Arabic, the register the sector writes in, with industry terms checked one by one.</li>
</ol>
<h2>Where do industrial companies use 3D, and what do you get?</h2>
<p><strong>Where it earns its keep:</strong> tenders and bid packs, trade shows on a screen or tablet, distributor and sales rep enablement, operator training, maintenance and shutdown planning, and LinkedIn.</p>
<p><strong>What you receive:</strong> a master film rendered at the size you need, 4K included; LinkedIn cuts in 9:16 and 4:5; web-embeddable 3D; GLB and USDZ files for AR; interactive product pages; English and Arabic versions.</p>
<p><strong>What I need from you:</strong> GA drawings, STEP or IGES CAD, BIM models (Revit, IFC, Navisworks), datasheets and photos of the real unit. For standard equipment, no CAD at all.</p>
<h2>Can the same 3D make product demo videos for LinkedIn?</h2>
<p>Yes, and they cost little once the model exists. From the client&rsquo;s renders I cut 16 social clips of 21 seconds, with callouts that ride the parts and one instrument per product, such as a torque trace, an eddy current scope or a pressure dial.</p>
<h2>How do you make industrial 3D load fast on a phone?</h2>
<p>A scroll film is hundreds of pictures, so the trick is deciding which ones to send:</p>
<ul>
<li><strong>AVIF frames.</strong> The phone film is 7.6 MB of AVIF at 720 by 1280, against 13.9 MB for the desktop set at 1920 by 1080.</li>
<li><strong>A skeleton first.</strong> The opening sends five landing frames and every eighth frame, then only frames near where you are. On data saver it sends every other frame.</li>
<li><strong>Load on approach.</strong> three.js and the AR viewer load only when their section comes within one and a half screens.</li>
</ul>
<p>The phone&rsquo;s first screen fell from 9.5 MB to 2.4 MB. Frames decode ahead of the playhead, and the live test showed zero janky frames on phone and desktop at four times CPU throttle. More on budgets in <a href="https://tawfik.tv/notes/unity-webgl-mobile">Unity WebGL on mobile</a> and <a href="https://tawfik.tv/notes/gaussian-splatting-website">Gaussian splatting on a website</a>.</p>
<h2>What does 3D product animation cost?</h2>
<p>Published market figures, not my prices:</p>
<ul>
<li><strong>Animation.</strong> $5,000 to $50,000+ per finished minute, with about $10,000 as a mid-tier baseline. A 30-second product animation runs $5,000 to $15,000 basic, and $20,000 to $50,000+ for a technical version with exploded views (<a href="https://framesixty.com/how-much-does-3d-animation-cost/">Framesixty</a>, 10 September 2026). 4K rendering adds 20 to 40% and rush delivery 25 to 50% (<a href="https://vidico.com/news/how-much-does-animation-cost/">Vidico</a>, 18 September 2026).</li>
<li><strong>Rendering.</strong> $50 to $150 per image for basic items, $150 to $500 mid-range, $1,200 to $3,000+ for complex products (<a href="https://framesixty.com/how-much-does-3d-rendering-cost/">Framesixty</a>, 29 July 2026).</li>
<li><strong>Configurators.</strong> Custom builds from $4,000 to $10,000 for one product, $10,000 to $30,000 with pricing logic, $30,000 to $150,000+ with ERP integration (<a href="https://framesixty.com/3d-configurator/">Framesixty</a>, 1 September 2026).</li>
<li><strong>The website.</strong> Web projects on Clutch typically cost under $10,000; the average agency project is $66,499.09 (<a href="https://clutch.co/web-developers/pricing">Clutch</a>, updated 21 September 2026).</li>
</ul>
<p>The model is the biggest line. Reuse it everywhere and every later piece gets cheaper. I price each project after a first call.</p>
<h2>How long does it take?</h2>
<p>Framesixty puts mid-tier product animation at 4 to 8 weeks and custom three.js configurators at 2 to 4 months. SEVEN Al Hamra took me just under 12 weeks from first file to sign-off, by hand. With AI in my workflow now, the client&rsquo;s seven families went from first model to live page in days.</p>
<h2>Questions people ask</h2>
<h3>How much does 3D product animation cost?</h3>
<p>Published 2026 guides put it at $5,000 to $50,000+ per finished minute, with 30-second product films from $5,000. A technical film with exploded views sits higher.</p>
<h3>Do I need CAD files for 3D animation?</h3>
<p>No. CAD, BIM or GA drawings save modelling time and make the model exact, but standard equipment can be built from datasheets and photos.</p>
<h3>Can buyers view a 3D model in AR without an app?</h3>
<p>Yes. A GLB file with model-viewer opens AR through the phone&rsquo;s own viewer on Android and iPhone, from a link.</p>
<h3>Does 3D on a product page slow the site down?</h3>
<p>Only if it loads up front. Put the text first, show a still, and load frames or the model as the visitor reaches them.</p>
<h3>Can you build a bilingual Arabic and English website?</h3>
<p>Yes. Separate /ar/ pages with hreflang, right-to-left layout and formal Arabic, so each language ranks on its own.</p>
<h3>What is the difference between 3D rendering and 3D animation?</h3>
<p>Rendering makes still images, animation makes moving film. Both come from the same model.</p>
<p>If you sell equipment and want films, interactive 3D or a site that wins enquiries, see <a href="https://tawfik.tv/hire/industrial-3d-and-web">industrial 3D and web</a> or write to me at m@tawfik.tv.</p>]]></content:encoded></item><item><title>How much does a 3D virtual tour cost? 360 photo, scanned and real-time 3D compared</title><link>https://tawfik.tv/notes/3d-virtual-tour-cost</link><guid>https://tawfik.tv/notes/3d-virtual-tour-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A 360 photo tour costs a $550 camera and free software, a scanned 3D tour about $319 a home, and a walkable real-time 3D tour is quoted per project.</description>
<content:encoded><![CDATA[<p>A 3D virtual tour costs anywhere from a $549.99 camera plus free software, for a 360 photo tour you shoot yourself, to $319 for a scanned Matterport-style tour of a home, done for you. A real-time 3D walkthrough, the kind people can walk through before the building exists, is a custom build quoted per project.</p>
<p>Buyers want tours more than agents supply them. In the National Association of Realtors&rsquo; <a href="https://www.nar.realtor/sites/default/files/2025-04/2025-home-buyers-and-sellers-generational-trends-04-01-2025.pdf">2025 Home Buyers and Sellers Generational Trends report</a>, 41% of buyers who searched online rated virtual tours &ldquo;very useful&rdquo;. Only 16% of sellers who used an agent said the agent marketed their home with one.</p>
<p>I&rsquo;m Mo Tawfik Khalifa. I build real-time 3D worlds: my Hermès virtual store, the TAG Heuer showroom I built at Napster, Virtual Expo Dubai with my team of 12, and <a href="https://tawfik.tv/projects/seven-al-hamra">SEVEN Al Hamra</a>, a building you could walk through before it was built. Here is what each kind of tour costs, takes and is good for. Every price comes from the maker&rsquo;s own page, checked in October 2026. None of them are my prices.</p>
<h2>What is the difference between a 360 virtual tour and a 3D tour?</h2>
<p>There are three kinds, and the names get mixed up.</p>
<ol>
<li><strong>360 photo tour.</strong> A 360 camera takes one spherical photo per room. Software links the photos, and visitors jump from spot to spot and turn on the spot.</li>
<li><strong>Scanned 3D tour.</strong> A scanning camera, or a phone, captures the rooms. Matterport is the name most people know. Visitors step between scan points, pull back to a dollhouse view, read a floor plan and measure rooms.</li>
<li><strong>Real-time 3D.</strong> The place is drawn live by a game engine, so visitors walk anywhere, like a video game. It can be built from construction drawings, as I did for SEVEN Al Hamra, or scanned from a real place as a Gaussian splat.</li>
</ol>
<p>So &ldquo;360 virtual tour vs 3D&rdquo; comes down to how people move: a 360 tour jumps, a scanned tour steps, real-time 3D walks.</p>
<h2>How much does a virtual tour cost?</h2>
<p><strong>360 photo tour.</strong> You buy the camera once and the rest can be free.</p>
<ul>
<li><strong>Camera:</strong> the <a href="https://store.insta360.com/product/x5">Insta360 X5</a> lists at $549.99 and the <a href="https://us.ricoh-imaging.com/product/theta-x/">Ricoh Theta X</a> at $599.95.</li>
<li><strong>Software:</strong> <a href="https://www.marzipano.net/">Marzipano</a> is free and open source, and its tool exports a web app you can put up as it is. <a href="https://www.3dvista.com/en/store/">3DVista Virtual Tour Pro</a> is 499 € once, with hosting from 99 € a year.</li>
</ul>
<p><strong>Scanned 3D tour.</strong> You pay per home, or you pay a subscription and scan it yourself.</p>
<ul>
<li><strong>Done for you:</strong> <a href="https://homejab.com/pricing/">HomeJab</a> lists a Matterport-powered 3D tour at $319 for homes up to 4,000 sq ft and $459 at 6,000 to 8,000 sq ft, in most of the US. Matterport&rsquo;s own <a href="https://buy.matterport.com/capture-services-order">capture service</a> delivers in as fast as 24 to 48 hours.</li>
<li><strong>Yourself:</strong> Matterport&rsquo;s <a href="https://matterport.com/plans/free">free plan</a> keeps one tour live and works with a phone or a 360 camera. The <a href="https://matterport.com/plans">Professional plan</a> is $108 a month for 10 tours, or $90 a month paid yearly. The <a href="https://matterport.com/pro3">Pro3 camera</a> starts at $3,995.</li>
</ul>
<p><strong>Real-time 3D from drawings.</strong> I found no published price list worth quoting, because every building is a different job. The cost is the build. SEVEN Al Hamra took me just under 12 weeks by hand, from first access to the construction models to sign-off. For market ranges on 3D web builds, see <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">what a 3D website costs</a>.</p>
<p><strong>Gaussian splat.</strong> <a href="https://scaniverse.com/">Scaniverse</a> scans on iOS and Android and makes the splat on the phone. <a href="https://github.com/sparkjsdev/spark">Spark</a> shows it in a browser and is open source under the MIT licence. You pay in time and a web host.</p>
<p>Switch the flat below between built and off-plan, then flip through the three tours. The quote sheet uses the numbers above.</p>
<p><a href="https://tawfik.tv/notes/3d-virtual-tour-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>Which virtual tour is best for real estate?</h2>
<p>It depends on one question: does the place exist yet?</p>
<ul>
<li><strong>Selling or letting a finished flat.</strong> A scanned tour. Buyers get the layout, the floor plan and the measurements, and $319 is a small line on a sale. If the budget is one camera, a 360 photo tour shows every room.</li>
<li><strong>Pre-selling a building that is not built.</strong> Real-time 3D from the drawings, because there is nothing to photograph or scan. SEVEN Al Hamra was still a construction site. I turned its Revit, IFC and Navisworks models into a building people explored floor by floor, by day and by night, and SEVEN signed it off as the first of six destinations for its 3D portal. <a href="https://tawfik.tv/worlds/rvt">Walk through it</a>.</li>
<li><strong>A branded experience.</strong> Real-time 3D again, because you control every surface, light and product, and every room can end in an action. That is how I build virtual stores, and why the <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">Expo 2020 twin</a> is still open after the Expo closed.</li>
<li><strong>One real room with atmosphere.</strong> A Gaussian splat keeps the real light and texture of a place in a small file. My <a href="https://tawfik.tv/window">window demo</a> runs Spark&rsquo;s own sample scene, and I explain the method in <a href="https://tawfik.tv/notes/gaussian-splatting-website">Gaussian splatting on a website</a>.</li>
</ul>
<h2>How do you make a 3D virtual tour?</h2>
<ol>
<li><strong>Decide what people must do inside.</strong> See every room, measure rooms, or walk a building that does not exist yet. That picks the kind.</li>
<li><strong>Check what you start from.</strong> A finished place can be photographed or scanned. An unbuilt one starts from the construction models: Revit, IFC or Navisworks.</li>
<li><strong>Capture.</strong> One 360 photo per room, or a scan at every step through the space, or the 3D views exported from the building model.</li>
<li><strong>Build.</strong> Link the photos in the tour editor, let Matterport process the scans, or strip, optimise and light the model in a game engine. For SEVEN Al Hamra I left out 758 hidden objects, like cable trays and ducts, that no visitor would ever see.</li>
<li><strong>Host it.</strong> A subscription for scanned tours, or plain files on a web host for the rest.</li>
<li><strong>Test on the weakest phone your buyers use</strong>, on mobile data, before anyone sees it.</li>
<li><strong>Put it where buyers look:</strong> the listing, the portal and the agent&rsquo;s own site.</li>
</ol>
<h2>What does a virtual tour cost to keep online?</h2>
<ul>
<li><strong>Scanned tours</strong> live on the subscription. Stop paying and archive one, and Matterport says the tour <a href="https://support.matterport.com/s/article/What-is-an-Active-or-Archived-Space?language=en_US">can&rsquo;t be viewed until you reactivate it</a>.</li>
<li><strong>360 tours, splats and WebGL builds</strong> are plain files. Any web host serves them, with one download per visitor.</li>
<li><strong>Streamed real-time 3D</strong> renders on a cloud GPU for each viewer, at <a href="https://instances.vantage.sh/aws/ec2/g4dn.xlarge">about $0.53 an hour each</a> on AWS. That is why I build for the browser unless the visuals are worth the bill.</li>
</ul>
<h2>Will a virtual tour work on a phone?</h2>
<p>The more freedom a tour gives, the more it weighs.</p>
<ul>
<li><strong>360 photo tour:</strong> the Marzipano viewer is 55 KB gzipped, then the photos. The lightest of the three.</li>
<li><strong>Gaussian splat:</strong> the scene in my window demo is 4.4 MB, about 5.5 MB with the renderer. Spark says it renders fast even on low-powered mobile devices.</li>
<li><strong>Real-time 3D:</strong> the SEVEN Al Hamra web build is a 74 MB download, drawing about 700,000 triangles at 60 fps on a laptop graphics chip. On phones it plays a short video first and loads the 3D when you ask.</li>
</ul>
<h2>Questions people ask</h2>
<h3>How much does a virtual tour cost?</h3>
<p>From a $549.99 camera and free software for a 360 photo tour, to $319 for a scanned tour of a home done for you, to a quoted custom build for real-time 3D. Scanned tours also need a subscription to stay online.</p>
<h3>Is a 360 tour the same as a 3D tour?</h3>
<p>No. A 360 tour is linked photos you jump between. A scanned 3D tour adds depth, so you get a dollhouse, a floor plan and measurements. Real-time 3D lets you walk anywhere.</p>
<h3>Do I need a Matterport camera?</h3>
<p>No. Matterport&rsquo;s free plan works with a phone or a 360 camera. The Pro3 camera, from $3,995, is for people who scan for a living.</p>
<h3>Can you make a virtual tour of a building that is not built yet?</h3>
<p>Yes, as real-time 3D built from the construction models. Photos and scans need finished rooms. SEVEN Al Hamra is one I built while the venue was still a site.</p>
<h3>What is the best virtual tour software?</h3>
<p>The best one depends on the kind. For 360 tours, Marzipano is free and 3DVista is a one-off licence. For scanned tours, Matterport. For real-time 3D, a game engine such as Unity or Unreal. For splats, a scan app such as Scaniverse and a renderer such as Spark.</p>
<p>If you need a tour or a walkable building made, write to <a href="mailto:m@tawfik.tv">m@tawfik.tv</a>, or see <a href="https://tawfik.tv/hire/3d-web-experiences">how I take on 3D web projects</a>.</p>]]></content:encoded></item><item><title>Vibe coding: what it is, where it breaks, and how to ship it safely</title><link>https://tawfik.tv/notes/vibe-coding</link><guid>https://tawfik.tv/notes/vibe-coding</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Vibe coding is building software by prompting an AI and accepting its code. It is great for prototypes; here is how to get one safely to production.</description>
<content:encoded><![CDATA[<p>Vibe coding is building software by describing what you want to an AI and accepting the code it writes, without reading it line by line. It is the fastest way yet to get from an idea to a working prototype, and the code still needs an engineer&rsquo;s eyes before real people, real data and real money touch it.</p>
<p>I ship with AI at every step, and I built a live app on my own with AI doing the typing. This is what I have learned about the gap between the vibe and production.</p>
<h2>What is vibe coding?</h2>
<p>Andrej Karpathy coined the term in a <a href="https://x.com/karpathy/status/1886192184808149383">post on 2 February 2025</a>: a new kind of coding where you &ldquo;forget that the code even exists&rdquo;. He accepted every change without reading the diffs, pasted error messages straight back to the AI, and said it was fine for throwaway weekend projects. Nine months later, Collins named vibe coding its <a href="https://blog.collinsdictionary.com/language-lovers/collins-word-of-the-year-2025-ai-meets-authenticity-as-society-shifts/">Word of the Year 2025</a>.</p>
<p>Most professional developers keep their distance. In the <a href="https://survey.stackoverflow.co/2025/ai">Stack Overflow 2025 Developer Survey</a> (July 2025), 72% of respondents said vibe coding is not part of their professional development work and another 5% said so emphatically, while 84% use or plan to use AI tools. The difference is ownership: AI-assisted engineering means someone reads the code, tests it and answers for it. Vibe coding means nobody does.</p>
<h2>What tools do people use for vibe coding?</h2>
<p>Two kinds, and many people use both.</p>
<ul>
<li><strong>App builders in the browser.</strong> Lovable, Bolt, Replit and v0. You describe the app in a chat and get a running app, often with hosting and a database wired in.</li>
<li><strong>AI code editors and coding agents.</strong> Cursor, Claude Code, Codex, Gemini CLI and GitHub Copilot. They work in a real code repository on your machine and can run commands.</li>
</ul>
<p>Underneath, most vibe-coded apps land on the same few services: a hosted database such as Supabase or Firebase, a host such as Vercel or Netlify, and Stripe for payments. That matters, because those services are where the production rules live.</p>
<h2>What is vibe coding good for?</h2>
<ul>
<li><strong>Prototypes</strong> that customers or investors can press and break, in days.</li>
<li><strong>Internal tools</strong> for a handful of people you trust.</li>
<li><strong>One-off apps for an event</strong>, where the stakes and the lifetime are short.</li>
<li><strong>Testing a product idea</strong> before you spend on a team.</li>
</ul>
<p>I built <a href="https://laqtaa.app">Laqtaa</a>, a shared wedding photo app, on my own for a friend&rsquo;s wedding: one shared camera for your event. About 100 guests used it on the day and nothing broke. Before any code I wrote a 780-line brief with a hard deadline. Even so, on the first day, a couple of hours after 6 milestones were built and deployed in 53 minutes, the next commit read &ldquo;resolve all critical runtime bugs&rdquo;. Over 5 weeks it took 188 commits, 93 of them fixes. The full story is in <a href="https://tawfik.tv/notes/one-person-ai-team">can one person with AI do a whole team&rsquo;s work</a>.</p>
<h2>Where do vibe-coded apps break in production?</h2>
<p>In the parts a demo never touches: other people, other people&rsquo;s data and money.</p>
<ul>
<li><strong>Sign-in and roles.</strong> The login works, but the check for who is staff sits in the browser or reads a field users can edit.</li>
<li><strong>Data rules.</strong> The database answers anyone holding the public key. In Supabase that means Row Level Security is off or too loose; my <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a> has the SQL.</li>
<li><strong>Secrets.</strong> A secret key ends up in the JavaScript every visitor downloads, or in git history. The <a href="https://tawfik.tv/notes/vibe-coding-security-checklist">vibe coding security checklist</a> covers secrets and the other 12 checks to run before launch.</li>
<li><strong>Payments.</strong> The app marks an order paid when the customer lands on the &ldquo;thank you&rdquo; page, or trusts any message sent to its payment webhook. Stripe warns that without signature verification &ldquo;an attacker could send fake webhook events&rdquo; to trigger actions like fulfilling orders, and that endpoints can receive the same event more than once (<a href="https://docs.stripe.com/webhooks#verify-events">Stripe webhooks</a>).</li>
<li><strong>Scale.</strong> Ten testers work fine. Two hundred people at your busiest moment run out of database connections, and two of them book the same table. Supabase tells you to use its transaction mode pooler for serverless functions, which &ldquo;open many short-lived connections&rdquo; (<a href="https://supabase.com/docs/guides/database/connecting-to-postgres#pooler-transaction-mode">Supabase docs</a>).</li>
<li><strong>Nobody understands the code.</strong> Karpathy wrote that his code grew beyond his usual comprehension. With no tests and no notes, each new prompt fixes one thing and breaks another, and nobody can say why.</li>
<li><strong>The agent itself.</strong> The AI that wrote the app has a shell and your keys. <a href="https://tawfik.tv/notes/ai-agent-deleted-database">It can delete your database</a>.</li>
</ul>
<p>The payment fix is short once you know it. Verify the signature on the raw body, and skip events you have already handled:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">// app/api/stripe-webhook/route.ts (Next.js)
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export async function POST(req: Request) {
  const body = await req.text();   // the raw body, not parsed JSON
  let event: Stripe.Event;
  try {
    event = stripe.webhooks.constructEvent(
      body, req.headers.get('stripe-signature')!, process.env.STRIPE_WEBHOOK_SECRET!);
  } catch {
    return new Response('bad signature', { status: 400 });
  }
  // store event.id; if you have seen it before, return 200 and do nothing
  return new Response('ok');
}</pre>

<p>And the double booking is one line of SQL, so the database refuses the second guest whatever the browser thinks:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">alter table bookings
  add constraint one_booking_per_slot unique (table_id, slot_start);</pre>

<h2>What stands between a prototype and production?</h2>
<p>Gates. Below is a release pipeline for a made-up restaurant booking app, built over a weekend with an AI app builder. Each gate runs a real kind of check and fails the way vibe-coded apps fail. Pick a fix and re-run the gate: some fixes look right and still fail. The last three gates are where an engineer earns their fee.</p>
<p><a href="https://tawfik.tv/notes/vibe-coding">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you take a vibe-coded app to production?</h2>
<p>This is the order I work in when I take a prototype to production as a <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer</a>. I come from coding and design, and I use AI at every step; the steps are what the AI does not do on its own.</p>
<ol>
<li><strong>Write down what the prototype does.</strong> The three or four flows that matter, who uses them and what must never happen. The prototype is now the spec.</li>
<li><strong>Get the code into a repository you own</strong>, with separate development and production databases and keys.</li>
<li><strong>Run the security pass.</strong> The <a href="https://tawfik.tv/notes/vibe-coding-security-checklist">13 checks</a> take an afternoon for a small app.</li>
<li><strong>Rebuild the risky paths properly</strong>: sign-in, payments and anything that writes data, each with tests.</li>
<li><strong>Load test your busiest moment</strong>, then fix what falls over, in the database, not the browser.</li>
<li><strong>Put a guard on the coding agent.</strong> I built <a href="https://gvnr.io">GVNR</a>, a free and source-available guard that runs on your own machine and works with Claude Code, Cursor, Codex, Gemini CLI and any MCP client. Before each action it decides allow, deny or ask a person, and it keeps a hash-chained record of every decision.</li>
<li><strong>Ship with a way back</strong>: a backup you have restored once, the previous release ready to roll back to, and alerts when errors spike.</li>
<li><strong>Name an owner</strong>, with a one-page note on how the app runs and deploys.</li>
</ol>
<h2>When should you bring in an engineer?</h2>
<p>Before the app does any of these:</p>
<ul>
<li><strong>Takes money</strong>, including deposits and subscriptions.</li>
<li><strong>Stores other people&rsquo;s personal data</strong>, or anything regulated such as health or financial records.</li>
<li><strong>Opens to people you do not know</strong>, at a launch, a sale or a busy hour.</li>
<li><strong>Breaks somewhere new every time you fix something.</strong></li>
</ul>
<p>You do not need a team for this. You need one person who reads the code, hardens the parts that carry risk and hands it back with tests and notes. That is the work I do as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO and forward deployed engineer</a>: prototypes in days, then the hardening that gets them to production.</p>
<h2>Questions people ask</h2>
<h3>Who coined the term vibe coding?</h3>
<p><a href="https://karpathy.ai/">Andrej Karpathy</a>, a founding member of OpenAI and former Director of AI at Tesla, in a post on X on 2 February 2025. Collins Dictionary named it Word of the Year 2025.</p>
<h3>Is vibe coding bad?</h3>
<p>No. It is the fastest way to a working prototype. It becomes a problem when a prototype goes live with real users, data or payments and nobody has read the code.</p>
<h3>Can a vibe-coded app go to production?</h3>
<p>Yes, after it passes the gates: secrets, sign-in and data rules, payments, load and handover. Keep what works, rebuild only what fails.</p>
<h3>Do I need to know how to code to vibe code?</h3>
<p>Not to build a prototype. To ship it safely, someone on the project needs to read code, or you need to bring that person in before launch.</p>
<h3>What is the difference between vibe coding and AI-assisted coding?</h3>
<p>Who owns the code. In AI-assisted coding a person reads, tests and answers for every change. In vibe coding the AI&rsquo;s output goes in unread.</p>
<p>If you have a vibe-coded app that needs to reach production, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>How to tokenize real estate: the company, the token and the rent, step by step</title><link>https://tawfik.tv/notes/tokenize-real-estate</link><guid>https://tawfik.tv/notes/tokenize-real-estate</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Put the property in its own company, issue that company&#x27;s shares as tokens that check every buyer, and pay the rent out to holders each month.</description>
<content:encoded><![CDATA[<p>To tokenize real estate, you put the property inside its own company, a special purpose vehicle (SPV), and issue that company&rsquo;s shares as tokens on a blockchain. The token carries the transfer rules, the SPV holds the title, and the rent flows out to token holders every month.</p>
<p>The token is a new way to keep the share register. It does not replace the land registry, the valuation, the tenancy or securities law.</p>
<p>The market is small today and forecast to grow fast. In April 2025 the <a href="https://www.deloitte.com/us/en/insights/industry/financial-services/financial-services-industry-predictions/2025/tokenized-real-estate.html">Deloitte Center for Financial Services predicted</a> that US$4 trillion of real estate will be tokenized by 2035, up from less than US$0.3 trillion in 2024. Dubai&rsquo;s land department projects tokenized property at <a href="https://dubailand.gov.ae/en/news-media/dubai-land-department-launches-pilot-phase-of-the-real-estate-tokenisation-project">AED 60 billion by 2033</a>, 7% of the emirate&rsquo;s real estate transactions.</p>
<h2>What is real estate tokenization, explained simply?</h2>
<p>A token is an entry on a shared ledger that says who owns what. In real estate it usually stands for a share in the SPV that owns a building, or a slice of a loan secured on it. Selling the token sells the share. The house itself never moves onto a blockchain.</p>
<p>Regulators read it the same way. On 28 January 2026, three divisions of the US SEC published a <a href="https://www.sec.gov/newsroom/speeches-statements/corp-fin-statement-tokenized-securities-012826-statement-tokenized-securities">statement on tokenized securities</a>: the federal securities laws apply whatever format a security is issued in. The UK FCA&rsquo;s <a href="https://www.fca.org.uk/publications/policy-statements/ps26-7-progressing-fund-tokenisation">policy statement PS26/7</a>, published on 30 April 2026, defines tokenisation as representing an asset, or ownership of one, using distributed ledger technology.</p>
<p>I have worked on this from the inside. As a forward deployed engineer at Instruxi, I worked with a client who turns rented homes into tokens that back a loan. I built a prototype that reads their live test network and follows each step: house, token, vault, loan, rent. It has four break-it gates (title check, valuation, rent feed and holder check) and the client&rsquo;s own yield formula as sliders. The full story is in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">four AI and fintech builds</a>. Everything below comes from that work and from the primary sources linked.</p>
<h2>How do you tokenize a property, step by step?</h2>
<ol>
<li><strong>Set up the SPV.</strong> One company per property, owning that property and nothing else. In the UK, registering a company online with Companies House costs <a href="https://www.gov.uk/government/publications/companies-house-fees/companies-house-fees">£100</a>, plus a £50 online confirmation statement each year.</li>
<li><strong>Put the title in the SPV&rsquo;s name.</strong> The land register names the SPV as owner. Token holders own the company, so a token sale never touches the register, and only the SPV can sell the house.</li>
<li><strong>Get an independent valuation.</strong> Tokens times price should land near it. Price far above it and buyers overpay from day one. Keep it fresh, because a stale valuation is the number lenders and buyers lean on.</li>
<li><strong>Pick the legal route for the offer.</strong> In the US, tokens sold privately under Regulation D are restricted securities, and <a href="https://www.sec.gov/reports/rule-144-selling-restricted-control-securities">Rule 144</a> holds them for six months if the issuer files reports with the SEC, one year if it does not. In Dubai, the land department&rsquo;s pilot sells through a licensed platform, with VARA, the virtual assets regulator, as a partner.</li>
<li><strong>Issue a token with transfer rules built in.</strong> It checks every buyer before it moves. More on standards below.</li>
<li><strong>Decide who holds the keys.</strong> The token contract has admin keys that can freeze a wallet or move tokens after a lost key or a court order. A regulated custodian or transfer agent should hold them, under written rules.</li>
<li><strong>Wire up the rent.</strong> A letting agent collects it off chain, costs come off the top, and the rest is paid per token to each holder&rsquo;s wallet.</li>
<li><strong>Plan the exit.</strong> Holders need somewhere to sell, and buyers who pass the same checks. Without a venue and a lock-up schedule, &ldquo;liquid&rdquo; is a promise.</li>
</ol>
<h2>Try it: a deal room for one London house</h2>
<p>Set the number of tokens and the price, collect rent, make the tenant move out, then try to sell tokens to a buyer who should be refused. Every number is a sample.</p>
<p><a href="https://tawfik.tv/notes/tokenize-real-estate">Open the interactive diagram on tawfik.tv</a></p>

<h2>Which token standard is best for real estate?</h2>
<p>Use a permissioned security token, not a plain ERC-20. A plain token moves to any wallet, so the SPV loses track of who its shareholders are.</p>
<p><a href="https://eips.ethereum.org/EIPS/eip-3643">ERC-3643</a> is a final Ethereum standard for permissioned tokens. Before any transfer it checks the buyer against an identity registry, then runs compliance rules such as caps per country or per investor. It also supports frozen wallets, pausing, and recovery when an investor loses their keys. <a href="https://github.com/ethereum/EIPs/issues/1411">ERC-1400</a> solves the same problem, adding transfer checks that return reason codes and documents attached to the token, but it never became a final standard.</p>
<p>The check order, as ERC-3643 lays it out:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">before transfer(from, to, amount):
  token paused?                               refuse
  from or to wallet frozen?                   refuse
  identityRegistry.isVerified(to) is false?   refuse   # buyer has no checked identity
  compliance.canTransfer(from, to, amount)?   refuse   # country, holder caps, lock-ups
  move the tokens, then tell compliance it happened</pre>

<p>The identity check is the same idea as proving your age once and showing a signed yes afterwards, which I cover in <a href="https://tawfik.tv/notes/prove-age-without-id">prove you&rsquo;re over 18 without showing your ID</a>.</p>
<h2>How do token holders get paid rent?</h2>
<p>The tenant pays the letting agent in pounds, dollars or dirhams. The agent takes its fee, the SPV tops up its repairs reserve and pays insurance and accounts, and what is left is divided by the number of tokens. That figure per token goes to each wallet, usually in a stablecoin or straight to a bank account. If the payout runs on stablecoins, <a href="https://tawfik.tv/notes/bank-stablecoin">how a bank issues its own stablecoin</a> covers the money side.</p>
<p>The rent feed is the weak point. The blockchain only knows what the agent reports. In the prototype, the rent feed is one of the four gates: switch it off and you see what fails without it.</p>
<h2>Where is real estate tokenization actually live?</h2>
<p>Dubai is the clearest government-run example. The Dubai Land Department <a href="https://dubailand.gov.ae/en/news-media/dubai-land-department-launches-pilot-phase-of-the-real-estate-tokenisation-project">launched its tokenization pilot</a> on 19 March 2025 with VARA and the Dubai Future Foundation, the first registration body in the Middle East to tokenize title deeds. Its first licensed platform <a href="https://dubailand.gov.ae/en/news-media/dld-launches-the-mena-s-first-tokenized-real-estate-project-through-the-prypco-mint-platform">opened on 25 May 2025</a>: from AED 2,000, ready properties only, UAE ID holders only, and dirhams only during the pilot.</p>
<p>In the UK, the <a href="https://lawcom.gov.uk/news/the-property-digital-assets-etc-act-2025-has-received-royal-assent/">Property (Digital Assets etc) Act 2025</a> received Royal Assent on 2 December 2025. It confirms that crypto-tokens can be property in law, which matters when a token holder goes bust or a court needs to trace a token.</p>
<h2>What breaks?</h2>
<p>These are the failures I built gates for, plus the ones every deal room should test:</p>
<ul>
<li><strong>Title mismatch.</strong> The token says one house, the register says another owner, or a charge nobody disclosed.</li>
<li><strong>Stale valuation.</strong> The price per token still reflects last year&rsquo;s number.</li>
<li><strong>Rent feed down or wrong.</strong> Payouts stop, or worse, pay on rent that never arrived.</li>
<li><strong>Holder check off.</strong> A token reaches a wallet nobody has verified, and the SPV has a shareholder it cannot name.</li>
<li><strong>Lost or misused admin keys.</strong> Whoever can freeze and move tokens is the real control point.</li>
<li><strong>No buyers.</strong> A token you can send but cannot sell is not liquid.</li>
</ul>
<h2>What does it cost to tokenize a property?</h2>
<p>The fixed government fees are small: £100 online to register the UK SPV and £50 a year for its confirmation statement, per <a href="https://www.gov.uk/government/publications/companies-house-fees/companies-house-fees">Companies House</a>. The real money goes on lawyers for the offering, the valuation, a transfer agent or custodian, a smart contract audit and the platform&rsquo;s fees. I have not found published prices for those that I would trust, so get written quotes for each before you commit.</p>
<h2>Questions people ask</h2>
<h3>Is tokenized real estate legal?</h3>
<p>Yes, where it follows the securities and property laws that already apply. The SEC says a tokenized security is still a security, and Dubai runs a licensed pilot through its land department.</p>
<h3>Do token holders own the house?</h3>
<p>No. They own shares in the SPV, and the SPV owns the house. The land register names the SPV.</p>
<h3>Can I tokenize my own house?</h3>
<p>You can put it in a company and issue the shares as tokens. Selling those tokens to other people is a securities offering, so you need a lawyer and the right exemption or licence where your buyers live.</p>
<h3>What does an RWA tokenization platform do?</h3>
<p>An RWA (real world asset) tokenization platform sets up the SPV, checks investors&rsquo; identity, issues the token with its transfer rules, keeps the register in step with the company&rsquo;s records, and pays out income. Ask who holds the admin keys before you sign.</p>
<h3>Can I sell real estate tokens any time?</h3>
<p>Only to buyers who pass the token&rsquo;s checks, and only after any lock-up. US private placements fall under Rule 144&rsquo;s six-month or one-year holding period.</p>
<h3>Which blockchain is best for real estate tokens?</h3>
<p>The one your investors, custodian and transfer agent already support. The token standard and its rules matter more than the chain.</p>
<p>If you need a tokenization product scoped, prototyped or explained to investors, write to m@tawfik.tv, or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>What is a digital twin? The definition, how it works and real examples</title><link>https://tawfik.tv/notes/what-is-a-digital-twin</link><guid>https://tawfik.tv/notes/what-is-a-digital-twin</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A digital twin is a virtual copy of a real thing kept in step with it by live data, so you can watch, test and plan on the copy before touching the real one.</description>
<content:encoded><![CDATA[<p>A digital twin is a virtual copy of a real thing, such as a pump, a shop, a building or a whole city, that live data keeps in step with the real one. You use the copy to see what is happening now, test a change and plan, before you touch the real thing.</p>
<p>The idea has been in mainstream use for years. In a <a href="https://www.gartner.com/en/newsroom/press-releases/2019-02-20-gartner-survey-reveals-digital-twins-are-entering-mai">February 2019 survey</a> of 599 organisations implementing the Internet of Things, Gartner found 13 percent already used digital twins and another 62 percent were setting them up or planned to within a year.</p>
<p>I build the 3D side of them. For the FIFA World Cup in Qatar, Expo 2020 and SEVEN, I turned engineering models into live Unreal and Unity environments. What one costs is in <a href="https://tawfik.tv/notes/digital-twin-cost">how much a digital twin costs</a>. This page covers what one is.</p>
<h2>What is a digital twin?</h2>
<p>The <a href="https://www.digitaltwinconsortium.org/initiatives/the-definition-of-a-digital-twin/">Digital Twin Consortium</a> defines it as &ldquo;an integrated data-driven virtual representation of real-world entities and processes, with synchronized interaction at a specified frequency and fidelity.&rdquo;</p>
<p>In plain words, a twin has three parts:</p>
<ol>
<li><strong>The copy.</strong> A model of the thing: its shape, its parts and how they connect.</li>
<li><strong>The real thing.</strong> A machine, a room, a crowd, a road network.</li>
<li><strong>The link.</strong> Data that keeps the copy in step with the real thing. &ldquo;Frequency&rdquo; is how often it updates: every second for a queue, once a day for a lease plan. &ldquo;Fidelity&rdquo; is how much detail it carries.</li>
</ol>
<p>Take the link away and you have a model. That is the whole test.</p>
<p>The Consortium also names a stage before that: a <strong>digital twin prototype</strong>, which models and simulates the future before it is linked to the real thing. A building modelled before it is built is one.</p>
<h2>What is the difference between a digital twin, a 3D model and a simulation?</h2>
<ul>
<li><strong>A 3D model</strong> copies the shape. It is frozen: when the real pump stops, the model does not know.</li>
<li><strong>A simulation</strong> is maths that predicts what would happen, usually from assumptions typed in by hand.</li>
<li><strong>A digital twin</strong> is a model plus the live link. When it also runs a simulation on the live readings, it becomes a twin that predicts.</li>
</ul>
<p>Pick a pump, a shop or a stadium gate below and step through the four levels. Only the last two are twins.</p>
<p><a href="https://tawfik.tv/notes/what-is-a-digital-twin">Open the interactive diagram on tawfik.tv</a></p>

<h2>How does digital twin technology work?</h2>
<p>Every twin I have seen is built from the same four layers. You add them in this order, and many projects stop after the first one.</p>
<ol>
<li><strong>Model.</strong> The shape, from CAD drawings, BIM files or a laser scan. For people to walk through it, it goes into a real-time engine: Unity, Unreal or WebGL in the browser. On SEVEN Al Hamra I started from the <a href="https://tawfik.tv/projects/seven-al-hamra">Revit, IFC and Navisworks construction models</a>, the same files the builders used.</li>
<li><strong>Sensors and data.</strong> Readings from the real thing: flow and vibration on a pump, door counts and till data in a shop, ticket scans at a gate, energy meters in a building. Most of it already exists somewhere; the work is getting it out.</li>
<li><strong>Platform.</strong> Software that holds the model and the data and keeps them in step. Azure Digital Twins, AWS IoT TwinMaker and Autodesk Tandem are the common ones; I compare their prices in <a href="https://tawfik.tv/notes/digital-twin-cost">digital twin cost</a>.</li>
<li><strong>Simulation.</strong> The maths that turns readings into a forecast. The interactive uses three real ones: the pump affinity laws, where power follows the cube of speed, so <a href="https://www.energy.gov/sites/prod/files/2014/04/f15/motor_tip_sheet11.pdf">slowing a pump by 20% cuts its power by about half</a> (US Department of Energy); the Erlang C queueing formula for tills; and the <a href="https://sgsa.org.uk/physical-factors/circulation/ingress/">Green Guide&rsquo;s 660 people an hour per turnstile</a> for stadium gates.</li>
</ol>
<p>Under the hood, the platform stores each real thing as a typed record. This is a pump in DTDL, the <a href="https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v3/DTDL.v3.md">modelling language Azure Digital Twins uses</a>: telemetry is what the sensors send, a property is a setting you can change, a relationship links it to other twins.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">{
  "@context": "dtmi:dtdl:context;3",
  "@id": "dtmi:com:example:Pump;1",
  "@type": "Interface",
  "displayName": "Pump",
  "contents": [
    { "@type": "Telemetry", "name": "flow", "schema": "double" },
    { "@type": "Telemetry", "name": "vibration", "schema": "double" },
    { "@type": "Property", "name": "speedPercent", "schema": "double", "writable": true },
    { "@type": "Relationship", "name": "feeds", "target": "dtmi:com:example:Tank;1" }
  ]
}</pre>

<h2>What are some digital twin examples?</h2>
<h3>Buildings</h3>
<p>I turned SEVEN&rsquo;s construction models for <a href="https://tawfik.tv/projects/seven-al-hamra">Al Hamra in Riyadh</a> into a building you can walk through in a browser, before it was built. It took just under 12 weeks from first access to sign-off, by hand. By the Consortium&rsquo;s definition it is a digital twin prototype: the copy came first, so people could explore floors and units of a venue that did not exist yet.</p>
<h3>Factories</h3>
<p>BMW Group says its Debrecen plant in Hungary is its <a href="https://www.press.bmwgroup.com/global/article/detail/T0411467EN/bmw-group-at-nvidia-gtc:-virtual-production-under-way-in-future-plant-debrecen">first plant planned and validated completely virtually</a> (March 2023), with vehicle production running in the twin more than two years before series production. Gartner&rsquo;s survey gives the smaller version: in a power plant, each <a href="https://www.gartner.com/en/newsroom/press-releases/2019-02-20-gartner-survey-reveals-digital-twins-are-entering-mai">valve, pump and generator can have its own twin</a>, plus one twin that combines them.</p>
<h3>Cities</h3>
<p>Helsinki calls its <a href="https://hel.fi/en/decision-making/information-on-helsinki/maps-and-geospatial-data/helsinki-3d">3D city models the city&rsquo;s digital twin</a>. Its Energy and Climate Atlas shows energy and renovation information building by building, and its Kalasatama project ran on the rule &ldquo;design, test and build digitally first.&rdquo;</p>
<h3>Events</h3>
<p>OnePlan says its browser-based <a href="https://www.oneplan.io/case-studies/paris-2024-olympics-digital-twins/">VenueTwin was used across 49 venues by 46 functional areas</a> to plan the Paris 2024 Games. Temporary venues such as the Eiffel Tower Arena existed only in the twin before they were built.</p>
<p>At Expo 2020 Dubai my team of 12 worked on <a href="https://virtualexpodubai.com">Virtual Expo Dubai</a>, the whole site in real-time 3D. The Expo closed. The twin is still live. How an event twin earns its keep before, during and after the event is in <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores, live shows and 3D worlds</a>.</p>
<p>The same engines also run virtual places where people meet. With Napster, DMCC launched its Crypto Centre metaverse in Dubai: walk into a boardroom where avatars meet, or join the treasure hunt, in a desktop browser. I led a 24-person team at Napster. A world like that becomes a twin only when it is linked to live data from a real place.</p>
<h2>Is a 3D virtual tour a digital twin?</h2>
<p>No. A 360 tour is photos you click between, and a scan-based 3D tour is a model of how a place looked on the day it was scanned. Both sit at level two or below in the interactive: a copy with no live link. The differences and prices are in <a href="https://tawfik.tv/notes/3d-virtual-tour-cost">how much a 3D virtual tour costs</a>.</p>
<h2>How do you start a digital twin?</h2>
<p>Start from a decision, not from the technology.</p>
<ol>
<li><strong>Write down the one decision the twin should help with.</strong> How many lanes to open at 6 pm. Which pump to service first. Whether a lease plan works on floor two.</li>
<li><strong>Pick the lowest level that answers it.</strong> If people only need to see and walk the place, a 3D model is enough and costs far less. SEVEN needed exactly that before opening.</li>
<li><strong>List what already exists.</strong> Drawings, BIM, the building management system, ticketing, till and maintenance data. Every file you have is one nobody models by hand.</li>
<li><strong>Set the frequency and the fidelity.</strong> Every second or once a day; every bolt or just the rooms. This choice drives the cost more than any platform.</li>
<li><strong>Choose where people will open it.</strong> A control room screen, a laptop browser, a phone. The weakest device sets the budget for the model.</li>
<li><strong>Twin one asset end to end first.</strong> One pump, one shop, one gate, from data to screen, then copy the pattern.</li>
</ol>
<h2>Questions people ask</h2>
<h3>What is a digital twin in simple terms?</h3>
<p>A live copy of something real. It looks like the real thing, it updates when the real thing changes, and you can try changes on the copy first.</p>
<h3>What is digital twin software?</h3>
<p>Two kinds of software working together: a platform that holds the data and keeps it in step, such as Azure Digital Twins, AWS IoT TwinMaker or Autodesk Tandem, and an engine that shows it in 3D, such as Unity, Unreal or three.js in the browser.</p>
<h3>Is a BIM model a digital twin?</h3>
<p>Not on its own. BIM is the model layer. It becomes a twin when live data from the finished building is linked to it.</p>
<h3>What are digital twins used for?</h3>
<p>Planning a building, plant or venue before it exists, watching it while it runs, finding faults before they cause a failure, and testing changes such as layouts, staffing or machine settings on the copy first.</p>
<h3>How much does a digital twin cost?</h3>
<p>It depends on the levels you need. I break a building twin down line by line, from the 3D model to sensors, platform and simulation, in <a href="https://tawfik.tv/notes/digital-twin-cost">how much a digital twin costs</a>.</p>
<p>If you have the drawings or the BIM and want a twin people can open from a link, see <a href="https://tawfik.tv/hire/3d-web-experiences">how I take on 3D web projects</a> or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>Supabase security checklist: the settings that leak your data, and how to fix each one</title><link>https://tawfik.tv/notes/supabase-security-checklist</link><guid>https://tawfik.tv/notes/supabase-security-checklist</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Supabase leaks data when RLS is off, a policy says using (true), a secret key ships to the browser or a view skips RLS. 12 fixes with SQL.</description>
<content:encoded><![CDATA[<p>Supabase data leaks through a few settings: Row Level Security switched off, a policy that says <code>using (true)</code>, a secret key shipped to the browser, or a view that skips RLS. Fix those four and the publishable key in your app is safe to expose; the checklist below covers the rest.</p>
<p>It happens at scale. In May 2025, Matt Palmer scanned 1,645 apps from Lovable&rsquo;s public showcase and found 170 whose Supabase tables anyone could read or write, through 303 endpoints, because RLS was missing or wrong (<a href="https://mattpalmer.io/posts/statement-on-CVE-2025-48757/">his statement</a>; filed as <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-48757">CVE-2025-48757</a>, which Lovable disputes). In February 2026, Wiz found Moltbook&rsquo;s Supabase database open with RLS disabled: 1.5 million API tokens, 35,000 email addresses and thousands of private messages, readable and writable with the key sitting in the site&rsquo;s JavaScript (<a href="https://www.wiz.io/blog/exposed-moltbook-database-reveals-millions-of-api-keys">Wiz, 2 February 2026</a>).</p>
<p>I have moved apps onto Supabase and fixed database security on live ones. The same settings come up every time. Here they are in the order I check them, with SQL you can paste.</p>
<h2>Is the Supabase anon key safe to expose?</h2>
<p>Yes, when RLS is on and your policies are right. The anon key, now called the publishable key (<code>sb_publishable_...</code>), is built to sit in your web or mobile app. Supabase lists it as safe to expose in web pages, apps and source code, and says RLS decides what that client can reach (<a href="https://supabase.com/docs/guides/api/api-keys">API keys</a>). When data leaks through it, the cause is a missing or loose policy.</p>
<p>The secret key (<code>sb_secret_...</code>, or the legacy <code>service_role</code> key) is the dangerous one. In Supabase&rsquo;s words, it &ldquo;bypasses every Row Level Security policy you have&rdquo;. It lives on your server and nowhere else. Search your built JavaScript for <code>sb_secret_</code>, and decode the middle part of any legacy key that starts with <code>eyJ</code>: it must say <code>"role":"anon"</code>. If a secret key has shipped, rotate it today.</p>
<h2>Who can read your table?</h2>
<p>With RLS off, anyone holding your publishable key can read and change every row. With RLS on and no policy, nobody can. An owner-only policy gives each signed-in user their own rows, and a view created without <code>security_invoker</code> skips all of it. Try each one below. I checked every combination against real Postgres with Supabase&rsquo;s <code>anon</code> and <code>authenticated</code> roles.</p>
<p><a href="https://tawfik.tv/notes/supabase-security-checklist">Open the interactive diagram on tawfik.tv</a></p>

<h2>The Supabase security checklist</h2>
<p><strong>1. Turn on RLS on every table the API can see.</strong> Tables you create in the dashboard get RLS automatically. Tables created in SQL or by a migration start with it off, and by default Supabase has granted visitors and signed-in users access to new tables in <code>public</code>, a default it is moving to opt-in (<a href="https://supabase.com/docs/guides/database/hardening-data-api">hardening the Data API</a>). Find the gaps:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">-- tables in public with RLS off
select tablename from pg_tables
where schemaname = 'public' and not rowsecurity;

-- turn it on, one line per table
alter table public.orders enable row level security;</pre>

<p>With RLS on and no policy, the API returns nothing (<a href="https://supabase.com/docs/guides/database/postgres/row-level-security">Row Level Security</a>). That is the safe way to fail. If your app never uses the Supabase client libraries, you can turn the Data API off altogether.</p>
<p><strong>2. Never use <code>using (true)</code> on private data.</strong> A policy with no <code>to</code> clause applies to every role, <code>PUBLIC</code> in <a href="https://www.postgresql.org/docs/current/sql-createpolicy.html">Postgres terms</a>, and <code>true</code> lets every row through. That includes visitors who never signed in. Name the role and check the owner:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">create policy "Read own orders" on public.orders
  for select to authenticated
  using ((select auth.uid()) = user_id);

create policy "Edit own orders" on public.orders
  for update to authenticated
  using ((select auth.uid()) = user_id)
  with check ((select auth.uid()) = user_id);</pre>

<p><strong>3. Pair every update policy with a select policy.</strong> Supabase needs a matching <code>SELECT</code> policy before an <code>UPDATE</code> can work. <code>using</code> decides which rows a user may change, <code>with check</code> decides what the row may look like afterwards. Postgres reuses <code>using</code> when you leave <code>with check</code> out; write both so the rule is visible.</p>
<p><strong>4. Check roles from <code>app_metadata</code>, never <code>user_metadata</code>.</strong> Signed-in users can edit their own <code>user_metadata</code>, so a policy that trusts it lets anyone promote themselves. Put roles in <code>app_metadata</code>, which only your server can set:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">create policy "Owners or admins read" on public.orders
  for select to authenticated
  using (
    (select auth.uid()) = user_id
    or (select auth.jwt() -> 'app_metadata' ->> 'role') = 'admin'
  );</pre>

<p><strong>5. Make every view <code>security_invoker</code>.</strong> Supabase&rsquo;s docs say it plainly: views bypass RLS by default, because the <code>postgres</code> user usually creates them. Postgres checks a view&rsquo;s tables against the view owner unless <code>security_invoker</code> is set (<a href="https://www.postgresql.org/docs/current/sql-createview.html">CREATE VIEW</a>). On Postgres 15 and later:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">alter view public.order_list set (security_invoker = true);</pre>

<p>Materialized views and foreign tables cannot be protected by RLS at all, so keep them out of exposed schemas.</p>
<p><strong>6. Lock down <code>security definer</code> functions.</strong> They run with their creator&rsquo;s rights and can return rows the caller is not allowed to read (<a href="https://supabase.com/docs/guides/database/functions">database functions</a>). Prefer <code>security invoker</code>, the default. Where you need definer, pin the search path and take execute away from roles that should not call it:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">alter function public.is_admin() set search_path = '';
revoke execute on function public.is_admin() from public, anon;</pre>

<p><strong>7. Keep secret keys on the server.</strong> Edge Functions, your backend, CI secrets: fine. The browser, a mobile app, a public repo: never. If one leaked, create a new key, swap it in everywhere, then delete the old one.</p>
<p><strong>8. Write storage policies per folder.</strong> Storage refuses uploads until a policy allows them, and files in a public bucket can be read by anyone with the URL (<a href="https://supabase.com/docs/guides/storage/security/access-control">storage access control</a>). Give each user a folder named after their ID:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">create policy "Upload to own folder" on storage.objects
  for insert to authenticated
  with check (
    bucket_id = 'uploads'
    and (storage.foldername(name))[1] = (select auth.jwt() ->> 'sub')
  );</pre>

<p><strong>9. Tighten Auth.</strong> From Supabase&rsquo;s <a href="https://supabase.com/docs/guides/deployment/going-into-prod">production checklist</a>: turn on email confirmations, set one-time password expiry to 3,600 seconds or lower, use your own SMTP server (the built-in one is limited to 2 emails an hour), and switch on CAPTCHA for sign-up, sign-in and password reset. On Pro and above, turn on <a href="https://supabase.com/docs/guides/auth/password-security">leaked password protection</a>, and keep the minimum password length at 8 or more. Protect your own Supabase account with MFA.</p>
<p><strong>10. Restrict direct database connections.</strong> <a href="https://supabase.com/docs/guides/platform/network-restrictions">Network restrictions</a> and <a href="https://supabase.com/docs/guides/platform/ssl-enforcement">SSL enforcement</a> cover Postgres and the connection pooler. They do not cover the HTTPS APIs, which always use SSL, so they sit alongside RLS rather than replacing it.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">supabase network-restrictions update --project-ref YOUR_REF --db-allow-cidr 203.0.113.10/32
supabase ssl-enforcement update --project-ref YOUR_REF --enable-db-ssl-enforcement --experimental</pre>

<p><strong>11. Keep a backup you have restored.</strong> Free projects get no automatic daily backups, so run <code>supabase db dump</code> on a schedule. Pro keeps 7 days, Team 14, Enterprise up to 30. Supabase recommends point-in-time recovery once a database passes 4 GB, and it needs at least the Small compute add-on. Files in Storage are not in database backups (<a href="https://supabase.com/docs/guides/platform/backups">backups</a>).</p>
<p><strong>12. Run the Security Advisor before every release.</strong> It sits in the dashboard under Advisors and flags most of this list by name: &ldquo;Table Publicly Accessible&rdquo;, &ldquo;View Bypasses Row-Level Security&rdquo;, &ldquo;Security Policy Allows Unrestricted Access&rdquo;, &ldquo;Security Policy Relies on User-Editable Data&rdquo; and &ldquo;SECURITY DEFINER Function Callable Without Sign-In&rdquo; (<a href="https://supabase.com/docs/guides/database/database-advisors">database advisors</a>). Clear every security warning before you ship.</p>
<p>If an AI coding agent works on your project, give it a read-only role and keep the secret key out of its reach. The <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> and <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop an agent deleting your database</a> cover that side.</p>
<h2>How do I fix slow Supabase queries caused by RLS?</h2>
<p>A policy runs against every row the query touches, so a slow policy makes every read slow. Supabase&rsquo;s own benchmarks show the size of the wins (<a href="https://supabase.com/docs/guides/troubleshooting/rls-performance-and-best-practices-Z5Jjwv">RLS performance and best practices</a>): an index on <code>user_id</code> took a query from 171 ms to under 0.1 ms, wrapping <code>auth.uid()</code> in a <code>select</code> took one from 179 ms to 9 ms, and adding <code>to authenticated</code> cut a visitor&rsquo;s request from 170 ms to under 0.1 ms.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">-- 1. index every column a policy filters on
create index orders_user_id_idx on public.orders using btree (user_id);

-- 2. slow: calls auth.uid() for every row
using (auth.uid() = user_id)

-- 2. fast: Postgres runs it once per query
using ((select auth.uid()) = user_id)

-- 3. filter in the query too, not only in the policy
supabase.from('orders').select('*').eq('user_id', userId)</pre>

<p>The Performance Advisor flags the second one as &ldquo;Slow Security Policy Detected&rdquo;, along with foreign keys that have no index.</p>
<p>Moving from Firebase? The rules model is different, and <a href="https://tawfik.tv/notes/firebase-to-supabase">moving from Firebase to Supabase</a> shows how security rules turn into policies.</p>
<h2>Questions people ask</h2>
<h3>Is the Supabase anon key safe to expose?</h3>
<p>Yes. It is designed to be public. RLS and your policies decide what it can reach, so it is only as safe as the policies on every exposed table.</p>
<h3>What happens if RLS is on but there are no policies?</h3>
<p>The API returns nothing for that table, to anyone using the publishable key, including your signed-in users. Add a policy to open it up.</p>
<h3>Does the service_role key bypass RLS?</h3>
<p>Yes. The <code>service_role</code> key and new secret keys skip every policy. Use them only on a server you control.</p>
<h3>Why can my users read rows but not update them?</h3>
<p>An update needs both an update policy and a select policy on the same table. Check that the update policy&rsquo;s <code>using</code> and <code>with check</code> both match the owner.</p>
<h3>Do Supabase views respect RLS?</h3>
<p>Not by default. A view runs as its owner, usually <code>postgres</code>, which skips RLS. Set <code>security_invoker = true</code> on Postgres 15 or later.</p>
<h3>How do I check my Supabase project for leaks?</h3>
<p>Open the Security Advisor, run the RLS query in step 1, and check your built JavaScript for secret keys. Then sign out and call your tables with only the publishable key.</p>
<p>If you need a Supabase project checked and fixed before launch, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>Can a bank issue its own stablecoin? How a community bank launches one, step by step</title><link>https://tawfik.tv/notes/bank-stablecoin</link><guid>https://tawfik.tv/notes/bank-stablecoin</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Yes. Under the GENIUS Act a US bank can issue a stablecoin through an approved subsidiary, or partner, distribute or hold one. Here is how to start.</description>
<content:encoded><![CDATA[<p>Yes. Under the GENIUS Act, signed on 18 July 2025, a US bank can issue its own payment stablecoin through a subsidiary its regulator approves, and it can already offer, hold and safeguard stablecoins for its customers.</p>
<p>The pressure to act is in the deposits. On 15 December 2025 ICBA, the community bankers&rsquo; trade body, <a href="https://www.icba.org/w/icba-analysis-permitting-interest-on-stablecoins">estimated</a> that letting crypto firms pay interest on stablecoins would pull $1.3 trillion of deposits out of community banks and cut their lending by $850 billion.</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I have built the customer side of this twice: dollars, stablecoins and tokenized gold in one balance, with a checkpoint in front of every move. This is what the law allows, the four ways in, the part a bank has to build itself, and a 90-day pilot.</p>
<h2>What does the GENIUS Act allow banks to do?</h2>
<p>The parts of the <a href="https://www.govinfo.gov/content/pkg/PLAW-119publ27/html/PLAW-119publ27.htm">law&rsquo;s text</a> a bank needs first:</p>
<ul>
<li><strong>Who may issue.</strong> Only a &ldquo;permitted payment stablecoin issuer&rdquo; can issue a payment stablecoin in the US. For a bank, that means a subsidiary approved under section 5. Nonbank issuers get a federal or state licence instead.</li>
<li><strong>A clock on approval.</strong> The regulator has to decide within 120 days of receiving a substantially complete application.</li>
<li><strong>One for one reserves.</strong> Every coin is backed at least one to one by cash, deposits at insured banks, Treasury bills of 93 days or less, and a short list of similar assets.</li>
<li><strong>Monthly disclosure.</strong> The issuer publishes the size and makeup of its reserves every month, an accounting firm examines the report, and the CEO and CFO certify it.</li>
<li><strong>No interest.</strong> An issuer may not pay holders interest or yield just for holding the coin.</li>
<li><strong>No deposit insurance.</strong> Stablecoins are not insured, and saying they are is unlawful.</li>
<li><strong>Full anti-money laundering duties.</strong> The issuer counts as a financial institution under the Bank Secrecy Act: customer identification, a sanctions programme, suspicious activity reporting, and the technical ability to block, freeze and reject transactions.</li>
<li><strong>Timely redemption.</strong> The issuer must publish clear redemption procedures, and only regulators can put discretionary limits on redemption.</li>
<li><strong>Tokenized deposits are separate.</strong> The definition of a payment stablecoin excludes a deposit, &ldquo;including a deposit recorded using distributed ledger technology&rdquo;. Section 16 keeps a bank&rsquo;s power to issue digital assets that represent its deposits.</li>
</ul>
<p><strong>When it starts.</strong> The Act takes effect on the earlier of 18 January 2027, 18 months after signing, or 120 days after the regulators issue final rules. The <a href="https://www.occ.gov/news-issuances/news-releases/2026/nr-occ-2026-9.html">OCC</a> proposed its rule on 25 February 2026, the <a href="https://www.fdic.gov/news/financial-institution-letters/2026/notice-proposed-rulemaking-establish-genius-act">FDIC</a> on 7 April 2026 and the <a href="https://www.federalreserve.gov/newsevents/pressreleases/bcreg20260924a.htm">Federal Reserve</a> on 24 September 2026. On 19 August 2026 the Comptroller <a href="https://www.occ.gov/news-issuances/news-releases/2026/nr-occ-2026-69.html">said</a> the OCC would have a final rule out by November.</p>
<p><strong>What is allowed already.</strong> On 7 March 2025 the OCC <a href="https://www.occ.gov/news-issuances/news-releases/2025/nr-occ-2025-16.html">confirmed</a> that crypto custody and certain stablecoin activities are permissible for national banks. On 28 March 2025 the FDIC <a href="https://www.fdic.gov/news/press-releases/2025/fdic-clarifies-process-banks-engage-crypto-related-activities">said</a> the banks it supervises may do permissible crypto activities without asking first, as long as they manage the risks.</p>
<h2>What are the four ways a bank can offer stablecoins?</h2>
<p>From the most work to the least.</p>
<ol>
<li><strong>Issue.</strong> The bank sets up a subsidiary, applies to its federal regulator, holds the reserve, publishes it monthly and runs the full compliance programme. A bank that wants a digital dollar without a new subsidiary can tokenize its own deposits instead, and those stay deposits under the law.</li>
<li><strong>Partner.</strong> A white-label stablecoin: an issuer that is already permitted issues the coin, and the bank puts its brand and its customers on it. The law is clear that the issuer of record must be a permitted issuer, so the contract decides who answers for what.</li>
<li><strong>Distribute.</strong> The bank lets customers buy, hold and send existing stablecoins and tokenized gold inside the app they already use. Section 16 says regulated banks may act &ldquo;as a principal or agent&rdquo; with any payment stablecoin. From 18 July 2028, three years after signing, a digital asset service provider may only offer US customers stablecoins from permitted issuers, with narrow exceptions for some foreign issuers, so choose the coin with that date in mind.</li>
<li><strong>Hold.</strong> The bank safeguards coins and keys for customers, which section 16 confirms banks may do. It can also hold another issuer&rsquo;s reserves as deposits, since cash at an insured bank is an eligible reserve asset. That one brings deposits back in.</li>
</ol>
<p>A bank does not have to pick one. Distributing and holding can start now, and issuing can wait for the final rules.</p>
<p><strong>Tokenized gold sits outside the GENIUS Act.</strong> A payment stablecoin has to be redeemable for &ldquo;a fixed amount of monetary value&rdquo;. A gold token is redeemable for a weight of metal, so it does not meet that definition. Its rules come from elsewhere, and the bank&rsquo;s counsel should map them before launch.</p>
<h2>What does a bank have to build that it cannot buy?</h2>
<p>Access is easy to buy. Large providers already resell custody and stablecoin payments to thousands of banks. What a bank cannot buy off the shelf is the decision: who passed identity checks, who may send, mint or redeem, up to what limit, checked before the money moves, and written into a record an examiner will accept. Those rules are the bank&rsquo;s, so the layer that applies them has to be the bank&rsquo;s too.</p>
<p>The first build was a bank-in-a-box for a listed gold company: a white-label app where a bank&rsquo;s customers hold dollars, stablecoins and tokenized gold in one balance. Every send or purchase goes through a checkpoint of 11 ordered rules with three outcomes: allowed, held, or unavailable when a fact the checkpoint needs, such as the gold price, has gone stale. The second was a partner-bank app: customers keep the keys to their own wallet, the bank chooses what is on the menu, and every move is checked before it happens. The full story is in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer: four AI and fintech builds</a>.</p>
<p>The rules that matter, in the order a checkpoint should read them:</p>
<ul>
<li><strong>Identity.</strong> Has this person passed the bank&rsquo;s identity check? I wrote about proving who someone is without exposing their whole file in <a href="https://tawfik.tv/notes/prove-the-fact">how to prove who someone is</a>.</li>
<li><strong>Sanctions.</strong> A match freezes the money and goes to a person. The app never clears it on its own.</li>
<li><strong>Funds and limits.</strong> The balance is there and the bank&rsquo;s daily limit is respected, except on redemption, where the law gives that power to regulators only.</li>
<li><strong>Fresh facts.</strong> A stale price makes the answer &ldquo;unavailable&rdquo;. The checkpoint does not guess.</li>
<li><strong>Reserve.</strong> No new coin is issued unless every coin already out is covered one for one.</li>
<li><strong>The record.</strong> Every decision is written down, including the ones that stopped, with the rule that stopped it.</li>
</ul>
<p>Try it below. Pick an action, switch facts off, and watch where the money stops.</p>
<p><a href="https://tawfik.tv/notes/bank-stablecoin">Open the interactive diagram on tawfik.tv</a></p>

<p>The order is part of the rule. If the sanctions screen runs after the limit check, a sanctioned customer gets a polite &ldquo;held for approval&rdquo; when the money should be frozen and reported. Compliance sets the order once, in plain English, and the checkpoint follows it every time.</p>
<h2>What does a 90-day stablecoin pilot look like?</h2>
<p>How I would run it: small, measured, and easy to stop.</p>
<ol>
<li><strong>Days 1 to 15: pick one route and one use.</strong> For example: distribute one permitted stablecoin to staff accounts only. Write the rules in plain English with the compliance officer, in order, with the outcome for each.</li>
<li><strong>Days 16 to 45: wire the checkpoint.</strong> Connect it to the identity check, the sanctions screen and the core ledger the bank already runs. Nothing gets ripped out. Every rule gets a test that breaks it on purpose.</li>
<li><strong>Days 46 to 75: go live with low limits.</strong> Staff first, then a small group of customers. Track holds, refusals and time to decide weekly.</li>
<li><strong>Days 76 to 90: review and decide.</strong> Walk compliance through the record, then widen, change the rules or stop, with the numbers in front of you.</li>
</ol>
<p>Ship a test with every claim on the screen, so what the customer sees never drifts from the rules behind it.</p>
<h2>Questions people ask</h2>
<h3>Can a community bank issue its own stablecoin?</h3>
<p>Yes, through a subsidiary approved by its federal regulator under the GENIUS Act. The regulator has 120 days to decide on a complete application. The detailed rules are still being finalised, so distributing or holding stablecoins is the faster start.</p>
<h3>Is a tokenized deposit the same as a stablecoin?</h3>
<p>No. The Act excludes deposits from the definition, including deposits recorded on a blockchain. The FDIC&rsquo;s April 2026 proposal says deposit insurance does not depend on the technology used to record a deposit. Stablecoins cannot be insured.</p>
<h3>What is a white-label stablecoin?</h3>
<p>A coin that carries the bank&rsquo;s brand while a permitted issuer issues it and holds the reserve. The bank brings customers and the decision layer. The contract sets who handles redemption, disclosure and compliance.</p>
<h3>Is tokenized gold a stablecoin?</h3>
<p>Not under the GENIUS Act. A gold token redeems for metal, and the definition needs a fixed amount of money. A bank can still offer it, with the same checkpoint in front of every purchase.</p>
<h3>When does the GENIUS Act take effect?</h3>
<p>On 18 January 2027 at the latest, or 120 days after the regulators issue final rules if that comes first.</p>
<p>If you need this built, write to m@tawfik.tv, or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>How much does it cost to build an app? Where the money goes, and what AI changes</title><link>https://tawfik.tv/notes/app-development-cost</link><guid>https://tawfik.tv/notes/app-development-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>On Clutch, app projects most often cost $10,000 to $49,999 and average $90,780. Here is where the money goes and what building with AI changes.</description>
<content:encoded><![CDATA[<p>A focused app with login, payments and an admin screen usually costs tens of thousands of dollars to build, and a bigger one with chat, maps or two native apps runs well into six figures. Most of that money pays for the work after the first version: security, payment edge cases, testing on real phones and getting through the app stores.</p>
<p>The best public number I know comes from Clutch. Across mobile app projects reviewed on its platform, the most common cost is <a href="https://clutch.co/app-developers/resources/cost-to-build-mobile-app">$10,000 to $49,999</a>, the average is $90,780.11 and the typical timeline is about 11 months (figures on the page as updated on 21 September 2026).</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I built and shipped <a href="https://tawfik.tv/notes/one-person-ai-team">Laqtaa</a>, a shared wedding photo app, on my own with AI, and I scope app builds for clients. I don&rsquo;t publish my own prices here. Every dollar below comes from a cited source.</p>
<h2>How much does it cost to build an app?</h2>
<p>It depends on three things: how much the app does, how many platforms it runs on, and who builds it at what hourly rate. Clutch&rsquo;s numbers give the market picture:</p>
<ul>
<li><strong>Most common project:</strong> $10,000 to $49,999.</li>
<li><strong>Average project:</strong> $90,780.11, spread over about 11 months, which Clutch puts at $8,188.44 a month.</li>
<li><strong>Hourly rates by company location:</strong> $25 to $49 in the United States, Spain and Ukraine, $50 to $99 in Canada and Poland, $100 to $149 in Australia.</li>
</ul>
<p>For comparison with an in-house hire: the U.S. Bureau of Labor Statistics puts the <a href="https://www.bls.gov/ooh/computer-and-information-technology/software-developers.htm">median software developer wage at $135,980 a year</a> in May 2025, before benefits, laptops and management time.</p>
<p>Build your own estimate below. Pick the app type, platforms, features, who builds it and a rate band. You get a cost range, a timeline and the monthly bill. The weeks are my planning assumptions, shown so you can check the sum. The rates and fees are cited market data.</p>
<p><a href="https://tawfik.tv/notes/app-development-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>Where does the money go when you build an app?</h2>
<p>Into nine pieces of work.</p>
<ol>
<li><strong>Discovery and design.</strong> Who the app is for, the screens, the flows, what is out of scope.</li>
<li><strong>The backend.</strong> The database, the server logic and the APIs every screen talks to.</li>
<li><strong>Login and accounts.</strong> Sign-up, password resets, social sign-in, deleting an account, and rules for who can see whose data. Get those rules wrong and one user reads another user&rsquo;s records. My <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a> covers the common holes.</li>
<li><strong>Payments.</strong> Checkout is quick. Refunds, failed cards and webhooks that arrive twice take the time.</li>
<li><strong>An admin screen.</strong> Someone on your team will need to look up a customer, fix an order or ban a spammer without a developer.</li>
<li><strong>QA on real phones.</strong> The cheap Android, the old iPhone, a phone call arriving mid-upload, bad signal.</li>
<li><strong>Store release.</strong> Apple&rsquo;s developer program costs <a href="https://developer.apple.com/programs/enroll/">$99 a year</a>, Google Play charges a <a href="https://support.google.com/googleplay/android-developer/answer/6112435">$25 one-time registration fee</a>, and both stores review your app before it goes live.</li>
<li><strong>Hosting.</strong> The servers and database the app runs on, every month.</li>
<li><strong>Maintenance.</strong> Operating systems update, store rules change and users find bugs. I haven&rsquo;t found a primary survey that puts a reliable yearly percentage on it, so budget it as monthly hours.</li>
</ol>
<h2>How much does an MVP app cost?</h2>
<p>An MVP, a minimum viable product, is the smallest version that proves people want the thing. For most MVPs, that means one platform or a web app, login, one core flow and an admin screen.</p>
<p>On the market numbers above, a focused MVP usually lands in Clutch&rsquo;s most common band, $10,000 to $49,999. It moves up fast with two native apps, chat, offline mode or anything that touches money. A web app that opens from a link skips the app store fees and review, which is why I start most MVPs in the browser.</p>
<p>Get two or three quotes against the same written scope, or the numbers won&rsquo;t be comparable. This is the one-page scope I send:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">App: one sentence on who it is for and the one job it does
Platforms: web / iPhone / Android (and one codebase or two)
Must have at launch: login, [core flow], admin screen
Not at launch: [list what you are cutting]
Payments: none / one-off / subscriptions / payouts to sellers
Data rules: who can see what, how long you keep it, how users delete it
Testing: which real phones, and who signs off
Release: who owns the Apple and Google developer accounts
After launch: hours per month for fixes and OS updates
Quote as: design / build / hardening and QA / release / monthly running costs</pre>

<p>The last line matters most: it shows where each vendor is cheap and what they left out.</p>
<h2>How much does it cost to build an app with AI?</h2>
<p>Less for the first version, about the same for everything after it.</p>
<p>The evidence goes both ways, and both results match what I see. In a controlled experiment, developers with an AI assistant <a href="https://arxiv.org/abs/2302.06590">finished a contained coding task 55.8% faster</a> than developers without one. In a later trial on mature code, <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">16 experienced developers took 19% longer</a> with AI across 246 real tasks, even though they expected it to make them 24% faster (METR, July 2025).</p>
<p>A new app starts as a contained task, and then it turns into mature code. Laqtaa went exactly that way. I wrote a 780-line brief first. On day one, 6 milestones were built and deployed in 53 minutes. A couple of hours later the next commit read &ldquo;resolve all critical runtime bugs&rdquo;. Over 5 weeks that became 188 commits, and 93 of them were fixes against 69 features. About 100 wedding guests used it on the day and nothing broke. <a href="https://tawfik.tv/notes/one-person-ai-team">The full story is here</a>.</p>
<p>So in the estimate builder, &ldquo;one builder with AI&rdquo; halves the build weeks, trims design by a quarter and leaves hardening untouched. That split is my assumption, and it is the same pattern I describe in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">four AI and fintech builds</a>: a prototype takes days, and identity, permissions, limits and an audit trail are the real work. AI makes a cheap first version possible. It doesn&rsquo;t make the security review, the payment edge cases or the testing on real phones optional.</p>
<h2>How much does an app cost to run each month?</h2>
<p>For a typical small app, before heavy usage:</p>
<ul>
<li><strong>Database, sign-in and file storage:</strong> Supabase Pro <a href="https://supabase.com/pricing">from $25 a month</a>, including 100,000 monthly active users and 100 GB of files.</li>
<li><strong>Hosting:</strong> Vercel Pro at <a href="https://vercel.com/pricing">$20 a month</a> per developer seat.</li>
<li><strong>Apple Developer Program:</strong> $99 a year if you ship on iPhone.</li>
<li><strong>Card payments:</strong> Stripe charges <a href="https://stripe.com/pricing">2.9% + 30¢ per successful US domestic card payment</a>. Digital goods sold inside an iPhone app pay Apple&rsquo;s commission instead, <a href="https://developer.apple.com/app-store/small-business-program/">15% under the Small Business Program</a> for developers earning up to $1 million a year.</li>
<li><strong>Maps:</strong> Google&rsquo;s Maps SDK for phone apps is free, and web maps get <a href="https://developers.google.com/maps/billing-and-pricing/pricing">10,000 free loads a month</a>, then $7 per 1,000.</li>
<li><strong>AI features:</strong> billed per use by the model provider. Set a monthly cap before launch.</li>
</ul>
<p>Laqtaa costs me about $46 a month: $20 for Vercel Pro, $25 for Supabase Pro and about $1 for the domain, and those two plans also carry my other projects.</p>
<h2>Should you hire an agency, a freelancer or one developer with AI?</h2>
<p>Match the choice to what you can manage yourself.</p>
<ul>
<li><strong>Agency.</strong> A designer, developers, QA and a project manager in one contract. The highest total in the estimate, because project management and QA hours sit on top, and the fastest on the calendar because people work in parallel. Pick it when nobody on your side can run the project.</li>
<li><strong>Freelancer.</strong> One developer, at the same market rates without the overhead. Slower on the calendar, and you become the project manager, the tester and the person who says no.</li>
<li><strong>One builder with AI.</strong> The cheapest first version and the fastest route to something you can tap. The hardening still takes the same weeks, so ask how they will test, secure and release it before you sign.</li>
</ul>
<p>Whichever you pick, ask for references from apps that are live in the stores, own your Apple and Google developer accounts yourself, and get the source code in your own repository from day one.</p>
<h2>Questions people ask</h2>
<h3>How much does it cost to build an app?</h3>
<p>On Clutch, the most common mobile app project costs $10,000 to $49,999 and the average is $90,780, over about 11 months. More features, more platforms and higher hourly rates push it up.</p>
<h3>How much does an MVP app cost?</h3>
<p>A focused MVP with login, one core flow and an admin screen usually fits Clutch&rsquo;s most common band, $10,000 to $49,999. A web app avoids app store fees and review.</p>
<h3>Is it cheaper to build an app with AI?</h3>
<p>The first version, yes: in one controlled study, developers with AI finished a contained coding task 55.8% faster. Hardening costs about the same, and a study on mature code found experienced developers 19% slower with AI.</p>
<h3>What are the monthly costs of running an app?</h3>
<p>For a small app, about $45 a month for a database plan and hosting, plus $99 a year for Apple, plus payment and usage fees. Budget developer hours for fixes and OS updates on top.</p>
<h3>How do I hire an app developer?</h3>
<p>Write a one-page scope, get two or three quotes split into design, build, hardening, release and running costs, check live apps they shipped, and keep the developer accounts and source code in your name.</p>
<h3>Can you build my app?</h3>
<p>Yes. I scope, build and ship apps with AI in the loop, and I can run the product side too, as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>. For booking apps with Apple and Google Wallet loyalty cards, see <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and loyalty</a>. If you need this built, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>Three.js website: what three.js is, what you need to build a 3D site, and what it costs</title><link>https://tawfik.tv/notes/threejs-website</link><guid>https://tawfik.tv/notes/threejs-website</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>three.js is a free, MIT-licensed JavaScript library that draws 3D in a web page. A 3D site needs a scene, a camera, a renderer, lights and glTF models.</description>
<content:encoded><![CDATA[<p>three.js is a free JavaScript library that draws interactive 3D inside an ordinary web page, so people open it from a link with nothing to install. A three.js website is a normal page with one canvas in it, where the library draws your models, lights and camera again on every frame.</p>
<p>It is the default way to put 3D on the web. The <code>three</code> package was downloaded <a href="https://api.npmjs.org/downloads/point/2026-10-06:2026-10-12/three">21.4 million times from npm</a> in the week of 6 to 12 October 2026. The current release is <a href="https://github.com/mrdoob/three.js/releases/tag/r186">r186</a>, published on 24 September 2026, under the <a href="https://github.com/mrdoob/three.js/blob/dev/LICENSE">MIT licence</a>.</p>
<p>I build 3D for the browser. My <a href="https://gvnr-survivors.vercel.app">GVNR Survivors</a> game is three.js, and my <a href="https://tawfik.tv/window">splat window demo</a> renders a Gaussian splat with Spark, a splat renderer for three.js. Here is what you need, code you can copy, how to keep it fast on a phone, and what a build costs.</p>
<h2>What is three.js?</h2>
<p>three.js describes itself as an &ldquo;easy-to-use, lightweight, cross-browser, general-purpose 3D library&rdquo; (<a href="https://github.com/mrdoob/three.js">README</a>). It does the hard parts for you: the maths of cameras and perspective, the shader code the graphics chip runs, loading 3D files, lights, shadows and materials.</p>
<ul>
<li><strong>Two renderers.</strong> <code>WebGLRenderer</code> draws with WebGL. <code>WebGPURenderer</code> uses WebGPU and, the docs say, <a href="https://threejs.org/docs/pages/WebGPURenderer.html">falls back to a WebGL 2 backend</a> where the browser has no WebGPU.</li>
<li><strong>Small for what it does.</strong> I bundled the scene below with esbuild: three.js r186 with the glTF loader and orbit controls comes to about 159 KB gzipped for WebGL, and about 270 KB with <code>WebGPURenderer</code>.</li>
<li><strong>Examples with source.</strong> The official <a href="https://threejs.org/examples/">three.js examples</a> page lists more than 600 demos, each with its code: materials, loaders, physics, post-processing, WebXR and WebGPU. There is also a <a href="https://threejs.org/editor/">three.js editor</a> that runs in the browser.</li>
</ul>
<h2>What do you need to build a 3D website?</h2>
<p>The <a href="https://threejs.org/manual/#en/creating-a-scene">three.js manual</a> puts it in one line: to display anything you need a scene, a camera and a renderer. For a real site you add two more.</p>
<ol>
<li><strong>A scene.</strong> The container. Everything you want drawn gets added to it.</li>
<li><strong>A camera.</strong> Usually a <code>PerspectiveCamera</code>, set by field of view, aspect ratio and the near and far distances it can see.</li>
<li><strong>A renderer.</strong> It draws the scene from the camera into a <code>&lt;canvas&gt;</code> on your page, once per screen refresh.</li>
<li><strong>Models in glTF.</strong> The manual <a href="https://threejs.org/manual/#en/loading-3d-models">recommends glTF</a>, as <code>.glb</code> or <code>.gltf</code>, because it is built for fast delivery and carries meshes, materials, textures, animations and cameras. Blender exports it.</li>
<li><strong>Lights.</strong> A <code>MeshStandardMaterial</code> is <a href="https://threejs.org/docs/pages/MeshStandardMaterial.html">physically based</a>, so with no light it renders black. A <a href="https://threejs.org/docs/pages/HemisphereLight.html">HemisphereLight</a> gives soft light from the sky and cannot cast shadows. A <a href="https://threejs.org/docs/pages/DirectionalLight.html">DirectionalLight</a> behaves like the sun and can. A <code>MeshBasicMaterial</code> ignores light altogether.</li>
</ol>
<p>Build one below. Add or remove each part, change its settings, and watch the preview, the code and a phone budget move together. Remove every light to see the black.</p>
<p><a href="https://tawfik.tv/notes/threejs-website">Open the interactive diagram on tawfik.tv</a></p>

<h2>A minimal three.js scene you can copy</h2>
<p>This is a complete page: a camera, two lights, a floor and a glTF model you can orbit. It follows the manual&rsquo;s <a href="https://threejs.org/manual/#en/installation">installation</a> and first-scene guides, with the version pinned, and I checked it against r186. Serve the folder from a local server, not by double-clicking the file.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">&lt;!doctype html&gt;
&lt;style&gt; body { margin: 0; } &lt;/style&gt;
&lt;script type="importmap"&gt;
{ "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.1/examples/jsm/" } }
&lt;/script&gt;
&lt;script type="module"&gt;
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);

const camera = new THREE.PerspectiveCamera(50, innerWidth / innerHeight, 0.1, 100);
camera.position.set(2.5, 2, 3.5);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2)); // a 3x phone screen is not worth the cost
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

scene.add(new THREE.HemisphereLight(0xffffff, 0x8d7c6a, 1.5));
const sun = new THREE.DirectionalLight(0xffffff, 2.5);
sun.position.set(3, 6, 3);
scene.add(sun);

const floor = new THREE.Mesh(new THREE.PlaneGeometry(8, 8), new THREE.MeshStandardMaterial({ color: 0xb9b4ab }));
floor.rotation.x = -Math.PI / 2;
scene.add(floor);

const model = await new GLTFLoader().loadAsync('/models/chair.glb');
scene.add(model.scene);

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0.5, 0);

addEventListener('resize', () =&gt; {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

renderer.setAnimationLoop(() =&gt; {
  controls.update();
  renderer.render(scene, camera);
});
&lt;/script&gt;</pre>

<p>For production, the manual recommends installing <code>three</code> from npm and building with a tool such as Vite, so you ship only what you use. Keep every three.js file on the same version: the manual warns that mixing versions can break the app.</p>
<h2>How do you keep a three.js site fast on a phone?</h2>
<p>Four numbers decide it. You can read the first two from <code>renderer.info</code> while the page runs.</p>
<ul>
<li><strong>Draw calls.</strong> Every mesh with its own material is at least one draw call, and each call costs processor time before the graphics chip draws a thing. Fifty copies of a chair with two materials is 100 calls. As an <code>InstancedMesh</code> it is 2. Shadows draw every shadow caster a second time.</li>
<li><strong>Texture memory.</strong> A PNG or JPEG is unpacked on the GPU to 4 bytes a pixel, so one 2048 by 2048 texture takes 16 MB, plus a third more for its smaller mipmap copies. JPEG makes the download smaller, not the memory. KTX2 textures stay compressed on the GPU, at about 1 byte a pixel in formats such as ASTC 4x4 and BC7, and three.js&rsquo;s <code>KTX2Loader</code> picks the format each device supports.</li>
<li><strong>Pixels.</strong> A phone screen of 390 by 844 points at 3x is 2.96 million pixels a frame. Capped at 2x it is 1.32 million, less than half. GVNR Survivors draws at most 1.75 pixels per screen point. My window demo goes further: when 60 frames average slower than 25 ms, it lowers the resolution a step.</li>
<li><strong>The first download.</strong> Compress meshes with Draco and load the first room first. In my <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores</a> the meshes were Draco-compressed and the textures KTX2, streamed from a CDN while the customer looked around. GVNR Survivors is about 4 MB with its 3D models.</li>
</ul>
<p>I go through draw calls, levels of detail, texture formats and memory in more depth, with the three.js names for each fix, in <a href="https://tawfik.tv/notes/unity-webgl-mobile">Unity WebGL on mobile</a>. The rules are the same in both engines.</p>
<h2>three.js, Unity WebGL or a splat viewer?</h2>
<ul>
<li><strong>three.js</strong> when the page must open fast from a link, especially on phones: stores, product configurators, branded games, a 3D hero on a marketing site. You write JavaScript, and the library is one of the smallest parts of the download.</li>
<li><strong>Unity for the web</strong> when the model is heavy or the same project also ships as an app. It brings an editor, baked lighting and a bigger first download. My route from a 650 MB construction model to a 74 MB browser build is in <a href="https://tawfik.tv/notes/unity-webgl-mobile">Unity WebGL on mobile</a>.</li>
<li><strong>A Gaussian splat viewer</strong> when you want a real place or object exactly as the camera saw it, scanned from photos instead of modelled. Spark draws splats inside a three.js scene, so you can mix both. How to capture and publish one is in <a href="https://tawfik.tv/notes/gaussian-splatting-website">Gaussian splatting on a website</a>.</li>
</ul>
<p>There is a fourth route, streaming a game engine from a cloud GPU, for when the visuals cannot be cut down to fit a phone. It costs a GPU per viewer for as long as they stay, which is why I build for the browser first.</p>
<h2>What does a three.js website cost?</h2>
<p>The library is free. Its MIT licence allows commercial use, as long as you keep the copyright notice. A three.js site is static files on a CDN: each visitor downloads it once, and there is no server rendering frames per viewer.</p>
<p>The build is custom web work. <a href="https://clutch.co/web-developers/pricing">Clutch&rsquo;s web development pricing guide</a>, updated 21 September 2026, says web development projects on its platform typically cost less than $10,000, puts the average agency project at $66,499.09, and says most agencies charge $25 to $49 an hour. A 3D site sits in the same market with extra work on top: models built or cleaned to a budget, lighting, and testing on real phones.</p>
<p>Four things set the price and the timeline: how many products or rooms are rebuilt in 3D, how real they must look, how many people are in it at once, and whether it runs once live or stays open. Bring the 3D files you already have: a clean CAD or glTF model to start from saves modelling time.</p>
<h2>Questions people ask</h2>
<h3>Is three.js free for commercial use?</h3>
<p>Yes. It is MIT licensed, so you can use it in paid and closed-source work. Keep the licence notice with the code.</p>
<h3>What is the difference between three.js and WebGL?</h3>
<p>WebGL is the browser&rsquo;s low-level graphics interface. three.js sits on top of it, and on WebGPU, and gives you scenes, cameras, lights, materials and model loaders, so you write far less code than WebGL alone needs.</p>
<h3>Do I need React to use three.js?</h3>
<p>No. three.js is plain JavaScript and works on any page. If your site is already React, <a href="https://github.com/pmndrs/react-three-fiber">React Three Fiber</a> is a React renderer for three.js, also MIT licensed.</p>
<h3>Where can I find three.js examples?</h3>
<p>On <a href="https://threejs.org/examples/">threejs.org/examples</a>, with source for every demo. To see one on a phone, play <a href="https://gvnr-survivors.vercel.app">GVNR Survivors</a> or open <a href="https://tawfik.tv/window">my window demo</a>.</p>
<h3>Does three.js work on iPhone and Android?</h3>
<p>Yes, in the browser, through WebGL 2, and through WebGPU where the browser supports it. Whether it runs well depends on draw calls, textures and pixel ratio, so test on a real mid-range phone.</p>
<p>If you want a 3D store, configurator, game or product page built in three.js, see <a href="https://tawfik.tv/hire/3d-web-experiences">3D web experiences</a> or write to me at m@tawfik.tv.</p>]]></content:encoded></item><item><title>AI chatbot for your website: build or buy, what it costs, and how it learns your content</title><link>https://tawfik.tv/notes/ai-chatbot-for-website</link><guid>https://tawfik.tv/notes/ai-chatbot-for-website</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Add an AI chatbot to your website three ways: a help desk widget, a no-code builder, or a custom bot on a model API. Prices checked at the source.</description>
<content:encoded><![CDATA[<p>You add an AI chatbot to your website by pasting a short script from a provider into your site, then giving the bot your own pages and documents to answer from. There are three routes: the AI add-on from a help desk vendor, a no-code chatbot builder, or a custom bot you build on a model API with your own documents.</p>
<p>Most small businesses have not done it yet. The US Census Bureau <a href="https://census.gov/library/stories/2026/05/ai-use-businesses.html">reported in May 2026</a> that between 17% and 20% of US businesses used AI from December 2025 to May 2026, and fewer than 20% of firms with four or fewer employees.</p>
<p>I set up an AI help desk for a fintech platform: I bought the agent instead of building one, and wrote the help centre it answers from. I&rsquo;m chief product officer and forward deployed engineer at Instruxi, where the job is making AI work inside a client&rsquo;s own systems. This note is for the owner choosing a chatbot for a website. If your real question is a support inbox, read <a href="https://tawfik.tv/notes/ai-customer-service-agent">AI customer service agent: what it can safely do</a> instead.</p>
<h2>How do you add an AI chatbot to your website?</h2>
<p>Pick a route, then do the same four steps whichever you choose.</p>
<ol>
<li><strong>A help desk widget.</strong> A live chat vendor sells an AI agent as an add-on to its chat box and inbox. You get the widget, the inbox your team answers handovers in, and a bill per AI conversation.</li>
<li><strong>A no-code builder.</strong> You upload files or point it at your website, it builds the bot, and you paste one script tag. You pay a monthly plan with a set number of message credits.</li>
<li><strong>Custom, on a model API.</strong> A developer writes the chat, stores your documents in a database, and calls a model such as Claude through its API. You pay for hosting and the tokens you use, plus the build.</li>
</ol>
<p>Then, on any route:</p>
<ol>
<li><strong>Collect the documents</strong>: your pages, price list, opening hours, payment rules, and what to do in an emergency.</li>
<li><strong>Write the instructions</strong>: answer only from those documents, say which one it used, and hand over when nothing matches.</li>
<li><strong>Test it with the questions customers really ask</strong>, including the awkward ones.</li>
<li><strong>Paste the script into your site</strong> and read the first week of chats.</li>
</ol>
<p>Try the three routes on a made-up London dental practice. Switch the route, take documents away, turn guessing on, and watch the answers, the sources, the handovers and the monthly bill.</p>
<p><a href="https://tawfik.tv/notes/ai-chatbot-for-website">Open the interactive diagram on tawfik.tv</a></p>

<h2>How much does an AI chatbot for a website cost?</h2>
<p>From about $45 a month to several hundred, depending on the route and how many people chat. US list prices, checked on each pricing page on 15 October 2026:</p>
<ul>
<li><strong>Help desk widget, <a href="https://www.tidio.com/pricing/">Tidio</a>.</strong> The free plan includes 50 AI conversations with its Lyro agent, once. Lyro starts at $32.50 a month for 50 conversations paid yearly; billed monthly, the page lists $75 for 100, $210 for 300 and $700 for 1,000. The Starter plan for the inbox is $24.17 a month paid yearly. Any conversation with at least one AI reply counts, solved or not. The bigger help desks charge per resolution; I priced them in the <a href="https://tawfik.tv/notes/ai-customer-service-agent">customer service agent note</a>.</li>
<li><strong>No-code builder, <a href="https://www.chatbase.co/pricing">Chatbase</a>.</strong> Hobby is $40 a month (or $32 paid yearly) for 700 message credits and 10 MB of training content. Standard is $150 a month (or $120 yearly) for 4,000 credits. Extra credits are $40 per 1,000, and removing its branding is $1,188 a year. Its <a href="https://www.chatbase.co/docs/faq/faq">FAQ</a> says most models use 1 credit per reply and premium models 2 to 5.</li>
<li><strong>Custom, on a model API.</strong> <a href="https://claude.com/pricing">Claude Haiku 5.5</a> costs $0.10 per million input tokens and $0.50 per million output tokens for prompts up to 100,000 tokens; Sonnet 5.5 is $2 and $10. Hosting on <a href="https://vercel.com/pricing">Vercel Pro</a> is $20 a month, and a <a href="https://supabase.com/pricing">Supabase</a> Pro database is from $25 a month.</li>
</ul>
<p><strong>A worked example: 300 chats a month, 3 replies each.</strong> The widget is $210 plus $24.17 for the inbox. The builder uses 900 credits: Hobby plus one top-up, $80. The custom bot sends about 3,000 tokens in and 250 out per reply: 2.7 million input tokens cost $0.27 and 225,000 output tokens $0.11 on Haiku 5.5, so $45.38 with hosting. On Sonnet 5.5 the tokens come to $7.65.</p>
<p>The custom route is cheapest to run and the only one with a build cost: a developer&rsquo;s time, and someone to look after it. That trade is what decides most cases. For the cost of the website around it, see <a href="https://tawfik.tv/notes/small-business-website-cost">how much a small business website costs</a>.</p>
<h2>How does a chatbot learn your website&rsquo;s content?</h2>
<p>It does not memorise your site. Every time someone asks a question, it looks up the right passage and reads it. The technical name is retrieval.</p>
<ol>
<li><strong>Split.</strong> Your pages and files are cut into short passages: a paragraph of the price list, one row of opening hours.</li>
<li><strong>Index.</strong> Each passage is stored so it can be found by meaning, as well as by its words. On a custom build that can be Postgres with <a href="https://supabase.com/docs/guides/database/extensions/pgvector">pgvector</a>.</li>
<li><strong>Find.</strong> The customer&rsquo;s question is matched against the index, and the closest three or four passages come back.</li>
<li><strong>Answer.</strong> Those passages go to the model with your instructions, and it writes a reply from them and names the source.</li>
</ol>
<p>If the right passage is missing, the model fills the gap with something that sounds right. That is why the documents come first. The instructions for the dental practice fit on one screen:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">You are the website assistant for Larkspur Dental, Islington, London.
Answer ONLY from the passages below. Name the document you used.
If no passage answers the question, say so and offer to pass it to reception.
Say you are an AI if anyone asks, and at the start of every chat.
Never:
  - give medical advice, or suggest any medicine or dose
  - quote a price, time or policy that is not in a passage
  - ask for or accept card details
  - book, move or cancel an appointment; link to the booking page
If someone mentions swelling, bleeding, a knocked-out tooth or severe pain:
  tell them to call 020 7946 0321, NHS 111 out of hours,
  and 999 or A&amp;E if swelling affects breathing or vision.

Passages:
{the 3 or 4 passages the search found}</pre>

<p>The emergency line follows the NHS&rsquo;s own advice on <a href="https://www.nhs.uk/nhs-services/dentists/how-to-find-an-nhs-dentist-in-an-emergency/">urgent dental care</a>, which sends severe swelling that affects breathing or vision to 999 or A&amp;E.</p>
<h2>What should a website chatbot never do?</h2>
<ul>
<li><strong>Guess.</strong> In March 2024 <a href="https://themarkup.org/news/2024/03/29/nycs-ai-chatbot-tells-businesses-to-break-the-law">The Markup found</a> that New York City&rsquo;s MyCity chatbot told business owners they could take a cut of their workers&rsquo; tips and go cashless, both against city law. Answer only from your documents, and hand over when nothing matches.</li>
<li><strong>Advise on health, money or law</strong> beyond what your documents say. Send people to a person or the right service.</li>
<li><strong>Promise what it cannot do</strong>: a price, a refund, a slot it has not checked.</li>
<li><strong>Take card details</strong> in chat. Send people to your payment page or reception.</li>
<li><strong>Pretend to be a person.</strong> The rules and the handover are in the <a href="https://tawfik.tv/notes/ai-customer-service-agent">customer service agent note</a>.</li>
<li><strong>Go quiet.</strong> On a credit plan, a bot that runs out shows a message that it is unavailable. Set a top-up or an alert.</li>
</ul>
<h2>How do you know if the chatbot is working?</h2>
<p>Read chats, not the dashboard. Every week:</p>
<ol>
<li><strong>Share answered with a source.</strong> Every unsourced answer is a possible wrong one.</li>
<li><strong>Handovers, by reason.</strong> Each repeat reason is a missing page or a missing rule.</li>
<li><strong>Wrong answers, from 20 chats read in full.</strong> The target is zero.</li>
<li><strong>What chats led to</strong>: booking clicks, enquiries, calls.</li>
<li><strong>Cost per useful chat</strong>: the monthly bill divided by chats that answered the question or started a booking.</li>
</ol>
<p>A chatbot answers. An AI agent takes actions, which needs a different set of controls, covered in <a href="https://tawfik.tv/notes/agentic-ai">what agentic AI is</a>.</p>
<h2>Which route should you pick?</h2>
<ul>
<li><strong>Help desk widget</strong> if people already answer chats and you want one inbox for the bot and the team.</li>
<li><strong>No-code builder</strong> if you want it live this week, your documents are in good shape, and volume is modest.</li>
<li><strong>Custom</strong> if the bot needs to read your own systems, such as free appointment times, if volume is high, or if you want the data and the instructions in your own hands.</li>
</ul>
<h2>Questions people ask</h2>
<h3>Can I add ChatGPT to my website?</h3>
<p>Not the ChatGPT app itself. The builders and the custom route use the same kind of model through an API, answering from your documents instead of the open web.</p>
<h3>Is there a free AI chatbot for a website?</h3>
<p>Tidio&rsquo;s free plan includes 50 AI conversations, once. That is enough to test with your own questions before you pay.</p>
<h3>Do I need a developer?</h3>
<p>Not for a help desk widget or a builder: both give you a script to paste. You need one for the custom route, and for anything that reads your booking system or customer records.</p>
<h3>How long does it take to set up?</h3>
<p>The writing takes longest: the price list, hours and rules in plain words. With those ready, a widget or builder can be live the same day. A custom build takes days, with time to test it on real questions.</p>
<p>If you want an AI chatbot or help desk built and set up properly, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>How to migrate from Firebase to Supabase without logging out a single user</title><link>https://tawfik.tv/notes/firebase-to-supabase</link><guid>https://tawfik.tv/notes/firebase-to-supabase</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Import Firebase users with their scrypt password hashes, reshape Firestore into tables, copy Storage, turn on RLS, then cut over with a freeze or dual-write.</description>
<content:encoded><![CDATA[<p>Export your Firebase users with their password hashes and create them through Supabase&rsquo;s admin API, which has checked Firebase&rsquo;s scrypt hashes natively since <a href="https://github.com/supabase/auth/pull/1768">Supabase Auth v2.162.0</a> (September 2024). Every user keeps their password and nobody gets a reset email.</p>
<p>Then reshape Firestore documents into tables, copy Storage, switch on row level security before anyone can reach the API, and cut over with either a short write freeze or a dual-write window.</p>
<p>People are making this move toward a database they like. In the <a href="https://survey.stackoverflow.co/2025/technology">Stack Overflow 2025 Developer Survey</a> (July 2025), 47.2% of developers who used Supabase wanted to keep using it, against 40.1% for Cloud Firestore. PostgreSQL, which Supabase is built on, topped the list at 65.5%.</p>
<p>I have moved apps onto Supabase and fixed database security on live ones. This is the order I use, with the commands, checked against Supabase&rsquo;s <a href="https://supabase.com/docs/guides/platform/migrating-to-supabase/firebase-auth">migration guides</a> and its <a href="https://github.com/supabase-community/firebase-to-supabase">firebase-to-supabase</a> tools.</p>
<h2>What should you inventory before you migrate?</h2>
<p>Write down everything the app touches in Firebase before you write any SQL. The list decides your plan.</p>
<ul>
<li><strong>Users</strong> by sign-in method: email and password, Google, Apple, phone.</li>
<li><strong>Custom claims</strong> such as <code>admin</code> or <code>role</code>.</li>
<li><strong>Collections and subcollections.</strong> The Supabase script lists only top-level collections, so walk the subcollections yourself.</li>
<li><strong>Storage</strong> buckets and the folder pattern, usually <code>users/{uid}/...</code>.</li>
<li><strong>Security rules</strong>, because every rule becomes a Postgres policy.</li>
<li><strong>Cloud Functions, triggers and <code>onSnapshot</code> listeners.</strong> Push messaging can stay on Firebase Cloud Messaging.</li>
</ul>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">git clone https://github.com/supabase-community/firebase-to-supabase.git
cd firebase-to-supabase/firestore
# add firebase-service.json (Firebase console > Project settings > Service accounts)
node collections.js</pre>

<p>Set your app&rsquo;s shape below to get the plan in order, with what goes wrong at each step.</p>
<p><a href="https://tawfik.tv/notes/firebase-to-supabase">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you turn Firestore documents into Postgres tables?</h2>
<p>Design the tables first, as a migration, then load data into them. Firestore rewards copying data into every document that shows it. Postgres rewards storing each fact once and joining.</p>
<ol>
<li>One table per collection. Keep the document ID in a <code>firestore_id text unique</code> column so every row traces back.</li>
<li>Subcollections become child tables with a foreign key to the parent.</li>
<li>Arrays of objects become child tables. Arrays of plain values can stay as <code>text[]</code>.</li>
<li>Maps you filter on become columns. Maps you only display can stay <code>jsonb</code>.</li>
<li>Denormalised copies, such as the author&rsquo;s name on every post, get dropped and replaced by a join.</li>
<li>Firebase user IDs are free-form strings and Supabase user IDs are UUIDs, so keep <code>firebase_uid</code> on the profile and remap every reference through it.</li>
</ol>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">supabase link --project-ref your-project-ref
supabase migration new firebase_schema

-- supabase/migrations/&lt;timestamp&gt;_firebase_schema.sql
create table public.profiles (
  id uuid primary key references auth.users on delete cascade,
  firebase_uid text unique not null,
  display_name text
);
create table public.orders (
  id bigint generated always as identity primary key,
  firestore_id text unique not null,
  user_id uuid not null references public.profiles (id),
  status text not null,
  total_pence integer not null,
  created_at timestamptz not null
);
create table public.order_items (  -- was the items array inside each order
  order_id bigint not null references public.orders (id) on delete cascade,
  sku text not null,
  qty integer not null check (qty &gt; 0)
);
create index on public.orders (user_id);

-- RLS goes in the same migration as the tables, never later
alter table public.profiles enable row level security;
alter table public.orders enable row level security;
alter table public.order_items enable row level security;
revoke all on public.profiles, public.orders, public.order_items from anon, authenticated;
grant select on public.profiles, public.orders, public.order_items to authenticated;
create policy "own profile" on public.profiles for select to authenticated
  using ((select auth.uid()) = id);
create policy "own orders" on public.orders for select to authenticated
  using ((select auth.uid()) = user_id);
create policy "own items" on public.order_items for select to authenticated
  using (exists (select 1 from public.orders o
                 where o.id = order_id and o.user_id = (select auth.uid())));

supabase db push --dry-run
supabase db push</pre>

<h2>How do you migrate Firebase Auth users without resetting passwords?</h2>
<ol>
<li>In the Firebase console, open Authentication, then Users, then the three-dot menu, then <strong>Password hash parameters</strong>. Copy <code>base64_signer_key</code>, <code>base64_salt_separator</code>, <code>rounds</code> and <code>mem_cost</code>. Treat them like a password.</li>
<li>Export the users with the Firebase CLI. Its <a href="https://firebase.google.com/docs/cli/auth"><code>auth:export</code></a> writes each user&rsquo;s <code>passwordHash</code> and <code>salt</code> in standard base64, plus <code>customAttributes</code>, which holds custom claims. Users Firebase imported from elsewhere with another hash come out with an empty hash and will need a reset.</li>
<li>Create each user through the admin API with a <code>password_hash</code> in Supabase&rsquo;s Firebase format. The supabase-js types say <code>password_hash</code> supports bcrypt, Firebase scrypt and argon2.</li>
</ol>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">firebase auth:export users.json --format=json --project your-firebase-project
npm i @supabase/supabase-js

// import-users.mjs   run: node import-users.mjs users.json
import { readFileSync } from 'node:fs';
import { createClient } from '@supabase/supabase-js';

const e = process.env; // SUPABASE_URL, SUPABASE_SECRET_KEY, FB_SIGNER_KEY, FB_SALT_SEPARATOR, FB_ROUNDS, FB_MEM_COST
const sb = createClient(e.SUPABASE_URL, e.SUPABASE_SECRET_KEY, { auth: { persistSession: false } });
const { users } = JSON.parse(readFileSync(process.argv[2], 'utf8'));

for (const u of users) {
  const hash = u.passwordHash &amp;&amp;
    `$fbscrypt$v=1,n=${e.FB_MEM_COST},r=${e.FB_ROUNDS},p=1,ss=${e.FB_SALT_SEPARATOR},sk=${e.FB_SIGNER_KEY}$${u.salt}$${u.passwordHash}`;
  const { error } = await sb.auth.admin.createUser({
    email: u.email,
    phone: u.phoneNumber,
    email_confirm: !!u.emailVerified,
    phone_confirm: !!u.phoneNumber,
    ...(hash &amp;&amp; { password_hash: hash }),
    app_metadata: { firebase_uid: u.localId, ...JSON.parse(u.customAttributes || '{}') },
    user_metadata: { name: u.displayName, avatar_url: u.photoUrl },
  });
  if (error) console.error(u.localId, error.message);
}</pre>

<p>Four things catch people here.</p>
<ul>
<li><strong>Custom claims go in <code>app_metadata</code>.</strong> Users cannot edit it, so policies can trust it through <code>auth.jwt() -&gt; 'app_metadata'</code>. Supabase&rsquo;s <a href="https://supabase.com/docs/guides/database/postgres/row-level-security">RLS guide</a> warns that <code>user_metadata</code> can be changed by the signed-in user.</li>
<li><strong>Google and Apple users need no password.</strong> Supabase <a href="https://supabase.com/docs/guides/auth/auth-identity-linking">links identities automatically</a> when the email matches, so their next Google or Apple sign-in lands on the imported account. Set up those providers in Supabase first.</li>
<li><strong>The older community import script is not the one to use.</strong> <code>import_users.js</code> writes an empty password and copies the whole Firebase record, hash and salt included, into <code>raw_user_meta_data</code>. Users would need a password reset or a separate checking server.</li>
<li><strong>Then fill the profiles table</strong> from <code>auth.users</code>, so every Firebase ID has a Supabase ID to map to.</li>
</ul>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">insert into public.profiles (id, firebase_uid, display_name)
select id, raw_app_meta_data -&gt;&gt; 'firebase_uid', raw_user_meta_data -&gt;&gt; 'name'
from auth.users;</pre>

<h2>How do you move the Firestore data itself?</h2>
<p>Export each collection to JSON, load it raw into a holding table, then reshape it with SQL. Two warnings from reading the export script. It pages with <code>offset</code>, and Firestore <a href="https://firebase.google.com/docs/firestore/pricing">charges a read for every skipped document</a>, so the bill grows with the square of a large collection. And it writes timestamps as <code>{"_seconds": ..., "_nanoseconds": ...}</code> objects. For anything big, export with a cursor and convert as you go.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">// export.mjs   run: node export.mjs orders   (writes orders_raw.json)
import { readFileSync, createWriteStream } from 'node:fs';
import { initializeApp, cert } from 'firebase-admin/app';
import { getFirestore, FieldPath, Timestamp, DocumentReference } from 'firebase-admin/firestore';

initializeApp({ credential: cert(JSON.parse(readFileSync('firebase-service.json', 'utf8'))) });
const plain = v =&gt; v instanceof Timestamp ? v.toDate().toISOString()
  : v instanceof DocumentReference ? v.path
  : Array.isArray(v) ? v.map(plain)
  : v &amp;&amp; v.constructor === Object ? Object.fromEntries(Object.entries(v).map(([k, x]) =&gt; [k, plain(x)]))
  : v;
const name = process.argv[2], out = createWriteStream(`${name}_raw.json`);
let last, n = 0;
out.write('[');
for (;;) {
  let q = getFirestore().collection(name).orderBy(FieldPath.documentId()).limit(1000);
  if (last) q = q.startAfter(last);
  const snap = await q.get();
  if (snap.empty) break;
  for (const d of snap.docs) out.write((n++ ? ',\n' : '\n') + JSON.stringify({ firestore_id: d.id, ...plain(d.data()) }));
  last = snap.docs.at(-1);
}
out.end('\n]\n');
console.log(n, 'documents');</pre>

<p>Load it with the Supabase tool, which creates a table named after the file in <code>public</code> with RLS off. Move it out of the API&rsquo;s reach straight away, reshape, then compare counts.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">node json2supabase.js ./orders_raw.json

create schema if not exists staging;
alter table public.orders_raw set schema staging;

insert into public.orders (firestore_id, user_id, status, total_pence, created_at)
select r.firestore_id, p.id, r.status, round(r.total * 100), r.created_at::timestamptz
from staging.orders_raw r
join public.profiles p on p.firebase_uid = r.uid;

insert into public.order_items (order_id, sku, qty)
select o.id, i -&gt;&gt; 'sku', (i -&gt;&gt; 'qty')::int
from staging.orders_raw r
join public.orders o using (firestore_id)
cross join jsonb_array_elements(r.items) i;

select (select count(*) from staging.orders_raw) as firestore,
       (select count(*) from public.orders) as postgres;</pre>

<p>If the two counts differ, the join dropped rows, usually orders whose user no longer exists. Find them before cutover, not after. The functions used are in the <a href="https://www.postgresql.org/docs/current/functions-json.html">Postgres JSON docs</a>.</p>
<h2>How do you move Firebase Storage?</h2>
<p><code>node download.js "" downloads</code> pulls the bucket to disk and <code>node upload.js "" downloads avatars</code> pushes it to a Supabase bucket, which the tool <a href="https://supabase.com/docs/guides/platform/migrating-to-supabase/firebase-storage">creates as private</a>. Two follow-ups: rewrite any <code>firebasestorage.googleapis.com</code> links saved inside your documents, and write <a href="https://supabase.com/docs/guides/storage/security/access-control">storage policies</a>. If your paths look like <code>users/{uid}/...</code> with the Firebase user ID, match the folder against the ID you imported.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">create policy "read own files" on storage.objects for select to authenticated
using (bucket_id = 'avatars'
  and (storage.foldername(name))[2] = (select auth.jwt() -&gt; 'app_metadata' -&gt;&gt; 'firebase_uid'));</pre>

<h2>Why must row level security be on before go-live?</h2>
<p>Firebase blocks a client that has no matching rule. Supabase works the other way round. Its <a href="https://supabase.com/docs/guides/database/postgres/row-level-security">RLS guide</a> says a table in an exposed schema without RLS is readable and writable by any role with a grant on it, and the publishable key shipped in your app makes requests as the <code>anon</code> role, which on many projects still holds those grants. In March 2025 a researcher scanned 1,645 apps featured by the Lovable app builder and found 170 of them exposing data through insufficient RLS (<a href="https://mattpalmer.io/posts/statement-on-CVE-2025-48757/">his write-up</a>, filed as <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-48757">CVE-2025-48757</a>). Write a policy test with <code>supabase test db</code>, and run the <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a> before the switch.</p>
<p>If you used <code>onSnapshot</code>, add each table to the <code>supabase_realtime</code> publication. Supabase&rsquo;s <a href="https://supabase.com/docs/guides/realtime/postgres-changes">Realtime docs</a> say RLS is not applied to delete events, and suggest Broadcast past about 3,000 subscribers on the same changes.</p>
<h2>Freeze-and-cut or dual-write?</h2>
<p><strong>Freeze-and-cut</strong> suits most apps that can take an hour of maintenance. Announce it, make Firestore read-only with rules (<code>allow write: if false;</code>), pause Cloud Functions too because the Admin SDK ignores rules, export the final state, import, check counts, ship the app config that points at Supabase, reopen.</p>
<p><strong>Dual-write</strong> is for apps that cannot stop, and for mobile apps where old versions keep talking to Firebase for weeks. New code writes to both, a backfill copies history, a nightly job compares counts, reads switch once the numbers match, and Firebase writes stop last. It costs more code and every write path has to be found.</p>
<p><strong>Rollback.</strong> Keep the Firebase project untouched and read-only for at least a month. Keep the previous app build ready to point back. Anyone who signs up or changes their password after cutover exists only in Supabase, so export them before you roll back.</p>
<h2>How do you fix a broken Supabase migration history?</h2>
<p>It breaks when someone changes the schema in the dashboard, renames a migration file, or a push fails halfway. <code>supabase db push</code> then stops with &ldquo;Remote migration versions not found in local migrations directory.&rdquo; The <a href="https://supabase.com/docs/reference/cli/supabase-migration-repair">CLI reference</a> fix: compare, mark, pull.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">supabase migration list                       # LOCAL vs REMOTE, by timestamp

# remote has a version you don't have locally: drop it from the history
supabase migration repair 20260101120000 --status reverted
supabase db pull                              # capture the real schema as a new file

# you ran a local file by hand: record it as applied without running it again
supabase migration repair 20260102090000 --status applied

supabase db push --dry-run</pre>

<p><code>repair</code> only edits the history table, <code>supabase_migrations.schema_migrations</code>. It never changes your schema, which is why it is safe and why it is not a fix on its own.</p>
<h2>Questions people ask</h2>
<h3>Can I migrate Firebase Auth to Supabase without password resets?</h3>
<p>Yes. Export users with <code>firebase auth:export</code>, then create them with <code>auth.admin.createUser</code> and a <code>password_hash</code> in the <code>$fbscrypt$</code> format built from your project&rsquo;s hash parameters.</p>
<h3>How long does a Firebase to Supabase migration take?</h3>
<p>It depends on the number of collections and write paths more than on the number of users. A full rehearsal on a staging project tells you the real cutover time.</p>
<h3>Do I keep my Firebase user IDs?</h3>
<p>Not as the primary key, because Supabase user IDs are UUIDs. Keep the old ID in <code>app_metadata</code> and on the profiles table, and remap references through it.</p>
<h3>What is supabase migration repair for?</h3>
<p>Fixing the migration history table when it no longer matches your migration files. It marks versions applied or reverted without running any SQL.</p>
<h3>Do I need a database migration consultant or database migration services?</h3>
<p>For a small app, this page is enough. For live payments, many write paths, or a mobile app that cannot stop, an outside review of the cutover and the policies is cheap insurance. More on how I work as a <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer</a>, and on <a href="https://tawfik.tv/notes/ai-agent-deleted-database">keeping AI agents away from your production database</a>.</p>
<p>If you need a migration like this planned or done, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>How much does a fractional CTO cost? UK, US and Gulf rates, and when full time is cheaper</title><link>https://tawfik.tv/notes/fractional-cto-cost</link><guid>https://tawfik.tv/notes/fractional-cto-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Fractional CTOs and CPOs charge about £1,200 to £3,000 a day in the UK and $1,500 to $4,000 in the US. Past 2 to 3 days a week, full time can cost less.</description>
<content:encoded><![CDATA[<p>A fractional CTO or CPO costs about £1,200 to £3,000 a day in the UK and $1,500 to $4,000 a day in the US. On a monthly retainer, a fractional CTO runs about £6,000 to £16,000 a month in the UK and $9,000 to $22,000 in the US.</p>
<p>Days per week set most of the bill, and somewhere between two and four days a week a full-time hire becomes the cheaper option.</p>
<p>Those ranges come from a fractional executive marketplace&rsquo;s <a href="https://fractionus.com/blog/fractional-executive-rates-by-role">April 2026 rate guide</a>. The open contract market can sit lower: UK contract CTO roles advertised in the six months to 15 October 2026 had a median day rate of £635, down from £900 a year earlier, from a small sample of 13 quoted rates (<a href="https://www.itjobswatch.co.uk/contracts/uk/chief%20technology%20officer.do">IT Jobs Watch</a>).</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I have been a CTO, and I take fractional work. Everything below is published market data, not my rates.</p>
<h2>Fractional CTO vs fractional CPO vs head of product: what is the difference?</h2>
<ul>
<li><strong>Fractional CTO.</strong> Owns how the product is built and run: the architecture, the stack, security basics, delivery and the first engineering hires.</li>
<li><strong>Fractional CPO.</strong> Owns what gets built and why: the one number the product has to move, the roadmap and its no list, and how the product team ships.</li>
<li><strong>Fractional head of product.</strong> Runs the backlog and discovery day to day: specs, customer interviews and priorities with engineering, usually reporting to a founder.</li>
</ul>
<p>Early teams often need parts of the first two at once. I cover the CPO work fully and the CTO parts an early team needs: more on my <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO page</a>.</p>
<h2>How much does a fractional CTO cost in the UK, US and Gulf?</h2>
<p><strong>United Kingdom</strong></p>
<ul>
<li>Senior fractional executives: £1,200 to £3,000 a day (<a href="https://fractionus.com/blog/fractional-executive-rates-by-role">Fractionus, April 2026</a>).</li>
<li>Fractional CTO retainers: £6,000 to £16,000 a month (same guide).</li>
<li>Contract CTO roles: median £635 a day, six months to 15 October 2026 (<a href="https://www.itjobswatch.co.uk/contracts/uk/chief%20technology%20officer.do">IT Jobs Watch</a>).</li>
<li>Contract head of product management roles: median £1,038 a day, from only 4 quoted rates (<a href="https://www.itjobswatch.co.uk/contracts/uk/head%20of%20product%20management.do">IT Jobs Watch</a>).</li>
</ul>
<p><strong>United States</strong></p>
<ul>
<li>Senior fractional executives: $1,500 to $4,000 a day (<a href="https://fractionus.com/blog/fractional-executive-rates-by-role">Fractionus, April 2026</a>).</li>
<li>Fractional CTO retainers: $9,000 to $22,000 a month (same guide).</li>
<li>Average day rate on one marketplace&rsquo;s bench, as of 15 October 2026: $1,615 for a fractional CTO across 79 rates (<a href="https://fractionus.com/markets/rates/cto">CTO rate index</a>) and $1,576 for a fractional CPO across 60 rates (<a href="https://fractionus.com/markets/rates/cpo">CPO rate index</a>).</li>
</ul>
<p><strong>The Gulf</strong></p>
<ul>
<li>I found no published day-rate benchmark for fractional CTOs or CPOs in the Gulf that I could verify.</li>
<li>A UAE fractional firm <a href="https://www.consultancy-me.com/news/13854/rhys-holding-and-sam-loyd-on-the-rise-of-fractional-leadership-in-the-uae">told Consultancy-me</a> in July 2026 that fractional leadership typically costs 30% to 60% less than the full-time equivalent. That is a seller&rsquo;s estimate, not market data.</li>
<li>For the full-time side: a CTO in the UAE averages AED 426,758 a year in base salary, from 48 salary profiles updated January 2026 (<a href="https://www.payscale.com/research/AE/Job=Chief_Technology_Officer_(CTO)/Salary">Payscale</a>).</li>
</ul>
<p>A warning on comparing guides: a &ldquo;CPO&rdquo; retainer in some rate tables is a chief people officer, the HR role. Check which one a number is for before you use it.</p>
<h2>Draft it: what does your engagement cost?</h2>
<p>Pick the role, the days a week, the region and the term. The statement of work below fills in the scope, the fees from the published rates above, the cost of the same person full time, and where the two cross.</p>
<p><a href="https://tawfik.tv/notes/fractional-cto-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>What do fractional CTO services include at one, two, three or four days a week?</h2>
<p>Most fractional engagements run one to three days a week, which a marketplace counts as roughly four to twelve days a month (<a href="https://fractionus.com/markets/rates/cto">Fractionus</a>). Here is what each step buys, from how I run my own engagements.</p>
<ol>
<li><strong>One day a week: direction.</strong> A weekly review, the decisions written down with the reason, the roadmap or technical plan on one page, and help with the key hire. Someone else runs the work day to day.</li>
<li><strong>Two days a week: ownership.</strong> The roadmap or the release process becomes theirs. Add customer discovery for a CPO, or environments, CI and an incident routine for a CTO, and a prototype of the first slice.</li>
<li><strong>Three days a week: hands on.</strong> Building the hardest part with the team, running planning, and managing the first hires until a full-time lead arrives.</li>
<li><strong>Four days a week: price a full-time hire too.</strong> At this load you are paying for most of a job. The break-even below usually says so.</li>
</ol>
<h2>When is a full-time hire cheaper than a fractional one?</h2>
<p>Work out the full cost of the full-time hire, then divide it by what the fractional lead charges for the same days.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">break-even days a week = full-time cost a year ÷ (day rate × 48)

UK CTO: £100,000 salary + £14,250 employer NI + £1,321 pension = £115,571
        £115,571 ÷ (£1,200 × 48) = 2.0 days a week

US CTO: $175,140 salary ÷ 0.70 (benefits are 30% of employer cost) = $250,200
        $250,200 ÷ ($1,500 × 48) = 3.5 days a week
        $250,200 ÷ ($4,000 × 48) = 1.3 days a week</pre>

<p>The 48 is one day a week at about four days a month for 12 months. The inputs:</p>
<ul>
<li><strong>UK salary:</strong> the median advertised CTO salary was £100,000 in the six months to 15 October 2026, from 58 salaries (<a href="https://www.itjobswatch.co.uk/jobs/uk/chief%20technology%20officer.do">IT Jobs Watch</a>). For product leaders, product director roles had a median of £130,000 from 31 salaries (<a href="https://www.itjobswatch.co.uk/jobs/uk/product%20director.do">IT Jobs Watch</a>).</li>
<li><strong>UK employer costs:</strong> National Insurance at 15% above £5,000 a year for 2026 to 2027 (<a href="https://www.gov.uk/guidance/rates-and-thresholds-for-employers-2026-to-2027">GOV.UK</a>), and a pension of at least 3% on earnings from £6,240 to £50,270 (<a href="https://www.gov.uk/workplace-pensions/what-you-your-employer-and-the-government-pay">GOV.UK</a>).</li>
<li><strong>US salary:</strong> the median for computer and information systems managers, a group that includes CTOs, was $175,140 in May 2025 (<a href="https://www.bls.gov/ooh/management/computer-and-information-systems-managers.htm">BLS</a>). Heads of product had a median advertised salary of $250,000 across 178 job postings in June 2026 (<a href="https://www.recruitingfromscratch.com/blog/head-of-product-salary-in-2026-real-data-from-1-9-million-job-postings">Recruiting from Scratch</a>).</li>
<li><strong>US employer costs:</strong> benefits were 30.0% of private-industry employer compensation costs in June 2026 (<a href="https://www.bls.gov/news.release/ecec.nr0.htm">BLS</a>).</li>
<li><strong>UAE employer costs:</strong> end-of-service gratuity of 21 days&rsquo; basic pay for each of the first five years of service, under Federal Decree-Law No. 33 of 2021 (<a href="https://www.morganlewis.com/pubs/2021/12/united-arab-emirates-updates-federal-labour-law">Morgan Lewis</a>).</li>
</ul>
<p>This leaves out recruiter fees, equity and the months a search takes, which favour fractional, and what a full-time person learns by being there every day, which favours full time.</p>
<h2>Do fractional CTOs and CPOs take equity?</h2>
<p>Some do, usually a small grant alongside a lower cash fee. I found no reliable published benchmark for the size, so I give no number. If you offer equity, make it a separate grant that vests over the engagement.</p>
<h2>How long does a fractional engagement last?</h2>
<p>Fractional work is part time and ongoing, over months. An interim CPO is different: full time and temporary, usually covering an empty seat for four to sixteen months (<a href="https://fractionus.com/hire/product">Fractionus</a>).</p>
<p>Mine follow one shape: a one-page brief in week one, a working prototype on real data in month one, hardening and shipping in months two and three, then month to month until a date we set at the start, with a handover.</p>
<h2>How do you evaluate a fractional CTO or CPO?</h2>
<ol>
<li><strong>Ask for something they shipped that you can open.</strong> A live product, a demo you can press, a repo. I keep mine on <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">what a forward deployed engineer does</a>.</li>
<li><strong>Ask who writes the code.</strong> Some only advise. If you need a first version built, check they build.</li>
<li><strong>Ask for the week-one output.</strong> A good one can tell you what you will hold after five days: a one-page brief, the one number, what to cut.</li>
<li><strong>Ask how it ends.</strong> The answer should name a handover and the hire who takes over.</li>
<li><strong>Call two founders they worked for.</strong> Ask what changed, and what broke after they left.</li>
<li><strong>Start with a short, fixed scope.</strong> A few weeks with a clear output tells you more than any interview.</li>
</ol>
<h2>What are the red flags?</h2>
<ul>
<li>A day rate with no scope behind it.</li>
<li>A long minimum term before you have seen any work.</li>
<li>Asking for production admin keys in week one. Access should grow with trust, and AI tools need the same limits as people: <a href="https://tawfik.tv/notes/ai-agent-deleted-database">your AI coding agent can delete your database</a>.</li>
<li>No written handover plan.</li>
<li>Four or five days a week, sold as fractional. That is a full-time job at contractor rates.</li>
</ul>
<h2>Questions people ask</h2>
<h3>How much does a fractional CTO cost per month?</h3>
<p>In April 2026 market data, fractional CTO retainers ran about £6,000 to £16,000 a month in the UK and $9,000 to $22,000 a month in the US. Days per week drive most of the difference.</p>
<h3>What does a fractional head of product cost?</h3>
<p>UK contract head of product management roles had a median of £1,038 a day in the six months to 15 October 2026, from a small sample of 4 rates. I found no reliable US figure.</p>
<h3>Fractional CTO vs full time: which is cheaper?</h3>
<p>Fractional is usually cheaper at one or two days a week. In the UK, at £1,200 a day, a full-time CTO at the median salary becomes cheaper from about two days a week. At US rates of $1,500 to $4,000 a day, the crossover sits between about 1.3 and 3.5 days.</p>
<h3>Can one person be your fractional CTO and CPO?</h3>
<p>For an early team, often yes: one person sets what to build and how, and builds the first version. For a large engineering organisation, hire a full-time CTO. I wrote about how far one person with AI can go in <a href="https://tawfik.tv/notes/one-person-ai-team">can one person with AI do a whole team&rsquo;s work</a>.</p>
<p>If you need a product led and built part time, write to m@tawfik.tv or start at the <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO page</a>.</p>]]></content:encoded></item><item><title>How to prove you’re over 18 without showing your ID</title><link>https://tawfik.tv/notes/prove-age-without-id</link><guid>https://tawfik.tv/notes/prove-age-without-id</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Let someone you trust check your ID once, then show each website one signed answer, &quot;over 18: yes&quot;, or a zero-knowledge proof of it. Nothing else.</description>
<content:encoded><![CDATA[<p>You prove your age once to someone you trust, like a bank, a government or a wallet on your phone, and from then on each website gets one signed answer: over 18, yes. With a zero-knowledge proof, the website can check that answer is real without learning your name, your birth date or which card it came from.</p>
<p>The UK is now running this at scale. Ofcom&rsquo;s <a href="https://assets.publishing.service.gov.uk/media/6a5770ae6d6d5c7e2845c9d0/Web-_accessible_Report_on_the_use_of_age_assurance_1.pdf">report to Parliament, published 16 July 2026</a>, counted over 69 million age checks between July and December 2025 across the 32 services it analysed, a 23-fold jump on the six months before. Facial age estimation was the method most offered, then photo ID matching.</p>
<p>Most of those checks still move far more than one fact. I&rsquo;ve built identity products three times around one rule: prove the fact, not the person. The long version, with the three builds, is in <a href="https://tawfik.tv/notes/prove-the-fact">How to prove who someone is without seeing who they are</a>. This is the short one for age.</p>
<h2>How does age verification work in the UK?</h2>
<p>The Online Safety Act makes two groups of services check age.</p>
<ol>
<li><strong>Sites that publish porn themselves.</strong> Their duty to use age checks <a href="https://www.gov.uk/government/publications/online-safety-act-explainer/online-safety-act-explainer">came into force on 17 January 2025</a>.</li>
<li><strong>Sites and apps where users share content</strong> that children are likely to use. Since July 2025, if they allow porn or content about suicide, self-harm or eating disorders, they must keep children away from it. Ofcom says most of the services it studied switched age checks on around 25 July 2025.</li>
</ol>
<p>The check has to be &ldquo;highly effective&rdquo;. Ofcom judges that on four things: technical accuracy, robustness, reliability and fairness. Ticking a box that says &ldquo;I&rsquo;m 18&rdquo; does not count. Services that get it wrong can be <a href="https://www.gov.uk/government/publications/online-safety-act-explainer/online-safety-act-explainer">fined up to £18 million or 10% of their qualifying worldwide revenue</a>, whichever is greater.</p>
<h2>What age verification methods does Ofcom accept?</h2>
<p>Ofcom lists seven methods it considers capable of being highly effective. The list is not closed, and each one still has to be done well. Here they are, with what leaves your phone.</p>
<ol>
<li><strong>Open banking.</strong> You log in to your bank and agree to share details with an age checking company, which tells the site yes or no.</li>
<li><strong>Photo ID matching.</strong> You upload a passport or driving licence and a selfie. The whole ID page goes.</li>
<li><strong>Facial age estimation.</strong> Software guesses your age from a selfie. Your face goes, unless the guess runs on your phone.</li>
<li><strong>Mobile network checks.</strong> Your mobile network says whether your account belongs to an adult. The site gets a yes or no.</li>
<li><strong>Credit card checks.</strong> Only adults can get a UK credit card, so a valid one is the signal.</li>
<li><strong>Email-based age estimation.</strong> Software looks at where your email address has been used before, such as with banks, and estimates your age from that.</li>
<li><strong>Digital identity services.</strong> A wallet or app that already checked you sends the answer. This is where selective disclosure and zero-knowledge proofs live.</li>
</ol>
<p>Privacy is part of the job too. Ofcom&rsquo;s report says services must follow UK data protection law, and found many delete the data straight away. Others keep it for a while: one third-party face check kept face images and ID documents for up to an hour. Two social media services ran the face check on the phone, so only a pass or fail left it.</p>
<h2>What does each method give away?</h2>
<p>The answer changes with the question: a face can say &ldquo;probably over 18&rdquo;, never where you live. You are the website.</p>
<p><a href="https://tawfik.tv/notes/prove-age-without-id">Open the interactive diagram on tawfik.tv</a></p>

<p>The pattern matches <a href="https://tawfik.tv/notes/prove-the-fact">my longer piece</a>. A photo of your ID sends everything printed on it, and anything stored can leak: Discord said <a href="https://discord.com/press-releases/update-on-security-incident-involving-third-party-customer-service">about 70,000 users may have had government ID photos exposed</a> through a customer service vendor that used them to review age appeals. A signed credential sends one line. A zero-knowledge proof sends a proof that the line is true, and nothing else.</p>
<h2>How does a zero-knowledge proof prove your age?</h2>
<p>Picture a busy page with one character hidden on it. You lay a big sheet of card over the page with one small hole, right on the character. Your friend sees you found it and learns nothing about where it is on the page. That&rsquo;s a zero-knowledge proof. Software does it with maths instead of card.</p>
<p>For age, it runs in four steps.</p>
<ol>
<li><strong>Checked once.</strong> A trusted issuer, like a government, a bank or a phone wallet provider, checks your ID one time and gives your phone a signed card.</li>
<li><strong>The site asks one question.</strong> Over 18?</li>
<li><strong>Your phone makes a proof.</strong> It says: &ldquo;I hold a card signed by a real issuer, and it says I&rsquo;m over 18.&rdquo; The card itself never leaves the phone.</li>
<li><strong>The site checks the maths.</strong> It gets yes or no. It never sees your name, birth date or card, and each proof looks new, so two sites can&rsquo;t match you by it.</li>
</ol>
<p>Google open-sourced <a href="https://blog.google/technology/safety-security/opening-up-zero-knowledge-proof-technology-to-promote-privacy-in-age-assurance/">its zero-knowledge libraries for age checks</a> in July 2025, with the example of proving you&rsquo;re over 18 &ldquo;without sharing anything else at all&rdquo;.</p>
<p>What a proof does not hide: your internet address, your device, and a site that asks for more than it needs. The <a href="https://www.eff.org/deeplinks/2025/07/zero-knowledge-proofs-alone-are-not-digital-id-solution-protecting-user-privacy">EFF makes that point well</a>.</p>
<h2>What is selective disclosure, and how is it different?</h2>
<p>Selective disclosure is the step before zero-knowledge. The issuer seals each line of your credential in its own envelope, mixes in a random value so nobody can guess what&rsquo;s inside, and signs the list of sealed envelopes. You open only the line you need, say &ldquo;over 18&rdquo;, and the site checks it matches the signed list.</p>
<ul>
<li><strong>SD-JWT</strong>, the internet standard <a href="https://www.rfc-editor.org/rfc/rfc9901.html">RFC 9901</a>, published November 2025, works this way.</li>
<li><strong>Mobile driving licences</strong> under ISO/IEC 18013-5 use <a href="https://learn.mattr.global/docs/concepts/mdocs">the same salted-hash trick</a>, so a holder can show proof of age without the rest of the licence.</li>
<li><strong>W3C Verifiable Credentials 2.0</strong>, <a href="https://www.w3.org/TR/vc-data-model-2.0/">a W3C Recommendation since May 2025</a>, names the roles: issuer, holder, verifier.</li>
</ul>
<p>The catch: show the same signed card to two sites and they can link you, because the signature is identical. RFC 9901 <a href="https://www.rfc-editor.org/rfc/rfc9901.html#name-unlinkability">says so in section 10.1</a> and gives the fix: the issuer hands out a batch of fresh copies, one per site. Flip that switch in the demo above to see it.</p>
<h2>What is the EU doing about age verification?</h2>
<p>The EU went straight for this design. Its <a href="https://digital-strategy.ec.europa.eu/en/factpages/blueprint-age-verification-solution-help-protect-minors-online">age verification blueprint</a> came out in July 2025 as open-source tools. The second version, in October 2025, added passports and ID cards as a way to get a proof of age, and included zero-knowledge proofs. Denmark, France, Greece, Italy and Spain are building national apps on it, and the Commission says the proof of age carries no ID details that trace back to you.</p>
<p>It&rsquo;s built to work with the <a href="https://digital-strategy.ec.europa.eu/en/policies/eudi-regulation">EU Digital Identity Wallets</a> that member states must offer their citizens by the end of 2026.</p>
<h2>How much does age verification cost?</h2>
<p>For most services, a few pence a check. Ofcom&rsquo;s <a href="https://assets.publishing.service.gov.uk/media/6a5770ae6d6d5c7e2845c9d0/Web-_accessible_Report_on_the_use_of_age_assurance_1.pdf">July 2026 report</a> worked out what the services it studied paid on average per check: a median of around £0.06, most at or below £0.10, and none above £0.30, the top of the £0.05 to £0.30 range Ofcom had estimated in April 2025.</p>
<p>The other costs, from the same report:</p>
<ul>
<li><strong>Set-up.</strong> Where services reported it, mostly tens of thousands of pounds, for IT integration, engineering, testing and user support. A few reported none, because they already had a vendor or had rolled checks out in other countries.</li>
<li><strong>Digital ID.</strong> Twelve of the services offered digital ID checks, and generally reported them as free to the service. Two reported minimal costs.</li>
<li><strong>Lost visitors.</strong> Traffic to porn services fell sharply once checks went live, and Ofcom counts the lost revenue as a cost.</li>
<li><strong>Checking the same person twice.</strong> A service that can&rsquo;t recognise returning users may need to check them again, which makes the price per check matter more.</li>
</ul>
<p>Ofcom adds that the average price per check often falls as volume grows, because vendors sell on fixed fees, subscriptions and volume tiers.</p>
<h2>What do age and KYC verification providers charge?</h2>
<p>A few publish their prices. These are list prices from their own pages, checked on 15 October 2026, before volume discounts.</p>
<ol>
<li><strong><a href="https://didit.me/pricing">Didit</a>:</strong> age estimation from a selfie, with a liveness check, is $0.10 a check. A full ID check (document, liveness, face match) is $0.33, and the first 500 every month are free. No monthly minimum.</li>
<li><strong><a href="https://www.veriff.com/pricing">Veriff</a>:</strong> Essential is $0.80 a verification with a $49 monthly minimum. Plus is $1.39 with a $99 minimum, and Premium $1.89 with a $209 minimum; both add specialist review.</li>
<li><strong><a href="https://sumsub.com/pricing/">Sumsub</a>:</strong> Basic is $1.35 a verification with a $149 monthly minimum. Compliance, which adds AML screening, is $1.85 with a $299 minimum.</li>
<li><strong><a href="https://stripe.com/identity">Stripe Identity</a>:</strong> $1.50 for an ID document and selfie check, charged when the user completes it.</li>
<li><strong><a href="https://ondato.com/pricing/">Ondato</a>:</strong> identity verification from €1.40 down to €0.50 a check, depending on volume.</li>
</ol>
<p>Yoti does not publish prices on <a href="https://www.yoti.com/business/age-verification/">its age verification page</a>; you ask its sales team.</p>
<p>Most of these are full identity checks, built for KYC: they confirm who someone is. An age gate needs one fact, so running full KYC on every visitor buys more data than you need, at a higher price. Watch the minimums too: at 30 checks a month, a $149 minimum works out at about $4.97 a check.</p>
<p><a href="https://tawfik.tv/notes/prove-age-without-id">Open the interactive diagram on tawfik.tv</a></p>

<h2>Which KYC or age verification software is best?</h2>
<p>The one that answers your question with the least data, at your volume. Five things I check before picking one.</p>
<ol>
<li><strong>Do you need to know who, or only how old?</strong> If the question is over 18, a face estimate or a digital ID answer is enough. The worked example in Ofcom and the ICO&rsquo;s <a href="https://ico.org.uk/media2/5ybpmabf/ofcom-ico-joint-statement.pdf">joint statement of 25 March 2026</a> collects only the information strictly necessary to confirm a user&rsquo;s age or age range. Full KYC is for when you must know the person, such as when money moves.</li>
<li><strong>What does it cost at your volume?</strong> Price per check, plus the monthly minimum, minus any free allowance. Run your own numbers in the bill above.</li>
<li><strong>Can people come back without another check?</strong> Keep the yes on their account, as in <a href="https://tawfik.tv/notes/prove-the-fact">prove the fact, not the person</a>, or accept a reusable digital ID.</li>
<li><strong>What does the vendor keep, and for how long?</strong> The same statement&rsquo;s example tells users what is collected and how long it is stored. Get both in writing before you sign.</li>
<li><strong>Can a wrongly blocked adult appeal?</strong> The example also gives users a prominent way to challenge a wrong age decision.</li>
</ol>
<p>If you keep that yes in your own database, lock the table down. My <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a> is how I check access rules on tables like that.</p>
<h2>What I&rsquo;d build if your site needs age checks</h2>
<p>I led a credential product where nurses and doctors prove their licence to employers. The licence is checked once at the source and sealed to the professional&rsquo;s own key, and they tick which fields each employer gets. Unticked fields are removed before anything leaves the phone. The gap I&rsquo;d close next time: the issuer signed the whole licence, so a partial share couldn&rsquo;t be checked line by line. SD-JWT fixes that, so I&rsquo;d start there.</p>
<p>At PLAYERUNKNOWN Productions I designed a zero-knowledge ID for players: the game learns a player is real, and a tag catches a second account, without learning who they are.</p>
<p>For age checks, the same rules carry over.</p>
<ol>
<li><strong>Ask for one fact.</strong> Over 18, not a birth date.</li>
<li><strong>Don&rsquo;t hold what you don&rsquo;t need.</strong> Keep the yes, delete the rest.</li>
<li><strong>Never call the issuer at check time.</strong> Check the signature against a published key, so the issuer never learns where you went.</li>
<li><strong>Give fresh copies,</strong> or use proofs, so sites can&rsquo;t link people.</li>
<li><strong>Say what still shows.</strong> Internet address, device, account.</li>
</ol>
<h2>Questions people ask</h2>
<h3>Is zero-knowledge age verification allowed under the Online Safety Act?</h3>
<p>Ofcom&rsquo;s guidance is technology-neutral and lists digital identity services among the methods capable of being highly effective. A zero-knowledge proof is one way a digital identity service can deliver the answer. It still has to meet Ofcom&rsquo;s four criteria: accuracy, robustness, reliability and fairness.</p>
<h3>Do age checks keep my ID or my face?</h3>
<p>Some do, for a while, as Ofcom found above. Before you upload, ask who keeps the photo, for how long, and which vendors see it.</p>
<h3>What&rsquo;s the difference between age verification and age estimation?</h3>
<p>Verification checks a record: your ID, your bank, your mobile account. Estimation makes a guess, from your face or your email history. A guess is surest far from the age line. Every porn service Ofcom studied offered more than one method, three on average.</p>
<h3>Can a website track me if I use a zero-knowledge proof?</h3>
<p>Not through the proof, since each one looks new. It can still see your internet address, your device and your account.</p>
<h3>Can I prove my age once and reuse it?</h3>
<p>Yes, with a digital identity wallet, and Ofcom&rsquo;s report notes reuse may cut costs. To keep it private, the wallet needs fresh copies per site or zero-knowledge proofs.</p>
<h3>How much does an age check cost per user?</h3>
<p>Ofcom found the services it studied paid a median of around £0.06 a check, most at or below £0.10. Public list prices run from $0.10 for a selfie age estimate to $1.50 for an ID and selfie check, and monthly minimums raise the cost per check at low volume.</p>
<h3>Do you build an age verification service?</h3>
<p>Yes. I design and build identity and credential products end to end, as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> or hands on. If you need privacy-preserving age checks built, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>Unity WebGL on mobile: how I took a 650 MB model to a 74 MB build at 60 fps</title><link>https://tawfik.tv/notes/unity-webgl-mobile</link><guid>https://tawfik.tv/notes/unity-webgl-mobile</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Unity WebGL builds are big and slow on phones because of triangles, textures, live lights, draw calls and code. Fix those, then Brotli and headers.</description>
<content:encoded><![CDATA[<p>A Unity WebGL build is big and slow on a phone for five reasons: too many triangles, textures in the wrong format, lights worked out live every frame, too many draw calls, and engine code nobody uses, all downloaded before the first frame. Fix them in that order, then compress the build with Brotli and serve it with the right headers.</p>
<p>That is the route I took with <a href="https://tawfik.tv/projects/seven-al-hamra">SEVEN Al Hamra</a>: a 650 MB construction model that became a 74 MB browser build drawing about 700,000 triangles at 60 fps on a laptop graphics chip. You can <a href="https://tawfik.tv/worlds/rvt">walk through it now</a>.</p>
<p>For scale: the median mobile home page in July 2025 weighed 2.6 MB, according to the <a href="https://almanac.httparchive.org/en/2025/page-weight">HTTP Archive Web Almanac 2025</a>. My finished build is still about 28 times that, so every megabyte you cut is one a visitor on mobile data does not wait for.</p>
<h2>Why are Unity WebGL builds so big and slow on phones?</h2>
<p>Four things stack up against you in a phone browser.</p>
<ul>
<li><strong>One big download.</strong> Unity packs every scene and asset into a <code>.data</code> file. The browser unpacks it into memory and keeps the uncompressed data there while the content runs (<a href="https://docs.unity3d.com/Manual/webgl-memory.html">Unity: memory in Unity Web</a>). Phones have the least memory to spare.</li>
<li><strong>A heap that has to grow in one piece.</strong> Unity&rsquo;s heap is one contiguous block. If the browser cannot find a big enough block when it grows, the app crashes, so Unity&rsquo;s advice is to keep the heap as small as possible.</li>
<li><strong>Slow draw calls.</strong> Sending work to WebGL costs more CPU time than native OpenGL, so Unity recommends avoiding large numbers of draw calls per frame and using batching and instancing (<a href="https://docs.unity3d.com/Manual/webgl-performance.html">Unity: Web performance</a>).</li>
<li><strong>The wrong texture format.</strong> If a phone does not support the format you built with, Unity decompresses the textures in software at runtime. It still works, with more memory and a slower frame (<a href="https://docs.unity3d.com/Manual/webgl-texture-compression.html">Unity: texture compression in Web</a>).</li>
</ul>
<p>Construction models make all four worse. They hold everything the builders need, including what sits inside ceilings, walls and floors, at a level of detail no browser needs.</p>
<h2>Try it: the six fixes on the Al Hamra build</h2>
<p>The build report below starts at the 650 MB source model. Tick each fix and watch the download and the frame time move. The start and the end are real; the steps between are illustrative.</p>
<p><a href="https://tawfik.tv/notes/unity-webgl-mobile">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do I make a Unity WebGL build smaller and faster?</h2>
<p>This is the order I work in. Each step makes the next one cheaper.</p>
<p><strong>1. Leave out what nobody sees.</strong> Sort every object by discipline and drop what is hidden. On Al Hamra the web version leaves out 758 objects: cable trays, ducts, plumbing, sprinkler pipes, plant units and emergency lights.</p>
<p><strong>2. Decimate the heavy meshes.</strong> Merge parts, delete hidden faces and reduce triangles where nobody will notice, in Blender or your modelling tool. The decorative canopy on Al Hamra was about 43 million triangles in the source. The whole building in the browser today draws about 700,000 at once.</p>
<p><strong>3. Add levels of detail.</strong> A LOD Group swaps a lighter mesh in as the camera moves away, so distant objects cost less.</p>
<p><strong>4. Compress textures for the device.</strong> Unity&rsquo;s Web build settings offer DXT, which suits desktop browsers, and ASTC and ETC2, which suit phones (<a href="https://docs.unity3d.com/Manual/web-build-settings.html">Unity: Web build settings</a>). Unity suggests making two builds, DXT for desktop and ASTC for mobile, and loading the right one. For mobile it suggests ASTC 8x8 blocks as a balance of quality and download size (<a href="https://docs.unity3d.com/Manual/web-optimization-mobile.html">Unity: optimise for mobile</a>).</p>
<p><strong>5. Bake the light.</strong> Baked lighting works out light and shadow once, ahead of time, and saves it into lightmaps, so the phone does not have to. The lightmaps add to the download; the frame gets much cheaper. Al Hamra has two baked sets, day and night, a switch between them, and reflection probes for glass and polished floors.</p>
<p><strong>6. Batch the draw calls.</strong> In the Universal Render Pipeline, keep the SRP Batcher on, share materials, and use GPU instancing for repeated objects. The live Al Hamra build runs with the SRP Batcher.</p>
<p><strong>7. Strip the code.</strong> Unity&rsquo;s recommended Player settings for Web include Managed Stripping Level set to High, IL2CPP code generation optimised for size, and Brotli (<a href="https://docs.unity3d.com/Manual/web-optimization-player.html">Unity: recommended Player settings</a>). For mobile, Unity also recommends turning off Development Build and setting Code Optimization to Disk Size with LTO. Remove packages you do not use, too: Unity names the Input System package as one that can significantly increase build size if left in (<a href="https://docs.unity3d.com/Manual/web-optimization-remove-resources.html">Unity: remove unused resources</a>).</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">// Assets/Editor/WebRelease.cs: Unity's recommended release settings for Web
using UnityEditor;
using UnityEditor.Build;

public static class WebRelease {
  [MenuItem("Build/Apply Web release settings")]
  static void Apply() {
    PlayerSettings.WebGL.compressionFormat = WebGLCompressionFormat.Brotli;
    PlayerSettings.WebGL.dataCaching = true;
    PlayerSettings.SetManagedStrippingLevel(NamedBuildTarget.WebGL, ManagedStrippingLevel.High);
    PlayerSettings.SetIl2CppCodeGeneration(NamedBuildTarget.WebGL, Il2CppCodeGeneration.OptimizeSize);
    UnityEditor.WebGL.UserBuildSettings.codeOptimization = UnityEditor.WebGL.WasmCodeOptimization.DiskSizeLTO;
  }
}</pre>

<p><strong>8. Compress with Brotli and send the right headers.</strong> Brotli gives the smallest files and takes longer to build; gzip is bigger and faster. Chrome and Firefox only decompress Brotli natively over HTTPS, and Unity only compresses release builds (<a href="https://docs.unity3d.com/Manual/webgl-deploying.html">Unity: deploy a Web application</a>). The server must say what it is sending: <code>Content-Encoding: br</code> on every <code>.br</code> file, and <code>Content-Type: application/wasm</code> on the WebAssembly so the browser can compile it while it downloads. This is the config that serves Al Hamra on Vercel:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">// vercel.json
{ "headers": [
  { "source": "/worlds/rvt/Build/(.*)\\.br",
    "headers": [{ "key": "Content-Encoding", "value": "br" }] },
  { "source": "/worlds/rvt/Build/(.*)\\.wasm\\.br",
    "headers": [{ "key": "Content-Type", "value": "application/wasm" }] },
  { "source": "/worlds/rvt/Build/(.*)\\.js\\.br",
    "headers": [{ "key": "Content-Type", "value": "application/javascript" }] },
  { "source": "/worlds/rvt/Build/(.*)\\.data\\.br",
    "headers": [{ "key": "Content-Type", "value": "application/octet-stream" }] }
] }

# nginx, from Unity's server guide
location ~ .+\.wasm\.br$ {
  gzip off;
  add_header Content-Encoding br;
  default_type application/wasm;
}</pre>

<p>Without the header, Unity&rsquo;s Decompression Fallback still loads the build, with a larger loader and a less efficient loading scheme. I leave it off and fix the server instead.</p>
<p><strong>9. Load on purpose.</strong> On a phone, Al Hamra plays a short video first and loads the 3D only when the visitor asks for it, so a large download never starts on mobile data unasked. Turn on Data Caching so the second visit does not download again. For bigger worlds, Unity recommends Addressables, which load assets when they are needed instead of at startup, and setting the Initial Memory Size to the app&rsquo;s typical heap use on mobile.</p>
<h2>Does Unity WebGL work on mobile browsers?</h2>
<p>Yes. Unity 6 lists iOS Safari 15 and newer, and Chrome 58 and newer on Android (<a href="https://docs.unity3d.com/Manual/webgl-browsercompatibility.html">Unity: browser compatibility</a>). Support is the easy part. Whether it runs well depends on the steps above, because a phone has less memory, a slower GPU and often a slower connection than the laptop you built on. Test on a real mid-range phone, not only the newest one.</p>
<h2>What are the three.js equivalents?</h2>
<p>The same rules apply in three.js; the tools have different names.</p>
<ul>
<li><strong>Draw calls:</strong> every mesh is at least one request to draw, so merge static geometry (<a href="https://threejs.org/manual/#en/optimize-lots-of-objects">three.js manual: optimise lots of objects</a>). Use <code>InstancedMesh</code> for many copies of one object and <code>BatchedMesh</code> for many different geometries that share a material (<a href="https://threejs.org/docs/pages/BatchedMesh.html">BatchedMesh docs</a>).</li>
<li><strong>Detail by distance:</strong> the <code>LOD</code> object switches between meshes at the distances you set (<a href="https://threejs.org/docs/pages/LOD.html">LOD docs</a>).</li>
<li><strong>Textures:</strong> ship KTX2 files with Basis Universal. <code>KTX2Loader</code> transcodes them to whatever compressed format the GPU supports (<a href="https://threejs.org/docs/pages/KTX2Loader.html">KTX2Loader docs</a>), which covers desktop and phones from one file.</li>
<li><strong>Light:</strong> bake it into lightmaps in Blender and use cheap materials, as you would in Unity.</li>
<li><strong>Measure:</strong> <code>renderer.info.render.calls</code> and <code>renderer.info.render.triangles</code> give you draw calls and triangles per frame (<a href="https://threejs.org/docs/pages/WebGLRenderer.html">WebGLRenderer docs</a>).</li>
<li><strong>Memory:</strong> geometries, materials and textures are not freed on their own; call <code>dispose()</code> when you remove them (<a href="https://threejs.org/manual/#en/how-to-dispose-of-objects">three.js manual: dispose of objects</a>).</li>
</ul>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">// Cap the pixel ratio: a phone at 3x draws far more pixels than at 2x
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

// Compressed textures that suit every GPU
const ktx2 = new KTX2Loader().setTranscoderPath('/basis/').detectSupport(renderer);
const tex = await ktx2.loadAsync('/textures/floor.ktx2');

// Watch the two numbers that matter
console.log(renderer.info.render.calls, renderer.info.render.triangles);</pre>

<p>The live Al Hamra page caps the pixel ratio at 2 for the same reason.</p>
<h2>When should you stream instead of building for WebGL?</h2>
<p>Stream when the visuals cannot be cut down to fit a phone, or when the model must never leave your servers. With Unreal Pixel Streaming the 3D renders on a cloud GPU and every viewer needs their own. One streaming GPU server on AWS costs <a href="https://instances.vantage.sh/aws/ec2/g4dn.xlarge">about $0.53 an hour</a>, so 1,000 people at once is roughly $526 an hour before bandwidth. A WebGL build is one download per visitor, however many come. For a building people browse for leasing or marketing, I build for the browser. I have shipped both routes: at Napster I led a team across Unreal, Unity and WebGL, which I compare with building alone in <a href="https://tawfik.tv/notes/one-person-ai-team">what one person with AI can ship</a>. I compare the routes for stores, shows and venues in <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">Virtual stores, live shows and 3D worlds people actually use</a>.</p>
<h2>Questions people ask</h2>
<h3>How do I reduce Unity WebGL build size?</h3>
<p>Leave out hidden objects, decimate heavy meshes, compress textures, strip code with Managed Stripping Level High and Disk Size with LTO, remove unused packages, and compress with Brotli.</p>
<h3>Brotli or gzip for Unity WebGL?</h3>
<p>Brotli gives smaller files and needs HTTPS in Chrome and Firefox. Gzip is bigger and works over HTTP and HTTPS. Either way, the server must send the matching <code>Content-Encoding</code> header.</p>
<h3>Why does my Unity WebGL build fail to load after upload?</h3>
<p>Usually the headers. Compressed files served without <code>Content-Encoding</code>, or the WebAssembly without <code>Content-Type: application/wasm</code>, will fail to load or load slowly. Check them in the browser&rsquo;s network panel.</p>
<h3>How many triangles can a phone browser draw?</h3>
<p>There is no single number; it depends on the phone, the shaders, the lights and the draw calls. Measure on a real mid-range device with the Profiler or <code>renderer.info</code>. For reference, the live Al Hamra build draws about 700,000 at once and holds 60 fps on a laptop graphics chip.</p>
<p>If you need a 3D world that opens from a link on a phone, see <a href="https://tawfik.tv/hire/3d-web-experiences">3D web experiences</a> or write to me at m@tawfik.tv.</p>]]></content:encoded></item><item><title>AI agent governance: a practical framework for securing agents and their permissions</title><link>https://tawfik.tv/notes/ai-agent-governance</link><guid>https://tawfik.tv/notes/ai-agent-governance</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>AI agent governance means every agent has an owner, its own identity, least privilege, a check before each action and a record you can prove.</description>
<content:encoded><![CDATA[<p>AI agent governance is the set of rules and controls that decide what each AI agent may do, who it acts for, and how you prove afterwards what it did. In practice that is nine things: an inventory, an identity per agent, least privilege, a check before every action, spend and loop limits, a person on anything irreversible, a tamper-evident record, a review cadence and an incident playbook.</p>
<p>Most teams find their gaps the expensive way. Gartner predicts that by 2027, 40% of enterprises will demote or decommission autonomous AI agents because of governance gaps found only after production incidents (<a href="https://www.gartner.com/en/newsroom/press-releases/2026-05-26-gartner-says-applying-uniform-governance-across-ai-agents-will-lead-to-enterprise-ai-agent-failure">Gartner, 26 May 2026</a>). Its advice: match controls to how much each agent can do on its own.</p>
<p>I lead product for <a href="https://gvnr.io">GVNR</a> at Instruxi, guardrails that decide allow, deny or ask before an agent acts. This is the framework I use, in plain words.</p>
<h2>What is AI agent governance?</h2>
<p>Model governance asks whether a model is fair and fit for purpose. Agent governance asks: <strong>may this agent do this, right now?</strong> An agent holds keys, calls tools and spends money, so the controls sit in front of its actions, outside the model. A line in the prompt saying &ldquo;never delete anything&rdquo; is a request. A permission the agent does not hold is a control.</p>
<h2>The AI agent governance framework in nine steps</h2>
<p><strong>1. Inventory every agent.</strong> List each agent, the person who owns it, what it touches and how much it can do on its own. Gartner&rsquo;s four autonomy levels are a useful label: observe, advise, act with approval, act autonomously. Include the ones people set up on their own laptops.</p>
<p><strong>2. Give each agent its own identity.</strong> No shared API keys. Each agent gets its own credential and acts for a named person, so every action traces back to both. This is the answer to OWASP&rsquo;s ASI03, Identity and Privilege Abuse, in the <a href="https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/">OWASP Top 10 for Agentic Applications</a> (December 2025). In GVNR the agent cannot choose or change its own id.</p>
<p><strong>3. Least privilege.</strong> Start read-only and add what the job proves it needs. Refunds up to a set amount, a staging database instead of production, a project folder instead of the whole disk. Separate credentials per environment.</p>
<p><strong>4. Decide before the action.</strong> Put a check between the agent and its tools that answers every call with allow, deny, or stop and ask a person. Deny what should never happen, ask before what cannot be undone, allow the rest. A check that runs after the fact can only report the damage.</p>
<p><strong>5. Set spend and loop limits.</strong> Two kinds: a total per agent per session or day, and a rate per minute. The rate catches runaways, the expensive incidents. Add loop detection: GVNR&rsquo;s defaults stop an agent that repeats the same action four times in its last eight, and ask when spend passes $2 a minute or 75% of a $20 cap.</p>
<p><strong>6. A person approves the irreversible.</strong> Deleting data, moving money, deploying, publishing and sending messages outside the company wait for a named human. Keep the list short: Gartner warns that approvals degrade under time pressure and approval fatigue.</p>
<p><strong>7. Keep a tamper-evident record.</strong> Record who the agent acted for, the exact action, the tool, the model, the rule that answered, the verdict and the time, as fields you can query. Chain each line to the hash of the one before, so an edit or a deleted line breaks the chain and a single check shows where.</p>
<p><strong>8. Review on a cadence.</strong> Each month the owner confirms the agent&rsquo;s access and removes what it has not used. Each week someone reads the denies and asks: denies show where agents push, asks show where rules are too tight or too loose.</p>
<p><strong>9. Write the incident playbook before the incident.</strong> Stop the agent, revoke its key, verify the record, work out what it touched, fix the rule that let it through, and write it up. Only a person should be able to resume a stopped agent.</p>
<p><a href="https://tawfik.tv/notes/ai-agent-governance">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do I secure AI agents?</h2>
<p>Steps 2 to 6 are the security core: identity, least privilege, a check before each action, limits, and a person on the irreversible. Those five cover the most common ways agents go wrong in the OWASP list: a hijacked goal (ASI01), misused tools (ASI02), abused identity and privileges (ASI03), unexpected code execution (ASI05) and cascading failures (ASI08). For coding agents with a shell, the <a href="https://tawfik.tv/notes/ai-agent-deleted-database">step-by-step settings for Claude Code, Cursor, Codex and Gemini CLI</a> are in my note on agents deleting databases. For agents connected to tools over MCP, start with the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a>.</p>
<h2>How do I manage AI agent permissions?</h2>
<p>Treat each agent like a new starter with a narrow role. Write its permissions down as scopes (what it can read, what it can change, how much it can spend), attach them to its own identity, and give it an owner who signs off each month. Make &ldquo;ask a person&rdquo; a permission in its own right: a finance agent can draft a payment and have it wait, rather than holding either no access or full access. When an agent changes job, change its scopes: editing the prompt changes nothing it can reach.</p>
<h2>How do you red team AI agents?</h2>
<p>AI red teaming means attacking your own agent before someone else does, and with an agent the thing to attack is what it can do: its tool calls, its spending, its deletes. Use the OWASP Top 10 for Agentic Applications as the test list: hide instructions in a document to hijack its goal (ASI01), push it to misuse a tool (ASI02), get it to act with someone else&rsquo;s identity or privileges (ASI03), and try to make it run code it should not (ASI05). Aim each attack at the check that sits before the action, and record its verdict. Every attack that reaches a tool is a rule to write, and every one that ends in deny or ask is evidence for your review in step 8.</p>
<h2>How does this map to NIST AI RMF, ISO/IEC 42001 and the EU AI Act?</h2>
<p>The <a href="https://www.nist.gov/itl/ai-risk-management-framework">NIST AI Risk Management Framework 1.0</a> (January 2023) organises the work into four functions: Govern, Map, Measure and Manage. <a href="https://www.iso.org/standard/42001">ISO/IEC 42001:2023</a> is the first international standard for an AI management system; ISO&rsquo;s own summary lists responsibilities, risk management, lifecycle controls, monitoring and continual improvement among its requirements (<a href="https://www.iso.org/insights/iso-42001-explained">ISO/IEC 42001 explained</a>). The <a href="https://eur-lex.europa.eu/eli/reg/2024/1689/oj/eng">EU AI Act</a> sets legal duties, the heaviest for high-risk uses.</p>
<div style="margin:0 0 24px;overflow-x:auto;border:1px solid #262a31;border-radius:10px"><table style="width:100%;border-collapse:collapse;font-size:14px;line-height:1.45">
<thead><tr style="text-align:left;color:#f4f5f7;background:#15171b"><th style="padding:9px 10px;font-weight:500">Step</th><th style="padding:9px 10px;font-weight:500">NIST AI RMF</th><th style="padding:9px 10px;font-weight:500">ISO/IEC 42001</th><th style="padding:9px 10px;font-weight:500">EU AI Act</th></tr></thead>
<tbody>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">1. Inventory</td><td style="padding:8px 10px">Map</td><td style="padding:8px 10px">Responsibilities, AI use identified</td><td style="padding:8px 10px">Art. 26 deployer duties</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">2. Own identity</td><td style="padding:8px 10px">Govern</td><td style="padding:8px 10px">Responsibilities</td><td style="padding:8px 10px">Art. 26(2) named oversight</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">3. Least privilege</td><td style="padding:8px 10px">Map, Manage</td><td style="padding:8px 10px">Risk management</td><td style="padding:8px 10px">Art. 9 risk management</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">4. Check before action</td><td style="padding:8px 10px">Manage</td><td style="padding:8px 10px">Lifecycle controls</td><td style="padding:8px 10px">Art. 14 human oversight</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">5. Spend and loop limits</td><td style="padding:8px 10px">Measure, Manage</td><td style="padding:8px 10px">Monitoring</td><td style="padding:8px 10px">Art. 14(4)(e) stop</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">6. Person approves</td><td style="padding:8px 10px">Manage</td><td style="padding:8px 10px">Lifecycle controls</td><td style="padding:8px 10px">Art. 14, Art. 26(2)</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">7. Tamper-evident record</td><td style="padding:8px 10px">Measure</td><td style="padding:8px 10px">Monitoring and evaluation</td><td style="padding:8px 10px">Art. 12 logs, Art. 26(6) keep 6 months</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">8. Review cadence</td><td style="padding:8px 10px">Govern</td><td style="padding:8px 10px">Performance evaluation</td><td style="padding:8px 10px">Art. 26(5) monitoring</td></tr>
<tr style="border-top:1px solid #262a31"><td style="padding:8px 10px">9. Incident playbook</td><td style="padding:8px 10px">Manage</td><td style="padding:8px 10px">Continual improvement</td><td style="padding:8px 10px">Art. 26(5) report risks and incidents</td></tr>
</tbody></table></div>

<p>For high-risk systems, <a href="https://artificialintelligenceact.eu/article/12/">Article 12</a> requires automatic event logs, <a href="https://artificialintelligenceact.eu/article/14/">Article 14(4)(e)</a> a stop button or similar procedure, and <a href="https://artificialintelligenceact.eu/article/26/">Article 26</a> oversight by competent people and logs kept for at least six months.</p>
<h2>When do the EU AI Act rules apply to AI agents?</h2>
<p>The Act entered into force on 1 August 2024. Prohibited practices and the AI literacy duty applied from 2 February 2025, rules for general-purpose AI models from 2 August 2025, and the transparency rules, such as telling people they are talking to a machine, from August 2026, according to the <a href="https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai">European Commission</a>. The Digital Omnibus, <a href="https://eur-lex.europa.eu/eli/reg/2026/1744/oj/eng">Regulation (EU) 2026/1744</a>, moved the high-risk duties: 2 December 2027 for Annex III uses such as employment, credit, education and critical infrastructure, and 2 August 2028 for AI built into regulated products.</p>
<p>Most coding and research agents are not high-risk. An agent that screens job applicants or decides who gets credit is. Either way, the nine steps are the evidence an auditor or a customer&rsquo;s security team will ask for.</p>
<h2>What should an AI agent governance platform do?</h2>
<p>Whatever you buy or build, check six things: an identity and owner per agent, a decision before each action runs, coverage of every agent whichever AI it uses, per-agent limits on spend, rate and repeats, irreversible actions routed to a named person, and a record you can verify without trusting the vendor.</p>
<p>That is what GVNR does on your own machine. It works with Claude Code, Cursor, Codex, Gemini CLI and any other MCP client. Where an agent offers a hook that runs before each tool call, the decision is enforced; Claude Code&rsquo;s hook is wired today, and over MCP the agent has to ask. It is free and source-available under FSL-1.1-ALv2, so each release becomes Apache 2.0 two years later (<a href="https://github.com/instruxi-io/enforcer-governor">code on GitHub</a>). It does not judge whether an answer is true. It decides what an agent may do, and keeps the receipt.</p>
<p>The same three answers sit behind the credential and banking builds in my <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed work</a>.</p>
<h2>Questions people ask</h2>
<h3>What is AI agent governance?</h3>
<p>The rules and controls that decide what each AI agent may do, who it acts for, and how you prove what it did.</p>
<h3>What is an AI agent governance framework?</h3>
<p>A repeatable set of controls applied to every agent: inventory, identity, least privilege, a check before each action, limits, human approval for the irreversible, a tamper-evident record, regular review and an incident playbook.</p>
<h3>How do I secure AI agents?</h3>
<p>Give each agent its own identity and the least access its job needs, check every action before it runs, cap spend and repeats, and make irreversible actions wait for a person.</p>
<h3>How do I manage AI agent permissions?</h3>
<p>Write them as scopes tied to the agent&rsquo;s own identity, start read-only, make &ldquo;ask a person&rdquo; a permission, and have the owner review them monthly.</p>
<h3>Does the EU AI Act apply to AI agents?</h3>
<p>Yes, depending on the use. Transparency rules apply now; high-risk duties such as logging and human oversight apply from 2 December 2027 for Annex III uses.</p>
<h3>What is the difference between AI risk management and AI compliance?</h3>
<p>AI risk management is the ongoing work of finding, measuring and reducing what can go wrong with an AI system; the NIST AI RMF splits it into Govern, Map, Measure and Manage. AI compliance is proving you meet a specific rulebook. For EU AI Act compliance on high-risk uses, that means automatic logs (Article 12), a way to stop the system (Article 14) and logs kept for at least six months (Article 26). The nine steps above serve both: the controls cut the risk, and the record is the evidence.</p>
<p>If you need agent governance designed or built into your product, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>MCP security checklist: 12 checks before you connect an AI agent to your tools</title><link>https://tawfik.tv/notes/mcp-security-checklist</link><guid>https://tawfik.tv/notes/mcp-security-checklist</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>MCP is safe when you pin servers, scope tokens, approve risky actions and limit what servers can reach. The 12 checks I run, ranked by risk.</description>
<content:encoded><![CDATA[<p>MCP is as safe as the servers you connect and the limits you set around them. Every server you add can put text in front of your model and act with whatever access you hand it, so the security has to live in your setup: pinned versions, narrow tokens, a person on risky actions, and servers that cannot reach what they do not need.</p>
<p>In September 2025, researchers at Koi Security found the first malicious MCP server in the wild. The package, postmark-mcp, was downloaded about 1,500 times a week, worked cleanly for 15 versions, and from version 1.0.16 quietly copied every email it sent to its publisher (<a href="https://web.archive.org/web/2025/https://www.koi.security/blog/postmark-mcp-npm-malicious-backdoor-email-theft">Koi Security, 25 September 2025</a>). No agent made a mistake. The server did what its code said.</p>
<p>I build guardrails for AI agents at Instruxi, including a free guard that plugs into agents over MCP. This is the list I run before an agent touches anything that matters, built from the <a href="https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices">official MCP security guidance</a> and OWASP. Tick what your setup has in the checker below and it ranks what to fix first.</p>
<h2>What is an MCP server?</h2>
<p>MCP is the <a href="https://modelcontextprotocol.io/">Model Context Protocol</a>, an open standard for connecting AI agents to tools and data. An MCP server is a small program that hands an agent a set of tools, such as &ldquo;send email&rdquo;, &ldquo;query the database&rdquo; or &ldquo;read this folder&rdquo;. The agent decides when to call them. That is the risk: whatever the server can reach, the agent can reach, so the server deserves the same checks as any code you install.</p>
<h2>What are the main MCP security risks?</h2>
<p>Six keep showing up in the advisories.</p>
<ul>
<li><strong>Tool poisoning.</strong> Tool names and descriptions are text the model reads as instructions, and a server can hide orders in them. Invariant Labs showed a poisoned tool getting an agent in Cursor to read <code>~/.ssh/id_rsa</code> and its own MCP config and hand them over (<a href="https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks">April 2025</a>). A server can also change a description after you approved it, which they call a rug pull.</li>
<li><strong>Prompt injection through tool output.</strong> A crafted issue in a public repository steered an agent using GitHub&rsquo;s MCP server into leaking private repository data into a public pull request (<a href="https://invariantlabs.ai/blog/mcp-github-vulnerability">Invariant Labs, May 2025</a>). OWASP ranks this family first, as agent goal hijack, in its <a href="https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/">Top 10 for Agentic Applications</a> (December 2025).</li>
<li><strong>Token passthrough.</strong> A server that takes the client&rsquo;s token and forwards it to the API behind it. The <a href="https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices">MCP security best practices</a> forbid it: servers &ldquo;MUST NOT accept any tokens that were not explicitly issued for the MCP server&rdquo;.</li>
<li><strong>Confused deputy.</strong> An MCP proxy that talks to a third-party API with one shared client ID can let an attacker ride your earlier consent and receive the authorization code. The same page requires per-client consent before the proxy forwards anything.</li>
<li><strong>Over-broad scopes.</strong> A token granted <code>files:*</code> or <code>admin:*</code> up front turns one leak into access to everything. OWASP calls the wider pattern <a href="https://genai.owasp.org/llmrisk/llm062025-excessive-agency/">excessive agency</a>: too much functionality, too much permission, too much autonomy.</li>
<li><strong>Unpinned and unpatched servers.</strong> postmark-mcp is the first case. The second: a flaw in mcp-remote, a widely used bridge, let a malicious server run commands on the machine that connected to it (<a href="https://jfrog.com/blog/2025-6514-critical-mcp-remote-rce-vulnerability/">CVE-2025-6514, CVSS 9.6, JFrog, July 2025</a>). Version 0.1.16 fixed it.</li>
</ul>
<h2>Is MCP safe to use?</h2>
<p>Yes, with the care you give any code that runs with your permissions. The official <a href="https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/local-server-security">local server security guide</a> is blunt about it: no check proves what a server will do. So the work splits in two. Vet what you install, then contain what it can reach, so a bad call costs little.</p>
<h2>The MCP security checklist: 12 checks in priority order</h2>
<ol>
<li><strong>A person approves risky actions.</strong> Delete, deploy, send, pay and reading secrets wait for a yes, with the full inputs on screen. The <a href="https://modelcontextprotocol.io/specification/2026-07-28/server/tools">MCP tools spec</a> says there should always be a human who can deny a tool call.</li>
<li><strong>Pin every server version.</strong> Install <code>name@1.2.3</code>, never latest. Pinning through <code>npx</code> or <code>uvx</code> fixes only the top package, since its dependencies resolve fresh at install; a container image pinned by digest freezes the whole tree.</li>
<li><strong>Run third-party servers isolated.</strong> A container with only the project folder mounted. The official guide calls isolation the single highest-leverage step, because it still protects you when your vetting was wrong.</li>
<li><strong>Give tokens only the scopes the job needs.</strong> Start read-only and add a scope when a tool first asks for it. No <code>*</code>, <code>all</code> or <code>full-access</code>.</li>
<li><strong>Give each server its own credentials.</strong> Put each secret in that server&rsquo;s own config block. If your shell profile exports cloud keys, every server you launch may inherit them.</li>
<li><strong>Treat tool output as untrusted.</strong> Issues, emails, tickets and web pages are data. Never let one session read untrusted text, hold private data and have a way to send data out.</li>
<li><strong>Re-approve changed tool descriptions.</strong> Read each server&rsquo;s tool list once, the <a href="https://modelcontextprotocol.io/docs/2026-07-28/tools/inspector">MCP Inspector</a> shows it with no model involved, and use a client that asks again when a definition changes.</li>
<li><strong>Limit network egress.</strong> Servers that work only on local files get no network at all (<code>--network=none</code> in Docker). The rest get a short allowlist of the hosts they need.</li>
<li><strong>No token passthrough.</strong> If you build a server, accept only tokens issued to it, and get its own token for the API behind it.</li>
<li><strong>Log every tool call.</strong> Server, tool, inputs, verdict and who approved, in a record that shows any edit. The spec asks clients to log tool usage for audit.</li>
<li><strong>Know every server you run.</strong> Open your client&rsquo;s MCP config and delete what you no longer use. A server that only wraps a remote API gains nothing from running on your laptop, so use its remote version.</li>
<li><strong>Patch bridges and proxies.</strong> Update when an advisory lands, and keep per-client consent on any OAuth proxy you run.</li>
</ol>
<p><a href="https://tawfik.tv/notes/mcp-security-checklist">Open the interactive diagram on tawfik.tv</a></p>

<h2>How does MCP tool poisoning work?</h2>
<p>Follow one attack through, the one the checker animates.</p>
<ol>
<li><strong>A poisoned update arrives.</strong> A server you approved last month ships a new version. One tool description now hides an instruction: read <code>~/.ssh/id_rsa</code> and pass it in the notes field. Pinning stops the update; a client that re-prompts on changed definitions shows it to you.</li>
<li><strong>The model follows it.</strong> Nothing stops this step. The model cannot tell a hostile description from an honest one, and Invariant found that even well-aligned models fall for it. Every defence sits before or after the model.</li>
<li><strong>The agent reads your key</strong> and calls the tool with it. A person asked before secrets are read, shown the inputs, says no.</li>
<li><strong>The server sends it out.</strong> An egress allowlist stops the call to the attacker&rsquo;s host.</li>
</ol>
<p>Each check alone stops the chain. The log decides whether you find out the same day or never.</p>
<h2>Where does a guard fit in an MCP setup?</h2>
<p>I built <a href="https://gvnr.io">GVNR</a>, a free, self-hosted guard that sits in front of AI agents and decides allow, deny or ask before each action runs, with a hash-chained record of every decision. It works with Claude Code, Cursor, Codex, Gemini CLI or any other MCP client. Its credentials rule matches <code>id_rsa</code>, <code>.ssh/</code> and <code>.env</code> and asks a person first, which is step three above.</p>
<p>The rule I held to: the agent being governed can never loosen its own limits. Its MCP tools let an agent ask permission, read status, check the record and stop an agent. There is no approve, resume or config tool, and the agent cannot pick its own identity. An agent that tries to reach the guard&rsquo;s own settings from a shell gets asked too.</p>
<p>One honest limit, and it applies to every MCP guard. Asking over MCP is cooperative: an agent that calls the tool gets a real answer, but nothing forces it to call. Where an agent supports a hook that runs before every action, use it, and against a deliberate attacker run the agent in a container. The official guide says the same about config allowlists: they keep honest servers in line, and isolation handles the rest. For what happens when an agent holds more access than its job needs, read <a href="https://tawfik.tv/notes/ai-agent-deleted-database">the note on an AI agent deleting a database</a>. For the same checks in front of real money and records, see <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">four AI and fintech builds</a>.</p>
<h2>Questions people ask</h2>
<h3>Is MCP safe?</h3>
<p>The protocol is a way for agents to call tools. It is as safe as the servers you connect and the access you give them. Pin versions, isolate third-party servers, keep tokens narrow, and put a person on risky actions, and the risk drops to that of any other software you install.</p>
<h3>What is tool poisoning in MCP?</h3>
<p>Hidden instructions inside a tool&rsquo;s name or description. The model reads them as part of its instructions and acts on them, often without the poisoned tool ever being called, and sometimes to misuse another server&rsquo;s tools. A server can add them after you approved it.</p>
<h3>How do I secure an MCP server?</h3>
<p>The spec says servers must validate tool inputs, enforce access controls, rate limit tool calls and sanitise tool outputs. Accept only tokens issued to your server, offer the smallest scopes that work, use stdio for local servers or require authorization over HTTP, and use random session IDs that are never treated as authentication.</p>
<h3>Should MCP servers run locally?</h3>
<p>Only when they need something on your machine: your files, a local tool or hardware. A server that wraps a remote API gains nothing from running locally and takes your environment and files within reach, so prefer its remote version.</p>
<p>If you need this built into your agents or your product, write to m@tawfik.tv, or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>MCP server: what it is, what it exposes, and how to build one</title><link>https://tawfik.tv/notes/mcp-server</link><guid>https://tawfik.tv/notes/mcp-server</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>An MCP server is a small program that gives AI agents tools, data and prompts over one standard protocol. Here is how to build, connect and ship one.</description>
<content:encoded><![CDATA[<p>An MCP server is a small program that hands an AI application a set of tools, data and prompt templates through the Model Context Protocol, so any MCP client can use them without custom glue code. You write it once, and Claude Code, Cursor, Codex, Gemini CLI and any other MCP client can connect to it, ask what it offers and call it.</p>
<p>The ecosystem got big fast. By 9 December 2025 there were more than 10,000 active public MCP servers and over 97 million monthly SDK downloads across Python and TypeScript, when Anthropic donated the protocol to the Agentic AI Foundation under the Linux Foundation (<a href="https://www.anthropic.com/news/donating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation">Anthropic, 9 December 2025</a>).</p>
<p>I lead product for <a href="https://gvnr.io">GVNR</a> at Instruxi, a free, source-available guard that plugs into agents over MCP. Designing its tool list taught me that the tool list of a server is its security design. This page covers what a server is, a working one in about 30 lines of Python, how to connect it, and how to ship it without handing an agent more than it needs.</p>
<h2>What is an MCP server?</h2>
<p>An MCP server is a program that exposes tools, data and prompts to AI applications over the <a href="https://modelcontextprotocol.io/">Model Context Protocol</a>, an open standard for connecting AI apps to the systems they work with. Anthropic introduced MCP in <a href="https://www.anthropic.com/news/model-context-protocol">November 2024</a>. There are three roles:</p>
<ul>
<li><strong>The host</strong> is the AI app the person talks to: an IDE, a coding agent, a chat app.</li>
<li><strong>The client</strong> lives inside the host and speaks MCP, one client per server.</li>
<li><strong>The server</strong> is what you build. It exposes capabilities and never talks to the model directly.</li>
</ul>
<p>Messages are <a href="https://www.jsonrpc.org/">JSON-RPC 2.0</a>. The current spec is version <a href="https://modelcontextprotocol.io/specification/2026-07-28">2026-07-28</a>, released on 28 July 2026, and it changed how a connection starts (more on that below). If you only want the short version and the risks, my <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> has both. This page is for the person building one.</p>
<h2>What does an MCP server expose?</h2>
<p>Three kinds of thing. What separates them is who decides to use them, as the <a href="https://py.sdk.modelcontextprotocol.io/get-started/first-steps/">Python SDK&rsquo;s first steps</a> puts it:</p>
<ul>
<li><strong>Tools</strong> are functions the model decides to call: search, create, send, deploy. A tool can change things.</li>
<li><strong>Resources</strong> are data the application loads into the model&rsquo;s context, addressed by a URI such as <code>notes://monday.md</code>. Reading one changes nothing.</li>
<li><strong>Prompts</strong> are templates the user picks by name, like a slash command.</li>
</ul>
<p>Each tool can carry annotations: <code>readOnlyHint</code>, <code>destructiveHint</code>, <code>idempotentHint</code> and <code>openWorldHint</code>. Set them honestly, but never rely on them. The <a href="https://modelcontextprotocol.io/specification/2026-07-28/schema#toolannotations">spec schema</a> calls them hints and says clients should never make tool decisions from annotations sent by an untrusted server.</p>
<h2>Local (stdio) or remote (HTTP)?</h2>
<p>There are two standard transports, and the choice decides your security model.</p>
<ul>
<li><strong>stdio.</strong> The client launches your server as a child process and talks over its stdin and stdout, one JSON message per line. No port is open. The <a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization">authorization spec</a> says stdio servers should take credentials from the environment, not run OAuth. Anything your server prints to stdout corrupts the stream, so log to stderr.</li>
<li><strong>Streamable HTTP.</strong> Your server listens at a URL, usually ending in <code>/mcp</code>. This is the one you deploy so other people can use it. The <a href="https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http">transport spec</a> says servers must check the <code>Origin</code> header to block DNS rebinding, should bind to 127.0.0.1 when running locally, and should authenticate every connection. Authorization is based on OAuth 2.1.</li>
</ul>
<p>My rule: stdio when the server needs something on your machine, HTTP when other people or other machines need it.</p>
<h2>What changed in the 2026-07-28 spec?</h2>
<p>Most tutorials still open with an <code>initialize</code> handshake. The <a href="https://modelcontextprotocol.io/specification/2026-07-28/changelog">2026-07-28 changelog</a> removed it, along with protocol-level sessions. Every request now carries its protocol version, client identity and capabilities in <code>_meta</code>. Servers must answer a new <code>server/discover</code> request listing their versions and capabilities. The Python SDK&rsquo;s v2 renamed <code>FastMCP</code> to <code>MCPServer</code> and speaks the new version while still serving older clients (<a href="https://py.sdk.modelcontextprotocol.io/whats-new/">What&rsquo;s new in v2</a>). If a guide imports <code>FastMCP</code>, it was written for v1.</p>
<h2>How do I build an MCP server?</h2>
<p>Here is a complete server in Python with the official SDK: one tool, one resource template and one prompt. I ran it on SDK 2.3.0, the current release, and it answered at protocol 2026-07-28. Official SDKs also exist for TypeScript, C#, Go, Rust, Ruby, Java and more (<a href="https://modelcontextprotocol.io/docs/sdk">SDK list</a>).</p>
<p><strong>1. Install the SDK</strong> (Python 3.11 or later):</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">uv add "mcp[cli]"      # or: pip install "mcp[cli]"</pre>

<p><strong>2. Write <code>server.py</code>.</strong> It reads notes from one folder and nothing else:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">from pathlib import Path

from mcp.server import MCPServer
from mcp.types import ToolAnnotations

NOTES = (Path(__file__).parent / "notes").resolve()  # the only folder it can read
mcp = MCPServer("Notes")


@mcp.tool(annotations=ToolAnnotations(read_only_hint=True, open_world_hint=False))
def search_notes(query: str) -&gt; list[str]:
    """Return the names of notes that contain the query."""
    return [p.name for p in NOTES.glob("*.md") if query.lower() in p.read_text().lower()]


@mcp.resource("notes://{name}")
def read_note(name: str) -&gt; str:
    """The full text of one note."""
    path = (NOTES / name).resolve()
    if path.parent != NOTES:
        raise ValueError("That file is outside the notes folder.")
    return path.read_text()


@mcp.prompt()
def weekly_review() -&gt; str:
    """Summarise this week's notes."""
    return "Search my notes for this week and list the open actions."


if __name__ == "__main__":
    mcp.run()</pre>

<p>The type hints become the input schema and the docstrings become the descriptions. <code>mcp.run()</code> with no arguments serves stdio. For HTTP, <code>mcp.run(transport="streamable-http")</code> serves <code>http://127.0.0.1:8000/mcp</code>.</p>
<p><strong>3. Open it in the MCP Inspector</strong>, which lists the tools and lets you call them with no model involved:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">uv run mcp dev server.py</pre>

<p><strong>4. Leave one check behind.</strong> The SDK&rsquo;s <code>Client</code> can connect to the server object in memory, no process and no port, so a broken tool fails before any agent sees it:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">import anyio
from mcp import Client
from server import mcp


async def main() -&gt; None:
    async with Client(mcp) as client:
        result = await client.call_tool("search_notes", {"query": "booking"})
        assert result.structured_content == {"result": ["tuesday.md"]}
        print("ok", client.protocol_version)  # ok 2026-07-28


anyio.run(main)</pre>

<p>On the wire, a tool call is one line of JSON from the client and one back. This is what my server returned over stdio, trimmed of <code>_meta</code>:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_notes","arguments":{"query":"booking"}}}
← {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"tuesday.md"}],"isError":false,"resultType":"complete","structuredContent":{"result":["tuesday.md"]}}}</pre>

<p>Build it up below: add tools to the sample server, switch transports, and watch what each risky setting lets an agent reach.</p>
<p><a href="https://tawfik.tv/notes/mcp-server">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do I connect an MCP server to Claude Code, Cursor, Codex or Gemini CLI?</h2>
<p>Every client needs the same thing: the command that starts your server. Use absolute paths, because the client launches it from its own working directory (<a href="https://py.sdk.modelcontextprotocol.io/get-started/real-host/">Python SDK, connect to a real host</a>).</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere"># Claude Code
claude mcp add notes -- uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

# Codex
codex mcp add notes -- uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

# Cursor: .cursor/mcp.json   Gemini CLI: ~/.gemini/settings.json
{ "mcpServers": { "notes": {
    "command": "uv",
    "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"] } } }

# A deployed HTTP server is a URL instead of a command
claude mcp add --transport http notes https://notes.example.com/mcp</pre>

<p>Sources: <a href="https://code.claude.com/docs/en/mcp">Claude Code MCP</a>, <a href="https://developers.openai.com/codex/mcp">Codex MCP</a>, <a href="https://cursor.com/docs/context/mcp">Cursor MCP</a>, <a href="https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md">Gemini CLI MCP</a>.</p>
<h2>How do I ship an MCP server safely?</h2>
<p>The 12 checks for people connecting servers are in the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a>. These are the ones that sit with the builder.</p>
<ol>
<li><strong>Narrow tools, typed arguments.</strong> <code>search_notes(query)</code> beats <code>run_sql(query)</code>, and both beat <code>run_command(command)</code>. A catch-all tool makes every other limit decoration.</li>
<li><strong>Validate every input on the server.</strong> The <a href="https://modelcontextprotocol.io/specification/2026-07-28/server/tools#security-considerations">tools spec</a> says servers must validate all tool inputs, enforce access controls, rate limit tool calls and sanitise outputs. The folder check in <code>read_note</code> above is that rule in three lines.</li>
<li><strong>Scope what the process can reach.</strong> Point it at one folder, not your home folder. Pass only the variables it needs: a stdio server launched from your shell can inherit every key in it.</li>
<li><strong>Read-only first.</strong> Ship a reader, then add a writer when someone needs it. Mark writes and deletes honestly so clients can ask a person first.</li>
<li><strong>Return errors as results.</strong> A failed call should come back with <code>isError: true</code> and a plain message the model can act on.</li>
<li><strong>On HTTP: check <code>Origin</code>, bind to 127.0.0.1 in development, require sign-in,</strong> and accept only tokens issued to your server. Never pass the client&rsquo;s token through to another API.</li>
<li><strong>Version every release.</strong> People should pin your server, so give them versions worth pinning.</li>
</ol>
<p>Rules 1, 3 and 4 do most of the work. In the inspector above, a read-only notes server reaches one place. Add <code>fetch_url</code> and widen the folder, and the agent can read secrets, read untrusted pages and send data out: everything a leak needs.</p>
<h2>Where does a guard fit around MCP servers?</h2>
<p>Even a well-built server does exactly what the agent asks. Something has to decide whether the agent should ask. GVNR works with Claude Code, Cursor, Codex, Gemini CLI and any other MCP client, and decides allow, deny or ask before each action, with a hash-chained record of every decision. It is free and source-available under FSL-1.1-ALv2, so each release becomes Apache 2.0 two years later (<a href="https://github.com/instruxi-io/enforcer-governor">code on GitHub</a>).</p>
<p>Its own MCP server follows the rules above. Its tools let an agent ask permission, read status, check the record and stop an agent. There is no approve, resume or config tool, and the agent cannot pick its own identity, so the agent being governed can never loosen its own limits. One honest limit: over MCP, asking is cooperative. Where an agent offers a hook that runs before every action, use it; Claude Code&rsquo;s hook is wired today.</p>
<p>For how this fits a wider programme of identity, limits and records, read <a href="https://tawfik.tv/notes/ai-agent-governance">AI agent governance</a>. For what agents are and when they need tools at all, see <a href="https://tawfik.tv/notes/agentic-ai">agentic AI</a>.</p>
<h2>Questions people ask</h2>
<h3>What is an MCP server in simple terms?</h3>
<p>A program that tells an AI app &ldquo;here are the things I can do and the data I have&rdquo;, in a format every MCP client understands, and then does them when asked.</p>
<h3>What is the difference between an MCP server and an API?</h3>
<p>An API is built for developers who read its docs. An MCP server describes itself to the model at runtime: names, descriptions and input schemas. Many MCP servers are thin wrappers around an existing API.</p>
<h3>Does MCP still use the initialize handshake?</h3>
<p>Not from version 2026-07-28. Each request carries its protocol version in <code>_meta</code>, and servers answer <code>server/discover</code>. Older clients still send <code>initialize</code>, and the official Python SDK serves both.</p>
<h3>Should I write an MCP server in Python or TypeScript?</h3>
<p>Whichever your team already runs. Both are Tier 1 official SDKs, alongside C#, Go, Rust and Ruby. The server&rsquo;s design matters more than the language.</p>
<p>If you need MCP servers, agents or the guardrails around them built into your product, write to m@tawfik.tv or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>How to build a fan engagement platform: points, games, rewards and fan data the artist owns</title><link>https://tawfik.tv/notes/fan-engagement-platform</link><guid>https://tawfik.tv/notes/fan-engagement-platform</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A fan engagement platform gives fans a reason to come back every day and earns one consented data point per screen, so the artist owns the fan list.</description>
<content:encoded><![CDATA[<p>A fan engagement platform is an app or website that gives fans a reason to come back every day, with points, games, collectibles, merch drops and show check-ins, and earns one piece of fan data per screen, with consent. The artist ends up owning what streaming and social platforms keep for themselves: a list of who the fans are, where they live and what they love.</p>
<p>Here are four kinds of fan world from the platforms I&rsquo;ve built for many artists and live events, de-branded, with the club night drawing on the PRISM shows I ran.</p>
<p><a href="https://tawfik.tv/notes/fan-engagement-platform">Open the interactive diagram on tawfik.tv</a></p>

<p>Those fans are worth knowing. In Luminate&rsquo;s <a href="https://luminatedata.com/reports/yearend-music-industry-report-2025">2025 Year-End Music Report</a>, published in January 2026, 20% of U.S. music listeners count as superfans: they engage with artists in at least 5 of 13 ways, from going to shows and buying merch to signing up for artist newsletters and joining fan clubs. Yet on Spotify, an artist sees totals and <a href="https://support.spotify.com/us/artists/article/listener-and-follower-data/">can&rsquo;t see the names of individual followers</a>.</p>
<p>I&rsquo;ve built fan platforms for many artists and live events, on both sides: the app the fan plays, and the dashboard the artist and label read. Here is how I build them.</p>
<h2>What is a fan engagement platform?</h2>
<p>It is two products joined by one database.</p>
<ul>
<li><strong>The fan side.</strong> A daily habit: check in, play, collect, buy, scan in at the show, bring a friend. Every action earns points, and points unlock rewards fans actually want: early merch, better tickets, a collectible nobody else has.</li>
<li><strong>The artist side.</strong> A dashboard that turns those actions into decisions: which cities to tour, which track to push, which merch to reprint.</li>
</ul>
<p>Immersion is the skin. A fan platform can read as the artist through rooms, objects, voice and marks, the way a <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual show</a> does, with Carl Cox&rsquo;s set in PRISM as the example there. Underneath, the engine is data capture, points, games, rewards and merch. Skip the engine and you have a beautiful page people visit once.</p>
<h2>Who owns fan data, the artist or the platform?</h2>
<p>Today, mostly the platform. Streaming services and social networks hold the accounts, so an artist with millions of listeners can still have no way to email one of them. The dashboards they get show streams, listeners and top cities as totals. The people stay with the platform.</p>
<p>First-party fan data is data fans give the artist directly, on the artist&rsquo;s own platform, with consent. That consent has rules. The UK regulator, the ICO, says consent should be <a href="https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/lawful-basis/consent/what-is-valid-consent/">unbundled from terms and conditions and granular for separate purposes</a>, never a pre-ticked box, and easy to withdraw. <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">GDPR Article 5</a> adds data minimisation: collect only what you need for the purpose.</p>
<p>So I design data capture as a trade, one screen at a time. The fan unlocks a collectible, and the same screen asks for their home city so they hear when the tour comes near them. One reason, one question, one tick box that starts empty.</p>
<h2>How do you build a fan app, step by step?</h2>
<ol>
<li><strong>Pick the one number.</strong> For most artists mine is fans still active on day 7. A sign-up who never comes back is a row, and that is all.</li>
<li><strong>Design the daily habit first.</strong> A check-in streak, a short game, a drop that only lasts today. If there is no reason to open it tomorrow, nothing else matters.</li>
<li><strong>Write the points table.</strong> What each action earns, what points unlock, and what points can never buy. It should fit on one screen.</li>
<li><strong>Map one data point to each screen.</strong> Sign-up gets an email and an age band. The game gets a favourite track. The collectible gets a home city. The show gets a scan at the door. Write down the consent for each before anyone designs a button.</li>
<li><strong>Put merch and tickets inside the loop.</strong> Points buy early access, purchases earn points, and every order tells the artist what sells where.</li>
<li><strong>Make the show the peak.</strong> A scan at the venue door turns a fan into a fan who came. That is the most valuable row in the database.</li>
<li><strong>Build the artist dashboard alongside the app.</strong> If the label cannot read the data, the fans gave it for nothing.</li>
<li><strong>Ship to the browser, test on the cheapest phone, then watch the number.</strong> Cut what does not move it.</li>
</ol>
<p>Play one fan&rsquo;s week below. Each action shows what the fan gets, what the artist gets and under which consent. Then switch to asking for everything up front and see what happens to the list.</p>
<p><a href="https://tawfik.tv/notes/fan-engagement-platform">Open the interactive diagram on tawfik.tv</a></p>

<p>The drop-off numbers in the demo are illustrative, not measured. The rule behind them holds: ask for each thing at the moment the fan can see why.</p>
<h2>What should an artist and label dashboard show?</h2>
<p>Five things, and each one answers a decision.</p>
<ul>
<li><strong>Fans by city.</strong> Where the people live, so tour and ad money follows them.</li>
<li><strong>Streams by track over time.</strong> Which song is pulling, and since when.</li>
<li><strong>Merch sales.</strong> What sells, where, at what price.</li>
<li><strong>Sign-ups and returning fans.</strong> Whether the list is growing and whether people come back.</li>
<li><strong>Where to tour next.</strong> A ranking that weighs the fans in each city by how often they come back and how much they buy.</li>
</ul>
<p>I&rsquo;ve built this artist and label view: fans, streams, merch and sign-ups by city. The demo below uses a fictional artist and sample data. Filter by age band, country or top track and watch the tour ranking change.</p>
<p><a href="https://tawfik.tv/notes/fan-engagement-platform">Open the interactive diagram on tawfik.tv</a></p>

<p>A city with fewer fans who come back every week and buy the hoodie can beat a bigger city full of casual listeners.</p>
<h2>How do you keep young fans safe in a fan app?</h2>
<p>Plan for young fans from the first sketch.</p>
<ul>
<li><strong>UK.</strong> Under UK GDPR, <a href="https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/children-and-the-uk-gdpr/what-are-the-rules-about-an-iss-and-consent/">only children aged 13 and over can consent for themselves</a> to an online service. Under 13, a parent consents. The ICO&rsquo;s <a href="https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/">Children&rsquo;s code</a> covers services likely to be used by under-18s, with 15 standards including high privacy by default, location off by default and no nudges to hand over more data.</li>
<li><strong>EU.</strong> <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">GDPR Article 8</a> sets the age of digital consent at 16 and lets each country lower it, to no less than 13.</li>
<li><strong>USA.</strong> COPPA requires verifiable parental consent for children under 13. The FTC&rsquo;s <a href="https://www.ftc.gov/news-events/news/press-releases/2025/01/ftc-finalizes-changes-childrens-privacy-rule-limiting-companies-ability-monetize-kids-data">updated rule, finalised in January 2025</a>, adds separate opt-in consent for targeted advertising and other disclosures to third parties, and stops companies keeping children&rsquo;s data indefinitely.</li>
</ul>
<p>In practice: ask for an age band at sign-up, send under-13s down a parent route, keep under-18s out of ad targeting, and never use a streak or points to push a young fan into sharing more. For age checks that do not collect an ID, see <a href="https://tawfik.tv/notes/prove-age-without-id">how to prove you&rsquo;re over 18 without showing your ID</a>. Then have a privacy lawyer read the consent map from step 4.</p>
<h2>Does the same platform work for sports teams and live events?</h2>
<p>Yes. Swap the track for the player and the show for the match: check-ins at the ground, predictions as the game, a matchday collectible, kit drops as merch. Same loop, same database: who the fans are, where they live, what they buy and whether they came. I&rsquo;ve built it for live events as well as artists.</p>
<p>A fan loyalty program does not always need its own app. I&rsquo;ve built digital loyalty for local service businesses as Apple Wallet and Google Wallet stamp cards: the card lives on the phone the customer already carries, and every stamp is a visit you can count.</p>
<h2>How much does a fan app cost?</h2>
<p>On Clutch, mobile app projects reviewed on the platform <a href="https://clutch.co/app-developers/resources/cost-to-build-mobile-app">most commonly cost $10,000 to $49,999</a>, with an average of $90,780 and a typical timeline of about 11 months (figures on the page as updated in September 2026). A fan platform sits toward the higher end once you add games, a points ledger, merch, ticket scanning and the artist dashboard. One browser codebase for every phone keeps it down.</p>
<h2>Questions people ask</h2>
<h3>What is a fan engagement platform?</h3>
<p>An app or website that gives fans a daily reason to come back, with points, games, collectibles, merch and show check-ins, and turns what they do into first-party data the artist owns, with consent.</p>
<h3>How do artists own their fan data?</h3>
<p>Give fans an account on the artist&rsquo;s own platform and ask for one piece of data at a time, each with a clear reason and its own opt-in. Streaming platforms show artists totals. The artist&rsquo;s own platform holds the names.</p>
<h3>How much does a fan app cost?</h3>
<p>Clutch puts the most common mobile app project at $10,000 to $49,999, with an average of about $90,780. Games, merch and a label dashboard push a fan platform higher.</p>
<h3>Can a fan app run in the browser?</h3>
<p>Yes. A web app opens from a link with no app store in the way. On iPhone, web apps added to the home screen can send push notifications <a href="https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/">since iOS 16.4</a>, and passes can go straight into Apple Wallet or Google Wallet.</p>
<h3>How do you keep young fans safe?</h3>
<p>Ask for an age band, route under-13s to a parent, keep high privacy settings on by default for under-18s, keep them out of ad targeting, and never use rewards to nudge them into sharing more. The UK Children&rsquo;s code, GDPR Article 8 and COPPA set the rules.</p>
<h3>Can you build a fan platform for us?</h3>
<p>Yes: the fan app, the 3D rooms and the artist dashboard. See <a href="https://tawfik.tv/hire/3d-web-experiences">3D web experiences</a>, or <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> if you need someone to run the product. If you need this built, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>Vibe coding security checklist: 13 checks a founder can run in an afternoon</title><link>https://tawfik.tv/notes/vibe-coding-security-checklist</link><guid>https://tawfik.tv/notes/vibe-coding-security-checklist</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Vibe coding is safe to ship once you check 13 things: secrets, auth and RLS, input, rate limits, dependencies, keys, uploads, backups and the agent.</description>
<content:encoded><![CDATA[<p>Vibe coding is safe enough to ship if you run a security pass before real people use the app. AI writes code that works. It rarely checks who else can use it, so the checks below are on you, and none of them needs a security background.</p>
<p>The risk is measured. In July 2025, Veracode tested more than 100 AI models on 80 coding tasks: when a task could be written safely or unsafely, the models chose the unsafe way 45% of the time, and they failed to defend against cross-site scripting in 86% of cases (<a href="https://www.veracode.com/press-release/ai-generated-code-poses-major-security-risks-in-nearly-half-of-all-development-tasks-veracode-research-reveals/">Veracode, 30 July 2025</a>).</p>
<p>I build and ship apps with AI. I built a shared wedding photo app on my own with AI, about 100 guests used it on the day and nothing broke (<a href="https://tawfik.tv/notes/one-person-ai-team">the full story</a>). I have moved apps onto Supabase and fixed database security on live ones, and I built a guard for AI coding agents. This is the list I run before anything goes live.</p>
<h2>What are the security risks of vibe coding?</h2>
<p>The same few mistakes, at scale. They are the top of the <a href="https://top10.owasp.org/2025">OWASP Top 10:2025</a>: broken access control is number one, and software supply chain failures are number three.</p>
<ul>
<li><strong>Open databases.</strong> In May 2025, Matt Palmer scanned 1,645 apps from Lovable&rsquo;s public showcase and found 170 whose Supabase tables anyone could read or write, because Row Level Security was missing or wrong (<a href="https://mattpalmer.io/posts/statement-on-CVE-2025-48757/">his statement</a>; filed as <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-48757">CVE-2025-48757</a>, which Lovable disputes).</li>
<li><strong>Leaked keys.</strong> GitGuardian counted 28,649,024 new secrets pushed to public GitHub in 2025, up 34% in a year. Secrets for AI services alone rose 81% to 1,275,105 (<a href="https://www.gitguardian.com/state-of-secrets-sprawl-report-2026">State of Secrets Sprawl 2026</a>).</li>
<li><strong>Agents with too much power.</strong> A coding agent holding your keys can delete a production database. It has happened, and I wrote up <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop it</a>.</li>
</ul>
<h2>What does a vibe-coded app look like to a scanner?</h2>
<p>Like this. The repo below is made up, but every alert in it maps to one step of the checklist. Open an alert to see the exact line, press Show fix for the change, then commit it. Criticals first: the grade will not leave F until they are gone.</p>
<p><a href="https://tawfik.tv/notes/vibe-coding-security-checklist">Open the interactive diagram on tawfik.tv</a></p>

<h2>The vibe coding security checklist</h2>
<p>Work through it in this order. The first six are where real data leaks from.</p>
<p><strong>1. Get secrets out of the repo and the browser bundle.</strong> A key in git is public to everyone who can ever see the repo, and deleting the file does not remove it from history. A key in the browser bundle is public to every visitor. Next.js inlines any variable named <code>NEXT_PUBLIC_</code> into the JavaScript it sends to the browser (<a href="https://nextjs.org/docs/app/guides/environment-variables">Next.js docs</a>), and Vite does the same with <code>VITE_</code>, warning that those variables &ldquo;should not contain sensitive information such as API keys&rdquo; (<a href="https://vite.dev/guide/env-and-mode">Vite docs</a>). Check both:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere"># is .env tracked by git?
git ls-files | grep -E '(^|/)\.env'

# secrets anywhere in history
git log -p | grep -nE 'sb_secret_|sk_live_|sk-proj-|PRIVATE KEY'

# secrets in the built app
npm run build
grep -rlE 'sb_secret_|sk_live_|sk-proj-' .next/static dist build 2>/dev/null</pre>

<p>Anything found: rotate the key first, then clean up. A key that has been public once is spent.</p>
<p><strong>2. Lock down auth and database access.</strong> Turn on Row Level Security on every table, write owner-only policies, and never check roles against data the user can edit, such as Supabase&rsquo;s <code>user_metadata</code>. Then sign out and call your API with only the public key: you should get nothing back. My <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a> has the SQL for each step.</p>
<p><strong>3. Validate input on the server.</strong> Check type, length and format for every field, accept only the fields you expect, and refuse the rest. Checks in the browser are for the user&rsquo;s convenience. Anyone can skip them.</p>
<p><strong>4. Rate-limit anything that costs money or guards a door.</strong> Login, sign-up, password reset, one-time codes, anything that sends an email or a text, and anything that calls a paid AI API. Without a limit, a script can try thousands of passwords or spend your monthly budget overnight. Use your host&rsquo;s firewall rules, a counter in Redis, or your auth provider&rsquo;s limits.</p>
<p><strong>5. Audit your dependencies.</strong> AI tools can suggest the versions in their training data, which may be out of date. A real example: Next.js versions from 14.0.0 up to 14.2.24 let a crafted request skip middleware, including login checks, rated critical at 9.1 (<a href="https://github.com/advisories/GHSA-f82v-jwr5-mffw">GitHub advisory for CVE-2025-29927</a>).</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">npm audit --omit=dev
npm audit fix          # safe upgrades only
npm outdated           # what is behind</pre>

<p>Turn on automatic dependency update pull requests in your repo host so this keeps happening without you.</p>
<p><strong>6. Keep third-party API keys on your server.</strong> AI, payments, email, maps: if the browser calls the provider with your key, the key is in the page source. Move the call into your own API route, read the key there, and set a spend limit in each provider&rsquo;s console. Map keys that must sit in the browser get restricted to your domain.</p>
<p><strong>7. Separate development from production.</strong> Different databases, different keys. Your laptop, your test seeds and your coding agent should never be able to reach the data real users put in. A local database or a staging project does the job.</p>
<p><strong>8. Stop error messages leaking data.</strong> Raw database errors and stack traces show table names, columns and file paths. Log the detail, show the user a plain message, and turn off debug mode in production.</p>
<p><strong>9. Restrict file uploads.</strong> Allow only the file types you need, cap the size, store files under random names in a folder per user, and keep the bucket private. The file type the browser reports can be faked, so check the first bytes on the server too.</p>
<p><strong>10. Set CORS to your own domains.</strong> An API that echoes back whichever site asks, with credentials allowed, lets other websites read its answers. List your domains. If only your own site calls the API, send no CORS headers at all.</p>
<p><strong>11. Log the right things, and never the secrets.</strong> Log sign-ins, failed sign-ins, permission errors and admin actions, so you can see an attack happening. Never log passwords, tokens or whole request bodies. OWASP lists logging and alerting failures at number nine.</p>
<p><strong>12. Keep a backup you have restored.</strong> A free Supabase project gets no automatic daily backups. Dump the database on a schedule and before every migration, and restore one copy into a scratch project once, so you know it works.</p>
<p><strong>13. Put a guard on the coding agent itself.</strong> The agent that wrote the app has a shell and your keys. Keep approvals on, put deletes, <code>git push</code> and database clients on the ask list, deny reads of <code>.env</code>, and give it a read-only database user pointed at staging. The settings for Claude Code, Cursor, Codex and Gemini CLI are in <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop an AI agent deleting your database</a>. For a live check, I built <a href="https://gvnr.io">GVNR</a>, a free, source-available guard that runs on your own machine and works with Claude Code, Cursor, Codex, Gemini CLI and any other MCP client: before each action it decides allow, deny or ask a person, and it keeps a hash-chained record of every decision. If your agent connects to tools over MCP, the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> covers that side.</p>
<h2>Can I ask the AI to check its own code?</h2>
<p>Yes, as a first pass. Paste this list into your coding agent and ask it to go through the repo step by step and show you the lines it changes. Then check the results yourself, the way an attacker would: sign out and call your API, search the built JavaScript for keys, upload a file you should not be allowed to. The model that wrote the hole is not the best judge of whether it is closed.</p>
<p>I do this kind of pre-launch pass as part of my <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed work</a>.</p>
<h2>Questions people ask</h2>
<h3>Is vibe coding safe?</h3>
<p>It is as safe as the checks you run before launch. The code works; the gaps are in access control, keys and limits. Run the 13 checks above and you close the ones that cause most real leaks.</p>
<h3>Is AI-generated code secure?</h3>
<p>Often not by default. Veracode found AI models chose the insecure way to write code 45% of the time across 80 tasks. Treat AI code like code from a fast junior developer: useful, and reviewed before it ships.</p>
<h3>What is the biggest security risk in a vibe-coded app?</h3>
<p>Broken access control: a database anyone can read, or a secret key shipped to the browser. It is number one in the OWASP Top 10:2025 and the cause of the Lovable showcase leaks.</p>
<h3>How long does a security check take?</h3>
<p>An afternoon for a small app, if you go in order. Secrets, database access and dependencies take the first hour or two. The rest are settings and short code changes.</p>
<h3>Do I need a security expert?</h3>
<p>Not for this list. You need one before you handle payments, health data or anything regulated at scale, and a penetration test before a big launch is money well spent.</p>
<p>If you need an app checked and fixed before launch, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>Cross-border payments with stablecoins: how they work, what they cost, and when they beat SWIFT</title><link>https://tawfik.tv/notes/stablecoin-cross-border-payments</link><guid>https://tawfik.tv/notes/stablecoin-cross-border-payments</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A partner turns your money into a dollar stablecoin, it crosses a chain in minutes, a second partner pays out locally. Faster than SWIFT, not always cheaper.</description>
<content:encoded><![CDATA[<p>A stablecoin payment turns your money into a dollar token at a licensed partner, moves that token across a blockchain in minutes, and turns it back into local money at a second partner, who pays the supplier on the local instant rail. It beats a bank wire on speed almost every time, and on cost only when the conversions at each end are cheap and the payout market is deep enough for your amount.</p>
<p>The bar it has to clear is not high. On 9 October 2025 the Financial Stability Board <a href="https://www.fsb.org/uploads/P091025-1.pdf">reported</a> that a cross-border business payment cost 1.6% on average, and 1.4 points of that was the FX margin. Only 39.6% of business payment services credited the payee within one business day, and 2.2% within an hour (data as of March 2025).</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I built a cross-border payments pitch for a network that settles between member banks in seconds: an interactive page where you switch one part off and watch the payment fail. I also built the checkpoint that sits in front of every move in a bank&rsquo;s stablecoin app.</p>
<h2>What is a stablecoin?</h2>
<p>A stablecoin is a token on a blockchain that is built to hold the value of a normal currency, usually one US dollar. The issuer keeps reserves behind every coin and swaps coins back for dollars. Under the US GENIUS Act, a regulated issuer has to back every coin at least one to one with cash, insured bank deposits, short-dated Treasury bills and a short list of similar assets, and publish those reserves every month (<a href="https://tawfik.tv/notes/bank-stablecoin">what the law allows banks to do</a>). Because the coin moves on a blockchain, it can cross a border in minutes, at any hour.</p>
<h2>How does a stablecoin payment work?</h2>
<p>Six steps, and only one of them is on a blockchain.</p>
<ol>
<li><strong>Onboard once.</strong> Your business passes KYB (know your business) with a licensed partner in your country: who owns it, what it does, where the money comes from. The supplier&rsquo;s side needs the same at their end.</li>
<li><strong>Pay in.</strong> You send local money to the partner on your domestic rail, for example Faster Payments in the UK or SEPA Instant in Europe, which <a href="https://www.europeanpaymentscouncil.eu/what-we-do/sepa-instant-credit-transfer">runs 24 hours a day, every day of the year</a>.</li>
<li><strong>Check.</strong> The partner screens the payee against sanctions lists and attaches the sender and payee details that must travel with the transfer.</li>
<li><strong>Convert.</strong> The partner turns your money into a dollar stablecoin such as USDC. If you started in dollars, this is one for one, less a fee.</li>
<li><strong>Move.</strong> The coins cross the chain to the payout partner. On Ethereum a block is final after two epochs of 32 twelve-second slots, <a href="https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/">about 13 minutes</a>. Network fees are small: $0.001 to $0.53 a transaction across chains, in a <a href="https://www.bis.org/events/20260626/25th-bis-annual-conference/25th-annual-conference-du.pdf">Harvard Business School study</a> presented at the BIS annual conference on 26 June 2026.</li>
<li><strong>Pay out.</strong> The second partner sells the coins for local money and pays the supplier on their instant rail: <a href="https://www.theclearinghouse.org/payment-systems/rtp">RTP</a> in the US, <a href="https://nppa.com.au/the-platform/">NPP</a> in Australia, both open around the clock.</li>
</ol>
<p>The same study calls this the stablecoin sandwich: the partners at each end do what correspondent banks do, holding fiat, running compliance and keeping custody. Stablecoins move the middle of the trip onto a chain. They do not remove the middlemen.</p>
<p>The big networks already use the middle part. On 16 December 2025 Visa <a href="https://usa.visa.com/about-visa/newsroom/press-releases.releaseId.21951.html">launched USDC settlement</a> with US banks over Solana, with stablecoin settlement at a $3.5 billion annualized run rate as of 30 November 2025, and named seven-day availability as a reason.</p>
<h2>How do B2B cross-border payments move over SWIFT instead?</h2>
<p>Your bank screens the payment, converts the currency and sends a SWIFT message. The payment hops through one or more correspondent banks, each screening it again, before the payee&rsquo;s bank credits the account. Every bank works to its own hours and cut-offs.</p>
<p>For large payments, $100,000 and up, the hops are fast: Swift data in the <a href="https://www.fsb.org/uploads/P091025-1.pdf">same FSB report</a> shows 88.5% cross the in-flight leg within an hour. The last bank is the slow part. Only 61.7% are credited within an hour of arriving there, so 54.6% land end to end within the hour and 93.2% within a business day. Smaller business payments are the ones that wait a day or more.</p>
<h2>Where are the real costs in a stablecoin payment?</h2>
<p>At the two ends, not on the chain.</p>
<ul>
<li><strong>FX.</strong> It is 1.4 of the 1.6 points in the FSB average. Large global banks charged about 2% to 4.7% in FX on the personal wires in the Harvard study, plus a $25 to $45 wire fee. On exchanges, stablecoin rates for major currencies track the wholesale benchmark on average, but swing: about 0.87% day to day for sterling and 0.80% for Australian dollars, one standard deviation.</li>
<li><strong>Ramp fees.</strong> Published exchange trading fees run 0 to 1% per conversion, depending on platform and volume. If neither end is dollars, you convert twice.</li>
<li><strong>Off-ramp depth.</strong> A typical day&rsquo;s exchange trading of stablecoins for Australian dollars was about $4 million in the study, $7.4 million for Mexican pesos and $17.4 million for sterling. A $1 million payout is a real share of that day.</li>
<li><strong>Compliance.</strong> It moves to your partners, and they price it in.</li>
</ul>
<p>Try it. Pick a corridor, an amount and a deadline, then switch the off-ramp off or put the payee on a sanctions list.</p>
<p><a href="https://tawfik.tv/notes/stablecoin-cross-border-payments">Open the interactive diagram on tawfik.tv</a></p>

<h2>What does a business need to send stablecoin payments?</h2>
<ul>
<li><strong>A licensed partner at each end.</strong> In the US the GENIUS Act, signed on 18 July 2025, sets who may issue a payment stablecoin, and from 18 July 2028 a provider may only offer US customers coins from permitted issuers, with narrow exceptions. I covered the bank side in <a href="https://tawfik.tv/notes/bank-stablecoin">can a bank issue its own stablecoin</a>.</li>
<li><strong>KYB and a payee check.</strong> Expect the same ownership and source-of-funds questions a bank asks. Proving facts about a business without handing over its whole file is the subject of <a href="https://tawfik.tv/notes/prove-the-fact">how to prove who someone is</a>.</li>
<li><strong>Travel rule data.</strong> The sender&rsquo;s and payee&rsquo;s details must move with the transfer. In the EU this applies to crypto transfers <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32023R1113">regardless of their amount</a> since 30 December 2024. In the US the rule covers transfers of <a href="https://www.ecfr.gov/current/title-31/subtitle-B/chapter-X/part-1010/subpart-D/section-1010.410">$3,000 or more</a>, and FinCEN&rsquo;s <a href="https://www.fincen.gov/sites/default/files/2019-05/FinCEN%20Guidance%20CVC%20FINAL%20508.pdf">2019 guidance</a> applies it to virtual currency.</li>
<li><strong>Sanctions screening on both routes.</strong> OFAC&rsquo;s <a href="https://ofac.treasury.gov/media/913571/download?inline">guidance for the virtual currency industry</a> is plain: blocked virtual currency must be frozen and reported within 10 business days, as with any blocked property.</li>
<li><strong>Treasury plumbing.</strong> Who approves a release, and how each payment reconciles to its invoice: the same job as <a href="https://tawfik.tv/notes/instapay-auto-confirm">confirming an instant payment automatically</a>.</li>
</ul>
<h2>What are the risks of stablecoin payments?</h2>
<ul>
<li><strong>Depeg.</strong> In March 2023 more than $3 billion of USDC&rsquo;s reserve cash was at Silicon Valley Bank when it failed. Circle&rsquo;s <a href="https://www.sec.gov/Archives/edgar/data/1876042/000119312525070481/d737521ds1.htm">own filing</a> says USDC saw &ldquo;a temporary price dislocation&rdquo; on some markets until the funds were released. The GENIUS Act will require one for one reserves and monthly reserve reports once it takes effect, by 18 January 2027 at the latest.</li>
<li><strong>Sanctions.</strong> A hit stops both routes at the first check. Issuers can also freeze coins in a wallet, so a payment can stop after it leaves you.</li>
<li><strong>Off-ramp liquidity.</strong> If the payout partner is offline or the market is thin, your money sits as USDC with no way into the supplier&rsquo;s currency. Line up a second partner per corridor.</li>
<li><strong>Money that is not quite money.</strong> The BIS <a href="https://www.bis.org/publ/arpdf/ar2025e3.htm">Annual Economic Report 2025</a> says stablecoins &ldquo;perform poorly&rdquo; on its three tests for money: singleness, elasticity and integrity.</li>
</ul>
<h2>When does a stablecoin beat SWIFT, and when does it not?</h2>
<p>It usually wins when:</p>
<ul>
<li>The payment has to land on a weekend, a holiday or after your bank&rsquo;s cut-off.</li>
<li>One end is already dollars, so there is one conversion, not two.</li>
<li>The amount is under $100,000, where wires are slowest.</li>
<li>The supplier will accept USDC, so there is no off-ramp at all.</li>
</ul>
<p>It usually loses, or ties, when:</p>
<ul>
<li>Your bank already quotes you close to the wholesale rate, so there is little FX margin left to save.</li>
<li>The payout currency trades thinly in stablecoins and the amount is large.</li>
<li>You have no second off-ramp and the payment cannot be late.</li>
</ul>
<p>How I would decide: run both routes side by side on one corridor for a month of real invoices, and log time to credit, all-in cost against the benchmark rate, and every hold. Put a checkpoint in front of each payment that gives a plain-English reason when it stops one. The four builds behind that approach are in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer: four AI and fintech builds</a>.</p>
<h2>Questions people ask</h2>
<h3>How do stablecoin payments work for a business?</h3>
<p>A licensed partner takes your local money, converts it to a dollar stablecoin and sends it on a blockchain. A partner in the supplier&rsquo;s country converts it back and pays out on the local rail. Both partners check identity, sanctions and travel rule data.</p>
<h3>Are stablecoin payments faster than SWIFT?</h3>
<p>Usually. The chain step takes minutes and the instant rails at each end run all week. Only 39.6% of business payment services credit within one business day, per the FSB.</p>
<h3>Are stablecoin payments cheaper than a bank wire?</h3>
<p>Sometimes. The chain fee is cents, but ramp fees run 0 to 1% per conversion. Against the 1.6% business average, it wins when one end is dollars and the payout market is deep.</p>
<h3>What is the travel rule for stablecoin payments?</h3>
<p>The sender&rsquo;s and payee&rsquo;s details must travel with the transfer, as they do with a bank wire. The EU applies it to every crypto transfer a provider handles, whatever the amount. The US applies it from $3,000.</p>
<h3>What happens if a stablecoin loses its peg mid-payment?</h3>
<p>The coins can trade below a dollar for a while, as USDC did in March 2023. A payment that takes minutes has little exposure. Coins waiting at a stuck off-ramp have more.</p>
<h3>What are the main B2B cross-border payment solutions?</h3>
<p>For most businesses, two routes: a bank wire over SWIFT through correspondent banks, or a stablecoin route, where a licensed partner at each end converts the money and pays out on the local instant rail. Some bank networks also settle between member banks directly, in seconds; I built a pitch for one. Choose per corridor: stablecoins win on weekends, after cut-offs and when one end is already dollars, while wires hold up when your bank&rsquo;s FX rate is close to wholesale or the payout currency trades thinly in stablecoins. Run both side by side on one corridor for a month of real invoices before you switch.</p>
<p>If you need this built, write to m@tawfik.tv, or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>Low latency streaming: why your live stream is delayed, and how to cut it</title><link>https://tawfik.tv/notes/low-latency-streaming</link><guid>https://tawfik.tv/notes/low-latency-streaming</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Live streams run 10 to 30 seconds behind because players hold whole segments. LL-HLS and LL-DASH cut that to TV&#x27;s range; WebRTC to under a second.</description>
<content:encoded><![CDATA[<p>A live stream is delayed because the video is cut into segments, usually 2 to 6 seconds long, and the player waits for about three of them before it starts. With 6-second segments that is 18 seconds of waiting before anything else is added, which is why apps run <a href="https://optiview.dolby.com/resources/blog/streaming/low-latency-chunked-cmaf/">10 to 30 seconds behind</a> while TV runs <a href="https://aws.amazon.com/blogs/media/how-to-compete-with-broadcast-latency-using-current-adaptive-bitrate-technologies-part-1">about 6</a>.</p>
<p>Low latency streaming shrinks the chunks. Low-Latency HLS and low-latency DASH bring an app down to TV&rsquo;s range, a few seconds. WebRTC goes under a second, at a higher cost per viewer.</p>
<p>In Bitmovin&rsquo;s <a href="https://bitmovin.com/downloads/bitmovin-9th-video-developer-report-2025-2026.pdf">9th Video Developer Report</a> (survey run July 2025), 39% of video teams reported under 5 seconds end to end, 40% sat between 10 and 30 seconds, and 21% did not measure latency at all.</p>
<p>I have worked at both ends of this. I was technical and transmission manager for Olympic Broadcasting Services at the PyeongChang Winter Olympics, a technical producer on live F1 race coverage, on the engineering team behind Sky Sports&rsquo; video players, and a streaming manager at Amazon, including live music streams for Amazon Music. The long version of how a goal travels from the pitch to your phone is on my <a href="https://tawfik.tv/notes/broadcast-workflows#live">broadcast workflows page</a>. This is the engineer&rsquo;s version: where the seconds go, and which protocol buys them back.</p>
<h2>Why is my live stream delayed?</h2>
<p>Follow one goal from the ground to a phone. Glass to glass, the seconds go here:</p>
<ol>
<li><strong>Camera and production.</strong> Cameras, the director and replays add well under a second.</li>
<li><strong>Contribution.</strong> The feed travels from the venue to the encoder, often over SRT, which holds packets for a short window so it can resend lost ones.</li>
<li><strong>Encode.</strong> Encoding for picture quality takes a second or two.</li>
<li><strong>Waiting for the segment.</strong> The packager can only publish a segment once all of it is encoded. A 6-second segment is, on average, 3 seconds old when it goes out.</li>
<li><strong>Origin and CDN.</strong> The file is copied to edge servers near the viewer.</li>
<li><strong>The player buffer.</strong> This is the big one. The HLS spec, <a href="https://www.rfc-editor.org/rfc/rfc8216">RFC 8216</a>, says a player should not start less than three target durations from the end of the playlist, because &ldquo;doing so can trigger playback stalls&rdquo;. Three 6-second segments is 18 seconds.</li>
</ol>
<p>So the delay sits at the end of the chain, in the packager and the player. The satellite or the internet is rarely the problem.</p>
<p>Set your own pipeline below, then kick off and watch the same goal reach two phones.</p>
<p><a href="https://tawfik.tv/notes/low-latency-streaming">Open the interactive diagram on tawfik.tv</a></p>

<h2>What is the lowest latency streaming protocol?</h2>
<p>WebRTC. Each protocol has a real range and a job it suits.</p>
<ul>
<li><strong>HLS and DASH, standard: 10 to 30 seconds.</strong> Segments of <a href="https://optiview.dolby.com/resources/blog/streaming/low-latency-chunked-cmaf/">2 to 6 seconds</a>, three held in the player. Apple&rsquo;s <a href="https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices">authoring spec</a> still says target durations should be 6 seconds. Use it when reach and price matter more than seconds.</li>
<li><strong>Low-Latency HLS: TV range.</strong> Apple splits each segment into <a href="https://developer.apple.com/documentation/http-live-streaming/enabling-low-latency-http-live-streaming-hls">partial segments</a>, for example 200 milliseconds each, and says that brings delay &ldquo;into the range of standard television broadcasts&rdquo;. Use it for sport on phones and TVs, especially where Apple devices dominate.</li>
<li><strong>Low-latency DASH: TV range.</strong> The <a href="https://dashif.org/docs/DASH-IF-IOP-CR-Low-Latency-Live-Community-Review.pdf">DASH-IF guidelines</a> aim to match broadcast, which they put at 3 to 10 seconds. The packager sends CMAF chunks while each segment is still growing, using HTTP chunked transfer, and the player nudges its playback speed to hold a target latency. <a href="https://www.iso.org/standard/85623.html">CMAF</a> is the shared file format, so one set of chunks can serve both LL-HLS and LL-DASH.</li>
<li><strong>WebRTC: under a second.</strong> Frames go out as they are encoded, with no segments. Cloudflare&rsquo;s WebRTC docs quote <a href="https://developers.cloudflare.com/stream/webrtc-beta/">under 500 milliseconds</a> to the viewer. WHIP, published as <a href="https://www.rfc-editor.org/rfc/rfc9725">RFC 9725</a> in March 2025, standardises the ingest: one HTTP POST, and the encoder is live. Use it when the viewer acts on what they see.</li>
<li><strong>SRT: contribution, not delivery.</strong> SRT moves the feed from the venue to your encoder over the open internet. The <a href="https://datatracker.ietf.org/doc/html/draft-sharabayko-srt">SRT draft</a> describes it as ideal for sub-second video, with a 120 millisecond minimum latency and a recommended setting of 3 to 4 times the round trip.</li>
</ul>
<p>The same Bitmovin survey shows what teams pick for low latency: LL-HLS at 26%, LL-DASH at 19%, WebRTC at 14%, and 28% use none.</p>
<h2>HLS vs WebRTC latency: what do you give up?</h2>
<p>Every second you cut is paid for in one of three ways.</p>
<ul>
<li><strong>Scale.</strong> HLS and DASH are plain files. A CDN caches each segment once and serves it to everyone, so the cost per viewer stays low as the audience grows. WebRTC has no HTTP cache in the path: every viewer holds a live connection to a media server.</li>
<li><strong>Cost.</strong> LL-HLS keeps the CDN but multiplies requests. At 0.2-second parts, each viewer asks for five parts a second, plus playlist updates. The CDN also has to support HTTP/2 or HTTP/3 and hold blocking playlist requests, which the <a href="https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis">HLS second edition draft</a> requires for low-latency serving. If the edge cannot, players fall back to regular latency. You pay for low latency and get the old delay.</li>
<li><strong>Resilience.</strong> A buffer is insurance. Eighteen seconds in hand rides out most network hiccups. Three seconds leaves little room, so low-latency players drop quality or speed up and slow down to stay on target, and a bad network shows up as a stall sooner.</li>
</ul>
<h2>How do I set up Low-Latency HLS?</h2>
<p>Start with Apple&rsquo;s numbers, then tune. Apple&rsquo;s <a href="https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices">authoring spec</a> recommends a 1-second part target, keyframes every 2 seconds, and a part hold-back of at least three parts. A media playlist then looks like this:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=3.0
#EXT-X-PART-INF:PART-TARGET=1.0
#EXT-X-PROGRAM-DATE-TIME:2026-10-17T15:42:11.000Z
#EXTINF:6.000,
seg2841.mp4
#EXT-X-PART:DURATION=1.000,URI="seg2842.0.mp4",INDEPENDENT=YES
#EXT-X-PART:DURATION=1.000,URI="seg2842.1.mp4"
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="seg2842.2.mp4"</pre>

<p>Three things to check before match day:</p>
<ol>
<li><strong>Every segment starts on a keyframe.</strong> Pick a GOP that divides the segment: 2-second GOPs for 6-second segments.</li>
<li><strong>The CDN holds blocking requests.</strong> Ask your CDN for its LL-HLS support in writing, then test it with a real player at the edge, not the origin.</li>
<li><strong>Measure glass to glass.</strong> Burn a clock into the picture at the venue, film it next to a phone, and compare. A dashboard number from the encoder misses the player buffer, which is the biggest stage.</li>
</ol>
<p>For low-latency DASH, the equivalent is a target latency in the manifest and segments that are shorter than it, as the DASH-IF guidelines require:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">&lt;ServiceDescription id="0"&gt;
  &lt;Latency target="4000"/&gt;
&lt;/ServiceDescription&gt;
&lt;SegmentTemplate timescale="1" duration="2"
  availabilityTimeOffset="1.5" availabilityTimeComplete="false"
  media="v-$Number$.m4s" initialization="v-init.mp4"/&gt;</pre>

<p>And for the contribution link from the venue, set SRT latency to about four round trips. With an 80 millisecond round trip:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">srt-live-transmit "srt://:9000?mode=listener&amp;latency=320" udp://127.0.0.1:5000</pre>

<p>The <code>latency</code> value is in milliseconds, and the default in live mode is <a href="https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md">120</a>.</p>
<h2>What latency do live sports, auctions and betting need?</h2>
<p>My rule: match the latency to the moment the viewer acts. Here is the checklist I use.</p>
<ul>
<li><strong>Live sports.</strong> Match the TV, 3 to 6 seconds, with LL-HLS or LL-DASH. Fans hear the neighbours cheer and get score alerts on their phone. A stream 20 seconds behind is a spoiler machine.</li>
<li><strong>Betting.</strong> Under a second, with WebRTC. If a viewer bets on what they see, the picture must not lag the odds. Bitmovin&rsquo;s survey names WebRTC as the tool of choice for auctions and sports betting.</li>
<li><strong>Auctions.</strong> Under a second, with WebRTC. Every bidder has to see the same lot at the same moment, or the late ones lose.</li>
<li><strong>Concerts.</strong> Standard HLS is often fine. Nobody at home knows the band is 20 seconds ahead, and a big buffer keeps the picture clean on bad Wi-Fi. Go low latency only when fans interact live: chat the artist reads, votes, or shout-outs.</li>
<li><strong>Interactive shows and quizzes.</strong> WebRTC for anyone on stage or on camera, LL-HLS for the audience at scale. Stamp the stream with <code>EXT-X-PROGRAM-DATE-TIME</code>, which the low-latency profile requires anyway, and close each viewer&rsquo;s vote against their own picture, so a slower phone still gets a fair answer window.</li>
</ul>
<p>Those last two are where live streaming meets the platforms I build now: <a href="https://tawfik.tv/notes/fan-engagement-platform">fan engagement platforms</a> with games and rewards timed to the show, and <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">live shows in 3D worlds</a>, where the audience in the room and the audience on video have to see the same beat.</p>
<h2>Questions people ask</h2>
<h3>What is low latency streaming?</h3>
<p>Live video delivered with a delay of a few seconds or less from the event to the screen, usually with LL-HLS, LL-DASH or WebRTC. Standard streaming runs 10 to 30 seconds behind.</p>
<h3>What is the lowest latency streaming protocol?</h3>
<p>WebRTC, at under a second. LL-HLS and LL-DASH reach broadcast TV&rsquo;s range of a few seconds while keeping CDN scale. SRT is low latency too, but it is for contribution from the venue, not for viewers.</p>
<h3>Why is my live stream delayed?</h3>
<p>The player waits for about three whole segments before it plays, so 6-second segments add 18 seconds on their own. Encoding and the CDN add a few more.</p>
<h3>Is LL-HLS better than WebRTC?</h3>
<p>For a big audience watching, yes: it is cheaper and scales on ordinary CDNs. For viewers who bid, bet or talk back, WebRTC is better, because a second matters more than cost.</p>
<h3>What is glass-to-glass latency?</h3>
<p>The time from light hitting the camera lens to light leaving the viewer&rsquo;s screen. Measure it with a clock in the shot and a phone beside it, because it includes the player buffer that server dashboards miss.</p>
<p>If you need a live stream, fan platform or interactive show built with the right latency, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>Your AI coding agent can delete your database. Here’s how to stop it.</title><link>https://tawfik.tv/notes/ai-agent-deleted-database</link><guid>https://tawfik.tv/notes/ai-agent-deleted-database</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Any AI coding agent with a shell and your keys can delete files or a database. Deny rules, a read-only user, backups and a guard that asks first stop it.</description>
<content:encoded><![CDATA[<p>Yes, an AI coding agent can delete your production database, your project folder or your git history. If it has a shell and your credentials, it can run anything you can, and it has already happened with Replit, Gemini CLI, Claude Code and Cursor.</p>
<p>The fix is the same for every agent: take away what it should never touch, make it ask before anything it cannot undo, cap what it can spend, and keep a record you can check afterwards.</p>
<p>Developers already sense the risk. In the <a href="https://survey.stackoverflow.co/2025/ai">Stack Overflow 2025 Developer Survey</a> (July 2025), 81% of respondents said they have concerns about the security and privacy of data when using AI agents, and 87% worried about the accuracy of what agents tell them.</p>
<h2>What has actually gone wrong?</h2>
<p>These are first-hand reports, linked to the people who filed them.</p>
<ul>
<li><strong>Replit, July 2025.</strong> SaaStr founder Jason Lemkin <a href="https://x.com/jasonlk/status/1946069562723897802">posted</a> that Replit&rsquo;s agent deleted his entire database during a code freeze. The agent then told him a rollback was impossible; <a href="https://x.com/jasonlk/status/1946240562736365809">it worked</a>. Replit&rsquo;s CEO <a href="https://x.com/amasad/status/1946986468586721478">called it</a> &ldquo;unacceptable and should never be possible&rdquo; and started separating development and production databases automatically.</li>
<li><strong>Gemini CLI, July 2025.</strong> A user asked it to organise the files in a folder. A failed folder creation turned a series of moves into lost files (<a href="https://github.com/google-gemini/gemini-cli/issues/4586">GitHub issue 4586</a>). The session ran with no sandbox.</li>
<li><strong>Claude Code, October 2025.</strong> A user reported a recursive delete that started from the root and removed every file they owned in their home directory before they could interrupt it (<a href="https://github.com/anthropics/claude-code/issues/10077">GitHub issue 10077</a>).</li>
<li><strong>Cursor, July 2026.</strong> A user asked the agent to clone a repository. It ran recursive delete commands that, by their account, removed hundreds of thousands of files across the C: drive (<a href="https://forum.cursor.com/t/cursor-agent-completely-wiped-my-c-drive-and-deleted-everything/164675">Cursor forum</a>).</li>
</ul>
<p>Different agents, one pattern: the agent was allowed to run the command, and nothing stood between its decision and the command.</p>
<h2>Why doesn&rsquo;t telling the agent &ldquo;don&rsquo;t&rdquo; work?</h2>
<p>A prompt is a request, not a control. Lemkin had told his agent to freeze the code. Agents also make ordinary mistakes at machine speed: a path variable that is empty in a new shell, a quote in the wrong place, a cleanup step aimed one folder too high. The control has to sit outside the model, in permissions, credentials and a check that runs before the action.</p>
<h2>How do I stop an AI coding agent deleting files?</h2>
<p>Do these today, in this order. None of them needs new software.</p>
<p><strong>1. Turn on approvals and block destructive commands.</strong> Every major agent has a setting for this. Never run with approvals switched off on a machine that holds real work.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere"># Claude Code: .claude/settings.json in the project
{ "permissions": {
    "ask":  ["Bash(rm *)", "Bash(git push *)", "Bash(psql *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"] } }

# Cursor: Settings > Agents > Approvals &amp; Execution
#   Run mode: Allowlist (not Run Everything)
#   Turn on File-Deletion Protection and External-File Protection

# Codex: ~/.codex/config.toml
sandbox_mode = "workspace-write"
approval_policy = "on-request"
[sandbox_workspace_write]
network_access = false

# Gemini CLI: ~/.gemini/policies/guard.toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["rm", "git push", "psql"]
decision = "ask_user"
priority = 100</pre>

<p>Sources: <a href="https://code.claude.com/docs/en/permissions">Claude Code permissions</a>, <a href="https://cursor.com/docs/agent/security/run-modes">Cursor run modes</a>, <a href="https://developers.openai.com/codex/config-reference">Codex config reference</a>, <a href="https://geminicli.com/docs/reference/policy-engine">Gemini CLI policy engine</a>.</p>
<p><strong>2. Give the agent its own read-only database user.</strong> An agent that only needs to read data should not hold a password that can drop a table.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">-- Postgres
CREATE ROLE agent_ro LOGIN PASSWORD 'a-long-random-one';
GRANT CONNECT ON DATABASE app TO agent_ro;
GRANT USAGE ON SCHEMA public TO agent_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO agent_ro;
ALTER ROLE agent_ro SET default_transaction_read_only = on;</pre>

<p><strong>3. Keep production keys out of the agent&rsquo;s reach.</strong> Use separate credentials for development, keep the production ones out of the project folder, and deny reads of <code>.env</code> files as in step 1.</p>
<p><strong>4. Point the agent at staging, never production.</strong> Separate development and production databases is the fix Replit shipped. A branch database or a nightly copy does the same job.</p>
<p><strong>5. Keep backups you have restored at least once.</strong> A backup you have never restored is a guess. Run <code>pg_dump --format=custom</code> on a schedule, restore it into a scratch database once, and turn on point-in-time recovery if your host offers it.</p>
<p><strong>6. Protect the main branch.</strong> Commit before you let an agent loose, and switch on branch protection so a force-push to main is refused by the server, whatever the agent does locally.</p>
<p><strong>7. Cap the spend.</strong> Set a limit in your model provider&rsquo;s console, and see the per-minute cap below.</p>
<h2>What is an AI agent guardrail?</h2>
<p>A guardrail is a check that runs outside the model, before the action, and gives one of three answers: allow, deny, or stop and ask a person. Steps 1 to 6 are static guardrails. I built a live one: <a href="https://gvnr.io">GVNR</a>, a free, source-available, self-hosted guard that runs on your own machine (<a href="https://github.com/instruxi-io/enforcer-governor">code on GitHub</a>; licensed FSL-1.1-ALv2, so it becomes Apache 2.0 two years after each release). It plugs into Claude Code, Cursor, Codex, Gemini CLI and any other MCP client. Where an agent offers a hook that runs before each tool call, the guard enforces the answer; it is wired for Claude Code&rsquo;s hook today. Over MCP the agent has to ask, so the hook is the stronger route.</p>
<p>Its default rules deny piping a script from the internet into a shell, and ask before deleting a whole tree, rewriting git history, reading or writing credentials, or publishing and deploying. It stops an agent that repeats the same action four times in its last eight, and it asks when spend passes $2 a minute or 75% of the agent&rsquo;s limit.</p>
<p>The demo below uses those exact rules and messages. Note what it does with <code>DROP TABLE</code>: nothing, until you add a rule. A guard only knows what you tell it.</p>
<p><a href="https://tawfik.tv/notes/ai-agent-deleted-database">Open the interactive diagram on tawfik.tv</a></p>

<p>To add the database rule to the guard, put a <code>rules</code> list in <code>governor.config.json</code>. It replaces the defaults, so copy the six from <code>src/policy.mjs</code> and add this one:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">{ "name": "drop or empty a table", "tool": "",
  "match": "\\b(drop\\s+(table|database|schema)|truncate\\s+(table\\s+)?\\w)",
  "action": "ask" }</pre>

<h2>What should an AI agent audit trail record?</h2>
<p>Enough to answer an auditor&rsquo;s four questions without reading prose: who the agent acted for, what it tried to do, which rule answered, and what the answer was. My guard records the agent, the person it acts for, the tool, the model, the rule, the verdict, the reason, the spend so far and the time. Each line also carries a hash of the line before it, so editing or deleting any past line breaks the chain from that point on, and a single check shows where.</p>
<h2>How do I cap an AI agent&rsquo;s spend?</h2>
<p>Use two kinds of limit. A total per agent or per day stops slow leaks. A per-minute limit stops runaways, which are the expensive incidents: by the time a daily cap notices, the day&rsquo;s money is gone. The guard&rsquo;s defaults are $20 per agent, a question at 75% of that, $2 a minute per agent and $10 a minute across all of them. Each speed alarm asks once rather than killing the work, so an overnight run pauses and waits for you.</p>
<p>I build these controls into products as part of my <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed work</a>. If you are connecting agents to tools over MCP, the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> covers that side.</p>
<h2>Questions people ask</h2>
<h3>Can an AI agent delete my database?</h3>
<p>Yes, if it holds credentials that allow it. Give the agent a read-only user, point it at staging, and keep tested backups. Then a mistake costs you an afternoon, not your data.</p>
<h3>How do I stop Claude Code, Cursor, Codex or Gemini CLI deleting files?</h3>
<p>Keep approvals on, put <code>rm</code>, <code>git push</code> and database clients on the ask list, block reads of <code>.env</code> files, and use the sandbox where the agent has one. The settings for all four are in step 1.</p>
<h3>What is an AI agent guardrail?</h3>
<p>A check outside the model that runs before each action and answers allow, deny or ask a person. Prompts are not guardrails, because the model can ignore them.</p>
<h3>What should an agent audit trail record?</h3>
<p>Who the agent acted for, the exact action, the tool, the model, the rule that answered, the verdict and the time, with each line chained to the one before so edits show.</p>
<h3>How do I cap an AI agent&rsquo;s spend?</h3>
<p>Set a total limit in your provider&rsquo;s console and a per-minute limit in front of the agent. The per-minute one catches a runaway in its first minute.</p>
<p>If you need guardrails like these built into your product or team, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>&quot;Online Safety Act: does it apply to your site, and what you must do&quot;</title><link>https://tawfik.tv/notes/online-safety-act-age-verification</link><guid>https://tawfik.tv/notes/online-safety-act-age-verification</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>If UK users can use your service and people can post, message or search on it, or you publish porn, the Online Safety Act applies, wherever you&#x27;re based.</description>
<content:encoded><![CDATA[<p>If people in the UK use your site or app, and users can post, upload or message each other on it, or it has a search engine, or it publishes porn, the Online Safety Act applies to you, wherever you&rsquo;re based. Most services in scope have owed a written illegal content risk assessment since March 2025, and the ones children use have had to protect them since 25 July 2025.</p>
<p>Ofcom is enforcing it. Its <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/roadmap-to-regulation">implementation update, last revised 28 July 2026</a>, says it had opened investigations into nearly 100 services.</p>
<p>I&rsquo;ve built identity products three times around one rule: prove the fact, not the person. This page covers the law from a builder&rsquo;s side: who&rsquo;s in, what you owe, what Ofcom has fined, and what to do this month. It isn&rsquo;t legal advice; for a decision that matters, ask a lawyer who knows the Act.</p>
<h2>Does the Online Safety Act apply to my website?</h2>
<p>Yes, if your service is one of three kinds the Act covers and it has links with the UK.</p>
<ol>
<li><strong>User-to-user services.</strong> Anything where content one user posts, uploads or shares can be seen by another: social apps, forums, marketplaces, dating apps, game chat, file sharing, group messaging. <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/3">Section 3</a> says the feature only has to exist, however little it&rsquo;s used.</li>
<li><strong>Search services.</strong> A search engine that searches more than one website or database. Search across just your own site doesn&rsquo;t count, <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/229">per section 229</a>.</li>
<li><strong>Porn providers.</strong> Services that publish porn themselves, including porn made by their own AI tool, under <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/79">Part 5</a>.</li>
</ol>
<p><strong>The UK link.</strong> <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/4">Section 4</a> counts a significant number of UK users, or the UK as a target market. It also catches any service people in the UK can use when it presents a material risk of significant harm to them. Ofcom fined an overseas suicide forum £950,000 in May 2026, noting it could still be reached from the UK <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/ofcom-fines-online-suicide-forum-950000">without a VPN</a>.</p>
<p><strong>Who&rsquo;s out.</strong> <a href="https://www.legislation.gov.uk/ukpga/2023/50/schedule/1/part/1">Schedule 1</a> exempts services where users can only share email, SMS or one-to-one voice calls, and services where users can only comment on, review, like or rate your own content. A blog with comments under your posts is usually out.</p>
<p>Describe your service below to get the duties that apply, their dates and a to-do list.</p>
<p><a href="https://tawfik.tv/notes/online-safety-act-age-verification">Open the interactive diagram on tawfik.tv</a></p>

<p>Ofcom runs its own <a href="https://ofcomlive.my.salesforce-sites.com/formentry/RegulationChecker">Regulation Checker</a> too. Use both and keep the answer in writing.</p>
<h2>What does the Online Safety Act make you do?</h2>
<p>Five duties carry most of the weight. Each assessment must be &ldquo;suitable and sufficient&rdquo;, with a written record.</p>
<ol>
<li><strong>Illegal content risk assessment</strong> (<a href="https://www.legislation.gov.uk/ukpga/2023/50/section/9">section 9</a>, or section 26 for search). How could your features be used for illegal content such as terrorism, child sexual abuse or fraud? Then reduce those risks, take illegal content down quickly once you know about it, and say in your terms how you protect people.</li>
<li><strong>Children&rsquo;s access assessment</strong> (<a href="https://www.legislation.gov.uk/ukpga/2023/50/section/35">section 35</a>). Can children get in, and do enough of them use it, or would it attract them? You may only answer &ldquo;children can&rsquo;t get in&rdquo; if age verification or estimation means children are not normally able to. Repeat it at least yearly, <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/36">under section 36</a>.</li>
<li><strong>Children&rsquo;s risk assessment</strong> (section 11). If children are likely to use it, assess the risk from content harmful to them, then protect them from it.</li>
<li><strong>Highly effective age assurance, where required.</strong> If children are likely to use it and you allow porn, or content encouraging suicide, self-harm or eating disorders, <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/12">section 12</a> requires age checks. Porn providers must check every visitor, keep a written record and publish a summary of their checks, <a href="https://www.legislation.gov.uk/ukpga/2023/50/section/81">under section 81</a>.</li>
<li><strong>Report child sexual abuse content</strong> to the National Crime Agency (<a href="https://www.legislation.gov.uk/ukpga/2023/50/section/66">section 66</a>), for user-to-user services.</li>
</ol>
<p>One rule runs through them all: assess again before any significant change to how the service works.</p>
<h2>Which Online Safety Act dates are already in force?</h2>
<p>From Ofcom&rsquo;s <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/important-dates-for-online-safety-compliance">important dates page</a> and roadmap:</p>
<ul>
<li><strong>17 January 2025:</strong> porn providers must use highly effective age assurance.</li>
<li><strong>16 March 2025:</strong> illegal content risk assessments due. Safety duties enforced from 17 March.</li>
<li><strong>16 April 2025:</strong> children&rsquo;s access assessments due.</li>
<li><strong>24 July 2025:</strong> children&rsquo;s risk assessments due. Children&rsquo;s safety codes in force from 25 July.</li>
<li><strong>7 April 2026:</strong> user-to-user services must report child sexual abuse content to the NCA.</li>
<li><strong>10 July 2026:</strong> Ofcom published the register of categorised services, the small group that gets extra duties.</li>
</ul>
<p>A service launched since then has three months from launch for its first illegal content risk assessment and children&rsquo;s access assessment, <a href="https://www.legislation.gov.uk/ukpga/2023/50/schedule/3">per Schedule 3</a>. Next: the government <a href="https://www.gov.uk/government/consultations/growing-up-in-the-online-world-a-national-consultation/outcome/growing-up-in-the-online-world-government-response-july-2026">plans to stop social media services offering accounts to under-16s</a>, with regulations laid by the end of 2026 and in force in spring 2027.</p>
<h2>What has Ofcom fined so far?</h2>
<p>Fines can reach £18 million or 10% of qualifying worldwide revenue, whichever is greater. Actual ones, from Ofcom&rsquo;s announcements:</p>
<ul>
<li><strong>4 December 2025:</strong> AVS Group Ltd, <a href="https://www.ofcom.org.uk/online-safety/protecting-children/ofcom-fines-porn-company-1million-for-not-having-robust-age-checks">£1 million</a>. It had what it called age verification; Ofcom didn&rsquo;t consider it highly effective. Plus £50,000 for ignoring information requests.</li>
<li><strong>17 December 2025:</strong> a file-sharing service, <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/ofcom-fines-online-file-sharing-service-20000">£20,000</a>, for ignoring information requests.</li>
<li><strong>23 February 2026:</strong> 8579 LLC, <a href="https://www.ofcom.org.uk/online-safety/protecting-children/ofcom-fines-porn-company-1.35-million-for-not-having-age-checks">£1.35 million</a> for no age checks.</li>
<li><strong>19 March 2026:</strong> 4chan, <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/4chan-fined-450000-for-not-protecting-children-from-online-pornography">£450,000</a> for no age checks, £50,000 for no illegal content risk assessment and £20,000 for its terms of service.</li>
<li><strong>13 May 2026:</strong> a suicide forum&rsquo;s provider, £950,000.</li>
<li><strong>9 July 2026:</strong> the provider of fapello.com, <a href="https://www.ofcom.org.uk/online-safety/protecting-children/ofcom-fines-porn-company-630000-for-age-check-failings">£600,000</a> for no age checks, plus £30,000 for a late answer.</li>
</ul>
<p>Open investigations show where it&rsquo;s heading. <a href="https://www.ofcom.org.uk/online-safety/protecting-children/investigation-into-tiktoks-compliance-with-duties-to-protect-children-from-encountering-harmful-content-under-section-12">TikTok</a>, since 16 July 2026, over whether its age checks spot children. <a href="https://www.ofcom.org.uk/online-safety/protecting-children/ofcom-launches-investigation-into-pornhubs-age-checks">Aylo</a>, Pornhub&rsquo;s provider, since 23 September, over a check relying on signals from Apple: the provider stays responsible, wherever the check happens. <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/ofcom-investigates-metas-compliance-with-uk-online-safety-laws">Meta</a>, since 6 October, over whether it risk assessed a new Instagram feature before launch.</p>
<h2>What counts as highly effective age assurance?</h2>
<p>Ofcom&rsquo;s <a href="https://www.ofcom.org.uk/online-safety/illegal-and-harmful-content/age-assurance">guidance of 16 January 2025</a> judges every check on four criteria: technically accurate, robust, reliable and fair. Seven kinds can meet them: open banking, photo ID matching, facial age estimation, mobile network checks, credit card checks, digital identity services and email-based age estimation.</p>
<p>Three can&rsquo;t: users stating their age, payment methods that don&rsquo;t require the user to be 18, such as debit cards, and terms saying children aren&rsquo;t allowed. The check must come before any harmful content shows, and you mustn&rsquo;t point children to ways round it, such as VPNs.</p>
<p>Which method to pick, what each gives away and what it costs is in my <a href="https://tawfik.tv/notes/prove-age-without-id">guide to proving age without ID</a>.</p>
<h2>What should you do this month?</h2>
<ol>
<li><strong>Write down whether you&rsquo;re in scope, and why.</strong> Date it and keep it.</li>
<li><strong>Find your illegal content risk assessment.</strong> No record means no assessment, and 4chan paid £50,000 for that.</li>
<li><strong>Write your children&rsquo;s access assessment.</strong> If it says children can&rsquo;t get in, keep evidence your age check is highly effective.</li>
<li><strong>Gate your releases.</strong> No significant feature ships before both assessments are updated.</li>
<li><strong>Test your age check against the four criteria,</strong> including any check a third party runs for you.</li>
<li><strong>Name one person for Ofcom&rsquo;s information requests.</strong> A missed deadline is a separate fine.</li>
<li><strong>If users can post, register with the NCA&rsquo;s reporting portal.</strong></li>
<li><strong>If you run anything like social media, plan for the under-16 rules.</strong></li>
</ol>
<h2>How I&rsquo;d build age checks into a product</h2>
<p>The law asks one question, is this user a child, and most checks answer it by collecting a passport or a face. That builds the thing you least want to hold: a database of IDs.</p>
<p>I led a credential product where nurses and doctors prove their licences to employers: each licence is checked once at the source, sealed to the professional&rsquo;s own key, and shared field by field. It&rsquo;s one of the builds in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">my forward deployed engineer write-up</a>. At PLAYERUNKNOWN Productions I designed a zero-knowledge ID: the game learns a player is real without learning who they are. The long version is <a href="https://tawfik.tv/notes/prove-the-fact">How to prove who someone is without seeing who they are</a>.</p>
<p>For an Online Safety Act build, the same rules: ask for one fact, keep the yes and delete the rest, record why you chose the method, and assess again before every change.</p>
<h2>Questions people ask</h2>
<h3>Does the Online Safety Act apply to websites outside the UK?</h3>
<p>Yes, if UK users are a significant number or a target market, or if people in the UK can use it and it presents a material risk of significant harm to them. Ofcom has fined providers based outside the UK.</p>
<h3>Does the Online Safety Act apply to small websites?</h3>
<p>Size doesn&rsquo;t take you out: a small forum or app where users post or message each other is in scope. The government says duties are <a href="https://www.gov.uk/government/publications/online-safety-act-explainer/online-safety-act-explainer">proportionate to risk and to each provider&rsquo;s size and capacity</a>.</p>
<h3>Do I need age verification on my website?</h3>
<p>If you publish porn, yes. If children are likely to use your service and you allow porn, or content encouraging suicide, self-harm or eating disorders, yes. Otherwise the assessments still apply, but age checks may not.</p>
<h3>When did age verification start in the UK?</h3>
<p>For sites that publish porn, 17 January 2025. For user-to-user and search services that must protect children, 25 July 2025.</p>
<h3>What is the fine for breaking the Online Safety Act?</h3>
<p>Up to £18 million or 10% of qualifying worldwide revenue, whichever is greater. Fines so far run from £20,000 to £1.35 million, plus daily penalties until a provider complies.</p>
<h3>Can you help my company comply?</h3>
<p>I design and build the product side: age checks that collect one fact, the records behind them and the release gates, as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> or hands on. If you need this built, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>&quot;Verifiable credentials: what they are, how they work, and how to build one&quot;</title><link>https://tawfik.tv/notes/verifiable-credentials</link><guid>https://tawfik.tv/notes/verifiable-credentials</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A verifiable credential is a digital licence, diploma or ID signed by whoever issued it, so anyone can check it in seconds without calling the issuer.</description>
<content:encoded><![CDATA[<p>A verifiable credential is a digital version of a licence, diploma or ID card, signed by whoever issued it, so anyone you show it to can check in seconds that it is real, unchanged and still valid. You keep it in a wallet on your phone and choose which parts to show.</p>
<p>The standard is settled. The W3C published <a href="https://www.w3.org/TR/vc-data-model-2.0/">Verifiable Credentials Data Model 2.0 as a Recommendation on 15 May 2025</a>, and Europe&rsquo;s member states must offer every citizen a digital identity wallet that holds credentials like these <a href="https://ec.europa.eu/digital-building-blocks/sites/display/EUDIGITALIDENTITYWALLET/The%2BDigital%2BIdentity%2BRegulation%2BEnters%2Binto%2BForce">by 2026</a>.</p>
<p>I&rsquo;ve built identity products three times around one rule: prove the fact, not the person. The long version, with all three builds, is in <a href="https://tawfik.tv/notes/prove-the-fact">How to prove who someone is without seeing who they are</a>. This page is the plain guide to the format underneath.</p>
<h2>What are verifiable credentials?</h2>
<p>A verifiable credential is a set of claims about someone, such as &ldquo;Hannah Clarke is a registered nurse, licence active until March 2027&rdquo;, with a digital signature from the body that made those claims. Three parties are involved, and the W3C standard names them:</p>
<ol>
<li><strong>The issuer</strong> makes the claims and signs them: a nursing board, a university, a government.</li>
<li><strong>The holder</strong> keeps the credential, usually in a wallet app, and decides when to show it: the nurse.</li>
<li><strong>The verifier</strong> receives it and checks it: the hospital.</li>
</ol>
<p>The verifier never has to phone the issuer. The signature carries the proof.</p>
<h2>How does a verifiable credential work?</h2>
<p>Four steps, from issue to check.</p>
<ol>
<li><strong>Issue.</strong> The nursing board checks Hannah&rsquo;s licence against its own register, puts the facts into a credential and signs it with its private key. Only the board has that key.</li>
<li><strong>Hold.</strong> The credential lands in a wallet on Hannah&rsquo;s phone.</li>
<li><strong>Present.</strong> A hospital asks for her licence. Her wallet shows what is asked for, and she picks the fields to send.</li>
<li><strong>Verify.</strong> The hospital runs three checks. Is the signature valid against the board&rsquo;s public key? Is the board on the list of issuers the hospital trusts? Has the board revoked the licence since?</li>
</ol>
<p>The third check is the clever one. Under the W3C <a href="https://www.w3.org/TR/vc-bitstring-status-list/">Bitstring Status List</a>, a Recommendation since 15 May 2025, the issuer publishes one long list of bits, at least 131,072 of them, and each credential points at one position. A 0 means fine, a 1 means revoked. The verifier downloads the whole list, so the issuer never learns whose credential was checked.</p>
<p>The hospital finds the board&rsquo;s public key through a decentralised identifier, a DID: an identifier that needs no central registry, <a href="https://www.w3.org/TR/did-1.0/">a W3C Recommendation since 19 July 2022</a>. <code>did:web:nursing-board.example</code> simply points at a file on the board&rsquo;s own website.</p>
<p>Try it below. Pick what the hospital sees, then try to cheat: change the expiry date, sign it with your own key, or have the board suspend the licence. Each one breaks a different check.</p>
<p><a href="https://tawfik.tv/notes/verifiable-credentials">Open the interactive diagram on tawfik.tv</a></p>

<h2>What does a verifiable credential look like?</h2>
<p>It is a small JSON file. This example comes from the <a href="https://www.w3.org/TR/vc-data-model-2.0/">W3C specification</a>, unchanged:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://www.w3.org/ns/credentials/examples/v2"
  ],
  "id": "http://university.example/credentials/58473",
  "type": ["VerifiableCredential", "ExampleAlumniCredential"],
  "issuer": "did:example:2g55q912ec3476eba2l9812ecbfe",
  "validFrom": "2010-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "alumniOf": {
      "id": "did:example:c276e12ec21ebfeb1f712ebc6f1",
      "name": "Example University"
    }
  }
}</pre>

<p><code>issuer</code> is who signed it, <code>credentialSubject</code> is who it is about and what is claimed, and <code>validFrom</code> is when it starts. The signature is added on top. To make it revocable, the issuer adds a status entry, as in the <a href="https://www.w3.org/TR/vc-bitstring-status-list/">Bitstring Status List spec</a>:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">"credentialStatus": {
  "id": "https://example.com/credentials/status/3#94567",
  "type": "BitstringStatusListEntry",
  "statusPurpose": "revocation",
  "statusListIndex": "94567",
  "statusListCredential": "https://example.com/credentials/status/3"
}</pre>

<h2>What is selective disclosure?</h2>
<p>Selective disclosure lets the holder show some fields and keep the rest back, while the verifier can still check that each shown field was signed by the issuer. In the common formats, the issuer signs a list of sealed fingerprints, one per field, and the holder opens only the ones the verifier needs. That is how the hospital in the demo gets name, licence, status and expiry, and never sees the date of birth or home address.</p>
<p><a href="https://tawfik.tv/notes/prove-the-fact">Prove the fact, not the person</a> has a hands-on sealed envelope demo, and <a href="https://tawfik.tv/notes/prove-age-without-id">how to prove you&rsquo;re over 18 without showing your ID</a> covers SD-JWT and zero-knowledge proofs, where the verifier learns only &ldquo;yes&rdquo;.</p>
<h2>How is a verifiable credential different from a PDF certificate or a database lookup?</h2>
<ul>
<li><strong>A PDF certificate</strong> is a picture of a claim. Anyone can edit it, and the only real check is to call the issuer.</li>
<li><strong>A database lookup</strong> is accurate, but the verifier has to reach the issuer&rsquo;s system every time, the issuer sees every check, and each issuer has its own website and format.</li>
<li><strong>A verifiable credential</strong> is checked by maths, in seconds, with no call to the issuer. The issuer learns nothing about where it was used. The holder carries it from job to job, and a change to any signed field makes it fail.</li>
</ul>
<h2>Verifiable credentials vs KYC software: which do you need?</h2>
<p>KYC software and identity verification software check a person from scratch, usually with a document scan, a liveness check and a face match, priced per check: list prices for a full ID check ran from $0.33 to $1.89 when I compared vendors in <a href="https://tawfik.tv/notes/prove-age-without-id">the age verification guide</a>. A verifiable credential is what can come out of a check like that: the result, signed by whoever did it, so the next verifier checks a signature instead of running the whole check again. So the two fit together. Use KYC software where you must know the person for the first time, such as when money moves, and issue or accept a credential so they do not repeat it at every stop. I build the credential side, the issuer, the wallet and the verifier; I do not sell KYC software.</p>
<h2>Which standards matter in 2026?</h2>
<ul>
<li><strong><a href="https://www.w3.org/TR/vc-data-model-2.0/">W3C Verifiable Credentials Data Model 2.0</a></strong>, Recommendation, 15 May 2025: the shape of the credential and the three roles.</li>
<li><strong><a href="https://www.w3.org/TR/did-1.0/">W3C DID 1.0</a></strong>, Recommendation, 19 July 2022: how a verifier finds the issuer&rsquo;s public key.</li>
<li><strong><a href="https://openid.net/openid-for-verifiable-credential-issuance-1-final-specification-approved/">OpenID for Verifiable Credential Issuance 1.0</a></strong>, approved as a Final Specification, announced 16 September 2025: how an issuer delivers a credential into a wallet.</li>
<li><strong><a href="https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html">OpenID for Verifiable Presentations 1.0</a></strong>, Final, 9 July 2025: how a verifier asks a wallet for credentials. It works with W3C credentials, ISO mdoc and SD-JWT VC.</li>
<li><strong><a href="https://webstore.iec.ch/publication/71432">ISO/IEC 18013-5</a></strong>, published 30 September 2021: the mobile driving licence, a different format built on the same issuer, holder and verifier model.</li>
</ul>
<h2>Where are verifiable credentials used now?</h2>
<ul>
<li><strong>Education.</strong> 1EdTech&rsquo;s <a href="https://www.imsglobal.org/spec/ob/v3p0">Open Badges 3.0</a> aligns with the W3C Verifiable Credentials Data Model 2.0 for achievements and skills.</li>
<li><strong>Health workforce.</strong> The NHS has been building a <a href="https://gov.uk/service-standard-reports/nhs-digital-staff-passport">Digital Staff Passport</a> on the W3C data model, starting with doctors in training, so staff can move between NHS organisations without repeating the same paperwork and checks.</li>
<li><strong>Age.</strong> The EU&rsquo;s <a href="https://digital-strategy.ec.europa.eu/en/factpages/blueprint-age-verification-solution-help-protect-minors-online">age verification blueprint</a> gives people a proof of age held on their phone, and Ofcom counts digital identity services among the methods that can be highly effective under the Online Safety Act. The <a href="https://tawfik.tv/notes/online-safety-act-age-verification">Online Safety Act guide</a> covers who must check, and the <a href="https://tawfik.tv/notes/prove-age-without-id">age proof guide</a> covers how.</li>
<li><strong>Travel.</strong> Apple <a href="https://www.apple.com/newsroom/2025/11/apple-introduces-digital-id-a-new-way-to-create-and-present-an-id-in-apple-wallet/">launched Digital ID on 12 November 2025</a>, an ID in Apple Wallet made from a U.S. passport, rolling out first in beta at TSA checkpoints in more than 250 U.S. airports. Apple says only the information needed for a transaction is presented.</li>
<li><strong>Government ID.</strong> The EU Digital Identity Regulation <a href="https://ec.europa.eu/digital-building-blocks/sites/display/EUDIGITALIDENTITYWALLET/The%2BDigital%2BIdentity%2BRegulation%2BEnters%2Binto%2BForce">entered into force on 20 May 2024</a>. The Commission says the wallets will hold <a href="https://digital-strategy.ec.europa.eu/en/policies/eudi-regulation">driving licences, diplomas and bank accounts</a>, and let people choose which parts they share.</li>
</ul>
<h2>How do you build a verifiable credentials system?</h2>
<ol>
<li><strong>Pick the one claim.</strong> &ldquo;Licence active&rdquo; or &ldquo;over 18&rdquo;, not a whole file. Decide who issues it and who will check it.</li>
<li><strong>Build the issuer.</strong> It checks the facts at the source, signs the credential with a key it guards, publishes its public key (a <code>did:web</code> file is the simplest start), gives every credential a slot in a status list, and hands it to the wallet over OpenID4VCI.</li>
<li><strong>Choose the wallet.</strong> Use one people already have, such as a national EU wallet, or build your own app when the credential lives in your product. Bind each credential to a key on the device, so a copied file is useless without the phone.</li>
<li><strong>Build the verifier.</strong> It asks for named fields over OpenID4VP and runs the checks from the demo: signature, trusted issuer, status, expiry, and that the holder&rsquo;s own key signed this presentation.</li>
<li><strong>Plan the boring parts first.</strong> Revocation, re-issue when a phone is lost, rotating the issuer&rsquo;s key, and what the verifier does when the status list is out of date.</li>
</ol>
<p>I led a credential passport app for clinicians: a licence nurses and doctors share without their whole file. Licences are verified against the issuing authority, the clinician ticks which fields each employer gets, names the one recipient, and can revoke the share at any time. Before that, at PLAYERUNKNOWN Productions, I designed a zero-knowledge player ID, where the game learns a player is real and not who they are, and at NOR, where I led technology, we built a game login on Holochain that never touched the player&rsquo;s keys. All three are written up in <a href="https://tawfik.tv/notes/prove-the-fact">prove the fact</a>, and the clinician app also appears in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer: four AI and fintech builds</a>.</p>
<h2>Questions people ask</h2>
<h3>Are verifiable credentials on a blockchain?</h3>
<p>They don&rsquo;t need one. Checking a credential needs the issuer&rsquo;s public key and its status list, and both can sit on an ordinary website.</p>
<h3>What is the difference between a verifiable credential and a digital ID?</h3>
<p>A digital ID is one kind of verifiable credential: claims about who you are. A licence, a degree or a proof of age are credentials too, and one wallet can hold many.</p>
<h3>Can verifiable credentials be used for KYB verification?</h3>
<p>For the result, yes; the check itself still has to happen. KYB verification confirms who owns a business, what it does and where its money comes from, usually through a licensed partner or a KYB provider. Once that is done, the outcome can be issued as a credential, so the next bank or partner checks one signature instead of collecting the same documents again. Proving facts about a business without handing over its whole file is the idea behind <a href="https://tawfik.tv/notes/prove-the-fact">prove the fact, not the person</a>.</p>
<h3>Is a mobile driving licence a verifiable credential?</h3>
<p>In the general sense, yes: the same issuer, holder and verifier model, in the ISO mdoc format rather than the W3C one. OpenID4VP can request both.</p>
<h3>Can a verifiable credential be revoked?</h3>
<p>Yes. The issuer flips the credential&rsquo;s bit in its published status list, and the next verifier that checks sees it. The copy in the wallet doesn&rsquo;t change, which is why verifiers must check the list.</p>
<h3>Do you build this?</h3>
<p>Yes. I design and build credential and identity products end to end, as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> or hands on. If you need verifiable credentials issued, held or checked, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>Agentic AI: what it is, what it costs to run, and how to ship one safely</title><link>https://tawfik.tv/notes/agentic-ai</link><guid>https://tawfik.tv/notes/agentic-ai</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Agentic AI is software that plans, uses tools, checks the result and repeats until a task is done. What it costs, where it fails, how to ship it safely.</description>
<content:encoded><![CDATA[<p>Agentic AI is software that takes a goal, plans the steps, acts with real tools such as your inbox, your database or a company card, checks what happened and repeats until the task is done. A chatbot gives you an answer and you do the work; an agent does the work, which is why it needs limits that a chatbot never did.</p>
<p>The hype is ahead of the results. Gartner predicts that over 40% of agentic AI projects will be canceled by the end of 2027, because of escalating costs, unclear business value or inadequate risk controls (<a href="https://www.gartner.com/en/newsroom/press-releases/2025-06-25-gartner-predicts-over-40-percent-of-agentic-ai-projects-will-be-canceled-by-end-of-2027">Gartner, 25 June 2025</a>). The same release estimates that only about 130 of the thousands of agentic AI vendors are real, and warns of &ldquo;agent washing&rdquo;: chatbots and automation tools rebranded without real agentic capabilities.</p>
<p>I build agents and the guardrails around them at Instruxi. This is what I tell teams before they ship one.</p>
<h2>What is agentic AI?</h2>
<p>Agentic AI is an AI model running in a loop with tools. Each turn of the loop has four parts:</p>
<ol>
<li><strong>Plan.</strong> The model reads the goal and decides the next step.</li>
<li><strong>Act.</strong> It calls a tool: look up an order, search flights, run a database query, send an email.</li>
<li><strong>Check.</strong> It reads what the tool returned.</li>
<li><strong>Repeat.</strong> It decides whether the job is done, or what to try next.</li>
</ol>
<p>Compare that with what people usually mean by &ldquo;AI&rdquo;:</p>
<ul>
<li><strong>A chatbot</strong> answers questions. You read the answer and take the action yourself.</li>
<li><strong>A single AI call</strong> takes one input and gives one output: summarise this email, classify this ticket. Your code decides what happens next.</li>
<li><strong>An agent</strong> decides what happens next itself, including which tool to call and when to stop.</li>
</ul>
<p>There is a middle ground. Anthropic&rsquo;s engineering guide separates workflows, where &ldquo;LLMs and tools are orchestrated through predefined code paths&rdquo;, from agents, where &ldquo;LLMs dynamically direct their own processes and tool usage&rdquo; (<a href="https://www.anthropic.com/engineering/building-effective-agents">Building effective agents, December 2024</a>). Gartner makes the same point: many use cases positioned as agentic today don&rsquo;t need to be. A workflow with one or two AI steps is often enough.</p>
<h2>What is agentic AI used for in business?</h2>
<p>Agents earn their cost where the steps change from case to case and a person would otherwise click through several systems:</p>
<ul>
<li><strong>Customer support.</strong> Read the ticket, look up the order and payments, answer or hand over. I set up an AI help desk for a fintech platform. I bought the agent instead of building one, wrote the help centre it answers from, and held one rule: the agent can read and explain, and it can never change an account. When I asked it to send a customer&rsquo;s cash-out to a third party, it refused and passed the conversation to a person. The full setup is in <a href="https://tawfik.tv/notes/ai-customer-service-agent">AI customer service agent: what it can safely do</a>.</li>
<li><strong>Back office.</strong> Match invoices to purchase orders, chase missing paperwork, prepare refunds for approval.</li>
<li><strong>Travel and expenses.</strong> Find options inside the policy, book, file the receipts.</li>
<li><strong>Software.</strong> Coding agents in a terminal: Claude Code, Cursor, Codex and Gemini CLI read the code, run commands and edit files.</li>
</ul>
<h2>How much does it cost to run an AI agent?</h2>
<p>You pay per token, the chunks of text the model reads and writes. List prices on 15 October 2026, per million tokens, input then output:</p>
<ul>
<li><strong>Anthropic:</strong> Claude Haiku 5.5 $0.10 and $0.50 (prompts up to 100,000 tokens), Claude Sonnet 5.5 $2 and $10, Claude Opus 5.5 $4 and $20 (<a href="https://platform.claude.com/docs/en/about-claude/pricing">pricing</a>).</li>
<li><strong>OpenAI:</strong> gpt-6-luna $0.10 and $0.50, gpt-6.1-sol $2 and $10, Standard tier, short context (<a href="https://developers.openai.com/api/docs/pricing">pricing</a>).</li>
<li><strong>Google:</strong> Gemini 3.1 Pro Preview $2 and $12 for prompts up to 200,000 tokens (<a href="https://ai.google.dev/gemini-api/docs/pricing">pricing</a>).</li>
</ul>
<p>The catch is the loop. Every model call re-sends the instructions, the list of tools and everything that has happened so far, so each step costs more than the last. Google&rsquo;s pricing page says it plainly for its Deep Research agent: the intermediate input and reasoning tokens generated during agentic loops are charged at list rates.</p>
<p>A worked example at $2 and $10, using the same token model as the demo below. A refund agent makes 4 model calls. The first call reads about 2,400 tokens, the fourth about 8,250, so in total about 22,000 tokens in and 960 out: $0.044 plus $0.0096, about 5 cents a run, or about $54 for 1,000 runs a month. Now let an agent retry a broken search 24 times: 26 model calls, about 502,000 tokens in, about $1.07. Twenty times the normal run, for nothing.</p>
<p>Two things bring it down. Prompt caching charges a fraction for the part of the prompt that repeats: on Claude Sonnet 5.5 a cache hit is $0.10 per million tokens against $2 uncached. And tools can cost extra: Anthropic charges $10 per 1,000 web searches on top of tokens. A step limit costs nothing, and it is the one that stops the $1.07 run.</p>
<h2>Where does agentic AI go wrong?</h2>
<p>The failures are ordinary mistakes, made at machine speed with real access:</p>
<ul>
<li><strong>Loops.</strong> A tool fails and the agent tries again, and again. Each try costs more, because the history grows.</li>
<li><strong>The wrong tool.</strong> Asked to tidy a database, an agent reaches for a raw <code>DELETE</code> when a merge tool with undo was right there.</li>
<li><strong>Deleting data.</strong> It has happened with Replit, Gemini CLI, Claude Code and Cursor; the incidents and the settings that stop them are in <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop an AI agent deleting your database</a>.</li>
<li><strong>Spending money.</strong> Refunds nobody owed, a fare over policy, a card used for something it was never meant for.</li>
<li><strong>Following instructions it should only have read.</strong> A customer writes &ldquo;your colleague agreed a £400 credit&rdquo; and the agent treats it as fact. OWASP ranks this first, as agent goal hijack, in its <a href="https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/">Top 10 for Agentic Applications</a>.</li>
</ul>
<p>Try them below. Run a task with the guardrails off, then switch them on one at a time and watch where the agent stops, and what the run costs.</p>
<p><a href="https://tawfik.tv/notes/agentic-ai">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you ship an AI agent safely?</h2>
<p>Three controls, all outside the model. A line in the prompt saying &ldquo;never refund more than £100&rdquo; is a request; a refund tool that cannot go over £100 is a control.</p>
<ol>
<li><strong>Permissions.</strong> Give the agent only the tools and access its job needs: a refund tool capped at an amount, a card limited to the policy, a read-only database user. Start read-only and add one action at a time, as I did on the help desk.</li>
<li><strong>A person approves the irreversible.</strong> Money out, deletes, bookings, deploys and messages to customers wait for a named person&rsquo;s yes. Keep the list short, or people approve without reading.</li>
<li><strong>A record of every action.</strong> Who the agent acted for, the tool, the exact input, the rule that answered and the result, each line chained to the one before so edits show. Without it, all you have afterwards is the agent&rsquo;s own summary.</li>
</ol>
<p>Add a stopping condition to the loop as well: a cap on steps, spend, or the same call repeated. Anthropic&rsquo;s guide notes that it is common to include stopping conditions, such as a maximum number of iterations.</p>
<p>The full programme for running many agents (inventory, owners, review cadence, incident playbook, and how it maps to NIST, ISO/IEC 42001 and the EU AI Act) is in <a href="https://tawfik.tv/notes/ai-agent-governance">AI agent governance: a practical framework</a>. If your agent reaches its tools over MCP, run the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> first.</p>
<h2>What I build</h2>
<p>I lead product for <a href="https://gvnr.io">GVNR</a> at Instruxi: a free, source-available guard for AI agents, licensed FSL-1.1-ALv2 (<a href="https://github.com/instruxi-io/enforcer-governor">code on GitHub</a>). It works with any AI agent, including Claude Code, Cursor, Codex, Gemini CLI and any MCP client. Before each action it answers allow, deny or ask a person, and it keeps a hash-chained record of every decision. Its defaults stop an agent that repeats the same action four times in its last eight, and ask when spend passes $2 a minute or 75% of a $20 cap. The step limit in the demo above uses that rule.</p>
<p>The same pattern runs through my <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed work</a>, such as a bank-in-a-box demo where a checkpoint opens or holds a customer&rsquo;s money with a plain-English reason, from 11 ordered rules. An agent that can act needs something that decides first.</p>
<h2>Questions people ask</h2>
<h3>What is agentic AI in simple terms?</h3>
<p>AI that does a task for you instead of only answering: it plans the steps, uses tools, checks the result and keeps going until the job is done.</p>
<h3>What is the difference between agentic AI and a chatbot?</h3>
<p>A chatbot answers and you act. An agent acts: it calls tools that look things up, change records, send messages or spend money, so it needs permissions and limits.</p>
<h3>How much does it cost to run an AI agent?</h3>
<p>A few cents per run for a short task on a mid-priced model, about 5 cents in my example at $2 and $10 per million tokens. Loops are the risk: one runaway run in my example cost twenty times a normal one.</p>
<h3>Is agentic AI safe for a business?</h3>
<p>Yes, if the agent holds only the access its job needs, a person approves anything irreversible, and every action is recorded. Without those three, a mistake runs at machine speed.</p>
<p>If you need an agent designed and shipped with these guardrails, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>AI receptionist: what an AI voice agent does on your phone line, what it costs, and what it must never do</title><link>https://tawfik.tv/notes/ai-receptionist-voice-agent</link><guid>https://tawfik.tv/notes/ai-receptionist-voice-agent</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>An AI receptionist answers your phone, books and moves appointments, takes messages and hands urgent calls to a person. Costs, risks and setup.</description>
<content:encoded><![CDATA[<p>An AI receptionist is an AI voice agent that answers your business phone, books and moves appointments in your calendar, answers questions from your own price list and notes, takes messages, and puts urgent or difficult calls through to a person. It should say it is an AI in its first sentence, and it should never take a card payment, agree a discount or read out anyone&rsquo;s records.</p>
<p>The job it covers is large. US employers had about <a href="https://www.bls.gov/ooh/office-and-administrative-support/receptionists.htm">947,500 receptionist jobs in 2025</a>, 42% of them in healthcare and social assistance, and the Bureau of Labor Statistics expects that number to fall 2% by 2035, partly because organisations &ldquo;continue to automate or consolidate administrative functions&rdquo;.</p>
<p>I set up an AI help desk for a fintech platform with one rule: the agent can read and explain, and never change an account. I also build online booking with Wallet stamp cards for local businesses. A phone agent talks like the help desk and writes into the booking calendar, so it needs the limits of both.</p>
<h2>What is an AI receptionist?</h2>
<p>It is an <a href="https://tawfik.tv/notes/what-is-an-ai-agent">AI agent</a> whose only channel is a phone call. The four jobs it does well:</p>
<ul>
<li><strong>Answers every call</strong>, after hours and when two lines ring at once.</li>
<li><strong>Books, moves and cancels appointments</strong> in the calendar your staff already use.</li>
<li><strong>Answers routine questions</strong> from your own notes: prices, opening hours, parking, what to bring.</li>
<li><strong>Routes and takes messages</strong>: an emergency goes straight to a person, a sales question becomes a message with a callback number, and the team gets a written summary of every call.</li>
</ul>
<p>&ldquo;AI voice agent&rdquo; is the wider term: the same parts can make reminder calls or run a sales line. If your customers mostly write to you, the chat version is in <a href="https://tawfik.tv/notes/ai-customer-service-agent">AI customer service agent</a>, and putting a bot on your site is in <a href="https://tawfik.tv/notes/ai-chatbot-for-website">AI chatbot for your website</a>.</p>
<h2>How does an AI voice agent work?</h2>
<p>Five parts run in a loop for every turn of the conversation:</p>
<ol>
<li><strong>Telephony.</strong> Your number forwards to the vendor, or you take a new number from them. The call arrives as audio.</li>
<li><strong>Speech to text.</strong> The caller&rsquo;s words become text as they speak.</li>
<li><strong>The model.</strong> It reads your instructions, the conversation so far and the results of any tools, then decides what to say or which tool to call.</li>
<li><strong>Tools.</strong> Small functions you allow: find free slots, book, look up a price, take a message, transfer. Each is a door into a real system, so the tool list matters more than the prompt.</li>
<li><strong>Text to speech.</strong> The reply is spoken back, and the loop repeats until the call ends.</li>
</ol>
<p>It is the loop from <a href="https://tawfik.tv/notes/agentic-ai">agentic AI</a>, with one difference: the caller hears every pause, so keep tools and answers short.</p>
<p>Try it on a made-up London dental practice: pick a caller, switch to night service, and set your call volume.</p>
<p><a href="https://tawfik.tv/notes/ai-receptionist-voice-agent">Open the interactive diagram on tawfik.tv</a></p>

<h2>How much does an AI receptionist cost?</h2>
<p>Either a finished receptionist priced per call or per bundle of minutes, or a developer platform priced per minute. US list prices, checked on each pricing page in October 2026:</p>
<ul>
<li><strong><a href="https://smith.ai/pricing/ai-receptionist">Smith.ai AI Receptionist</a></strong>: free for 25 calls a month, then $3.00 a call. Paid plans are $150 a month for 75 calls and $500 a month for 300, with extra calls at $2.50 down to $2.10. Every answered call counts, except known spam. Transfer to a live receptionist is available.</li>
<li><strong><a href="https://heyrosie.com/pricing">Rosie</a></strong>: $49 a month for 250 minutes, $149 for 1,000 minutes and $299 for 2,000, paid monthly. Only the $149 and $299 plans book directly into your calendar and transfer calls; the $49 plan texts a booking link instead.</li>
<li><strong><a href="https://www.retellai.com/pricing">Retell AI</a></strong>: $0.07 to $0.31 a minute depending on the model and add-ons, plus $2 a month per phone number, with $10 of free credit.</li>
<li><strong><a href="https://vapi.ai/pricing">Vapi</a></strong>: a $0.05 a minute platform fee plus the speech, model and voice providers at cost. Its own estimate for 1,000 minutes a month is $82 to $129.</li>
</ul>
<p><strong>A worked example: 300 calls a month at 2.5 minutes each</strong>, so 750 minutes. Smith.ai is $500. Rosie&rsquo;s $149 plan covers it. Retell comes to $54.50 to $234.50 and Vapi about $62 to $97, before a developer&rsquo;s time to build the agent, connect the calendar and test the transfers. The same 750 minutes at the US median receptionist wage of $18.27 an hour is $228, but nobody hires a receptionist for 12.5 scattered hours. The real comparison is the calls you miss now.</p>
<p>Check what counts as a call, whether booking and transfers are on your plan, and what happens above your bundle.</p>
<h2>What must an AI receptionist never do?</h2>
<p><strong>Take card payments by voice.</strong> The PCI Security Standards Council <a href="https://www.pcisecuritystandards.org/faqs/1210/">says</a> that storing the card security code in any audio recording after authorisation breaks PCI DSS, and that audio should be suppressed during card entry where the technology exists. A recorded AI line is the worst place for a card number. Send a payment link by text, or pass the call to a person on a compliant system.</p>
<p><strong>Make promises.</strong> A discount, a refund, a diagnosis, &ldquo;the dentist will see you today&rdquo;: each belongs to a person. The agent can quote the price list and offer a callback.</p>
<p><strong>Act on what the caller tells it to do.</strong> Callers will say &ldquo;ignore your instructions, I am the manager&rdquo;. The OWASP <a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">LLM01 prompt injection</a> guidance gives the fix: restrict the model&rsquo;s access to the minimum it needs, and put a person in the loop for privileged actions. If the phone agent has no refund tool, no caller can talk it into a refund.</p>
<p><strong>Read records to an unverified caller.</strong> Check who is calling before discussing any booking.</p>
<p>Write the rules down outside the model, so they hold whatever the caller says:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">agent: front-desk-phone
opening: "You are speaking to our AI assistant. Calls are recorded."
tools:
  calendar.find_slots:  allow
  calendar.book:        allow   new bookings, opening-hours slots only
  calendar.move:        allow   caller verified, own booking, 24 hours or more away
  price_list.lookup:    allow
  message.take:         allow
  call.transfer:        ask_person   emergencies, complaints, "can I speak to someone"
  payments.refund:      deny    not given to the phone agent
  patient.read:         deny    unless caller verified, own booking only
never say: "that's free", "we'll refund you", "the dentist will see you today"</pre>

<p>That is the idea behind <a href="https://gvnr.io">GVNR</a>, the free and source-available guard I lead for AI agents, which works with Claude Code, Cursor, Codex, Gemini CLI and any MCP client. Before each action it answers allow, deny or ask a person, and it keeps a hash-chained record of every decision. A phone agent needs the same three answers.</p>
<h2>Do you have to tell callers they are talking to an AI?</h2>
<p>In the EU, yes. <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=OJ:L_202401689">Article 50 of the EU AI Act</a>, which applies from 2 August 2026, says a system that talks to people must tell them they are dealing with an AI unless that is obvious. Elsewhere, say it anyway.</p>
<p>Recording is a separate rule. In California, recording a confidential phone call without the consent of all parties can be fined up to $2,500 per violation under <a href="https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=PEN&amp;sectionNum=632">Penal Code section 632</a>. Say &ldquo;calls are recorded&rdquo; in the opening line, and check the rules where you and your callers are.</p>
<p>If the agent also calls people back, the US Federal Communications Commission <a href="https://docs.fcc.gov/public/attachments/FCC-24-17A1.pdf">ruled in February 2024</a> that AI-generated voices count as &ldquo;artificial&rdquo; voices under the Telephone Consumer Protection Act, so those calls need the called party&rsquo;s prior express consent unless an exemption applies.</p>
<h2>How do you set up an AI receptionist for a small business?</h2>
<ol>
<li><strong>List why people call.</strong> Go through a week of calls and your missed-call log, and write one answer or action for each reason.</li>
<li><strong>Connect the booking calendar</strong> your staff already use, with each service&rsquo;s length and buffers, never a second diary. On my <a href="https://tawfik.tv/notes/digital-stamp-card">booking and Wallet loyalty</a> builds, every booking lands in one list and a completed visit adds a stamp to the customer&rsquo;s card; a phone booking belongs in that same list.</li>
<li><strong>Set your hours and the night rule.</strong> In hours, urgent calls go to the front desk; out of hours, to an on-call number or a message.</li>
<li><strong>Name the handover numbers and triggers</strong>: emergencies, complaints, anything about money, and anyone who asks for a person. Keep that one step away at all times.</li>
<li><strong>Write the opening line</strong>: the business name, &ldquo;AI assistant&rdquo;, and the recording notice.</li>
<li><strong>Test 30 calls before going live</strong>, including a caller asking about someone else&rsquo;s appointment, a refund demand and an emergency.</li>
<li><strong>Forward the line in office hours first</strong>, with someone reading every summary, then extend to evenings and weekends.</li>
</ol>
<h2>Questions people ask</h2>
<h3>Is an AI receptionist worth it for a small business?</h3>
<p>If you miss calls when staff are busy or closed, usually yes. The plans that book and transfer start around $150 a month, about one 8-hour day at the US median receptionist wage. If you answer nearly every call already, start with after-hours only.</p>
<h3>Can an AI receptionist take payments over the phone?</h3>
<p>It should not take card numbers by voice. Have it text a secure payment link, or pass the call to a person on a PCI-compliant system.</p>
<h3>What is the difference between an AI receptionist and an answering service?</h3>
<p>An answering service puts a person on your line. An AI receptionist takes several calls at once and books straight into your calendar, but needs written rules and a person to hand over to.</p>
<h3>Will it work with my booking system?</h3>
<p>If your booking tool lets other software read and write bookings, often yes. Smith.ai, for example, lists a Calendly integration on every plan; a custom build can connect to any booking tool with an API.</p>
<p>If you want an AI receptionist set up with these limits, or booking and loyalty around it, see <a href="https://tawfik.tv/hire/ai-consultant">AI consulting</a> or <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and Wallet loyalty</a>, or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>How to accept InstaPay on your website and confirm payments automatically</title><link>https://tawfik.tv/notes/instapay-auto-confirm</link><guid>https://tawfik.tv/notes/instapay-auto-confirm</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Give each order an exact amount, forward your bank&#x27;s incoming-transfer texts to a matcher, and mark the order paid when the amount and a second sign agree.</description>
<content:encoded><![CDATA[<p>To accept InstaPay on a website, show each order an exact amount and your InstaPay address, let the customer pay from their own bank app, then confirm it from your bank&rsquo;s &ldquo;money in&rdquo; text. Forward that text to a small matcher that marks the order paid when the amount and one more sign agree.</p>
<p>That is worth getting right, because InstaPay is now how a large part of Egypt pays. By the end of Q2 2026, Egypt&rsquo;s Instant Payment Network had nearly 22 million registered customers and 1.47 billion processed transactions worth around EGP 4.33 trillion, <a href="https://www.cbe.org.eg/en/news-publications/news/2026/10/01/08/19/the-50th-annual-meeting-of-the-council-of-arab-central-banks">according to the Central Bank of Egypt</a>.</p>
<p>I built InstaPlug, my own product that does this confirmation for any website, app or AI agent. The same matching runs a dog club&rsquo;s bookings. Here is how it works, and what happens when customers do the unexpected.</p>
<h2>What is InstaPay?</h2>
<p>InstaPay is Egypt&rsquo;s instant payment app. It runs on the Instant Payment Network, a national network linking all banks operating in Egypt, which the Central Bank of Egypt <a href="https://www.cbe.org.eg/en/payment-systems-and-services/instant-payment-network">launched on 22 March 2022</a>. The app is published by the <a href="https://play.google.com/store/apps/details?id=com.egyptianbanks.instapay">Egyptian Banks Company</a>.</p>
<p>The facts that matter for a business, from <a href="https://www.instapay.eg/?lang=en">InstaPay&rsquo;s own site</a> and the CBE:</p>
<ul>
<li><strong>Limits:</strong> EGP 70,000 per transaction, EGP 120,000 a day and EGP 400,000 a month, per bank registered in the app.</li>
<li><strong>Fees:</strong> 0.1% of the transfer, at least EGP 0.50 and at most EGP 20, applied from 1 April 2025.</li>
<li><strong>Addresses:</strong> you can receive on your mobile number, your account number, or an Instant Payment Address that looks like name@instapay.</li>
<li><strong>Status:</strong> a transfer is successful, rejected or pending. Pending means the receiving bank will execute it shortly.</li>
</ul>
<h2>Is there an InstaPay API for websites?</h2>
<p>Not one you can sign up for as a merchant. I could not find a public merchant API on instapay.eg or on the CBE&rsquo;s network page. That leaves two routes.</p>
<ol>
<li><strong>A licensed payment provider.</strong> Some Egyptian payment companies offer InstaPay inside their checkout. Kashier, for example, lists <a href="https://developers.kashier.io/docs/accept-payments">a QR code or request to pay over InstaPay</a>. You sign up as a merchant, the provider sits in the middle, and you pay its fee.</li>
<li><strong>Your own account, confirmed by your bank.</strong> The customer sends money straight to your account, as they would to anyone. Your bank already tells you when it lands, by text message. You turn that text into an automatic confirmation.</li>
</ol>
<p>InstaPlug takes the second route. Nobody sits in the middle and there is no fee on top of InstaPay&rsquo;s own. One limit I hit in testing: an InstaPay payment link opens the app with your details filled in, but not the amount, so the customer types the amount themselves. That is why the matching has to be careful.</p>
<h2>How does automatic InstaPay confirmation work?</h2>
<p>Five steps, from order to &ldquo;Paid&rdquo;.</p>
<ol>
<li><strong>Create the payment.</strong> Your website, your dashboard or an AI agent creates a payment for the price. The customer gets a pay page with the exact amount, copy buttons, your InstaPay number and, on a computer, a QR code to pay from their phone.</li>
<li><strong>The customer pays from their own bank app.</strong> They send the amount by InstaPay to your number or address.</li>
<li><strong>Your bank texts your phone.</strong> The phone that gets your account&rsquo;s alerts forwards the incoming-transfer text to your server. On an iPhone that is one Shortcuts automation. On Android, any text-forwarding app that can post to a web address.</li>
<li><strong>The matcher reads the text.</strong> It pulls out the amount, the payer&rsquo;s name and the bank&rsquo;s reference. Today it reads the Arabic texts from CIB, NBE, Banque du Caire and Banque Misr. Money going out, card withdrawals and one-time codes are ignored.</li>
<li><strong>It marks the order paid, once.</strong> The pay page turns to &ldquo;Paid&rdquo; by itself and your shop gets a signed webhook, so your own system can ship the order or confirm the booking.</li>
</ol>
<h3>Why one amount is not enough</h3>
<p>Customers pay the real price by default, because most shops sell at fixed prices. But a friend might send you exactly EGP 750 for something else on the same afternoon. So the exact amount alone never marks an order paid. One of three second signs has to agree:</p>
<ul>
<li><strong>The payer&rsquo;s first name</strong> on the bank text matches the customer&rsquo;s name.</li>
<li><strong>The customer tapped pay</strong> on the pay page (copied the number, opened InstaPay) in the last 30 minutes. This covers a parent or partner paying for someone.</li>
<li><strong>Unique amounts are on.</strong> For busy hours there is a setting where each open order asks a pound or two less, 1 to 2% of the price at most: EGP 749, then 748. If only one order asks that amount, the amount is the proof.</li>
</ul>
<p>If no sign agrees, the text waits on a check list for a person. It never pays the wrong order on a guess.</p>
<h2>What happens when something goes wrong?</h2>
<p>Most of the work is in the edge cases. In short:</p>
<ul>
<li><strong>Two orders at the same price:</strong> names or the &ldquo;tapped pay&rdquo; sign decide, or unique amounts keep them apart. With nothing to go on, a person decides.</li>
<li><strong>The customer pays the wrong amount:</strong> within 10% of an open order, the text goes on the check list. Further off, it is treated as personal money and never stored.</li>
<li><strong>The text arrives late:</strong> if the order is still open, it matches when the text lands, and the pay page simply waits. If the link has expired, the text goes on the check list.</li>
<li><strong>The phone forwards the same text twice:</strong> the bank reference is stored once, so the second copy is dropped and the order is paid once.</li>
<li><strong>Someone sends a fake bank text:</strong> texts from ordinary phone numbers are never trusted. Fake &ldquo;money in&rdquo; messages come from normal numbers, and real ones come from the bank&rsquo;s sender name.</li>
</ul>
<p>Try each one below, with unique amounts on and off.</p>
<p><a href="https://tawfik.tv/notes/instapay-auto-confirm">Open the interactive diagram on tawfik.tv</a></p>

<h2>Can a screenshot prove an InstaPay payment?</h2>
<p>No. A screenshot is easy to fake, and a pending transfer can still be rejected. InstaPlug has a &ldquo;did it arrive?&rdquo; check for shop counters: the staff snap the customer&rsquo;s screenshot, it is read on the device without uploading, and checked against the bank texts that really arrived. Each text can vouch for one screenshot only, so the same payment cannot be shown twice. The answer is never &ldquo;fake&rdquo;, because texts can be late. Your bank app is the final word.</p>
<h2>What do you need to set it up?</h2>
<ul>
<li><strong>A bank account linked to InstaPay</strong>, with incoming-transfer texts going to a phone you control.</li>
<li><strong>That phone on and online.</strong> If it goes offline, payments wait and match when it is back.</li>
<li><strong>A small server and a Postgres database.</strong> You run your own copy, so bank texts and payments stay in your database.</li>
<li><strong>A webhook in your shop</strong> that ships the order or confirms the booking when the signed message arrives.</li>
<li><strong>Your bank&rsquo;s terms.</strong> Money arrives in your own account like any InstaPay transfer, so check what your bank says about business use. This is not legal advice.</li>
</ul>
<p>Personal money into the same account stays private: only amounts close to an open order are kept, and only exact ones mark anything paid. Check your bank app now and then, since a text is a notification, not a statement.</p>
<p>The same server can also serve a talking counter screen for shops, staff alerts that never show the balance, and tools for AI agents to create a payment link and check whether it is paid. None of those tools can move money, the same rule I hold to in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">the guard I built for AI coding agents</a> and in <a href="https://tawfik.tv/notes/mcp-security-checklist">my MCP security checklist</a>.</p>
<h2>Questions people ask</h2>
<h3>Does InstaPay have an API for websites?</h3>
<p>There is no public merchant API on InstaPay&rsquo;s own site. You either go through a licensed payment provider that offers InstaPay in its checkout, or receive into your own account and confirm from your bank&rsquo;s incoming-transfer texts.</p>
<h3>Do I need a payment gateway integration to accept InstaPay?</h3>
<p>Only if you want a provider in the middle. A payment gateway integration with a licensed provider that offers InstaPay in its checkout, such as Kashier&rsquo;s QR code or request to pay, confirms each payment for you, for a fee. Without one, the money lands in your own account, a matcher confirms it from your bank&rsquo;s texts, and your shop gets a signed webhook. That second route is the one InstaPlug takes.</p>
<h3>Can InstaPay payments be confirmed automatically?</h3>
<p>Yes. Forward your bank&rsquo;s &ldquo;money in&rdquo; text to a matcher. It marks the order paid when the exact amount matches and a second sign agrees: the payer&rsquo;s name, the customer tapping pay in the last 30 minutes, or a unique amount.</p>
<h3>What is the InstaPay limit for one transaction?</h3>
<p>EGP 70,000 per transaction, EGP 120,000 a day and EGP 400,000 a month, per bank registered in the app, according to InstaPay and the Central Bank of Egypt.</p>
<h3>Does InstaPay charge fees?</h3>
<p>Since 1 April 2025, transfers cost 0.1% of the amount, at least EGP 0.50 and at most EGP 20. Balance checks and mini-statements are EGP 0.50 each, with 10 free a month.</p>
<h3>What if two customers pay the same amount?</h3>
<p>Each payment needs a second sign: the payer&rsquo;s name, a recent tap on the pay page, or a unique amount. If none fits, it waits for a person instead of paying the wrong order.</p>
<h3>Is a screenshot proof of payment?</h3>
<p>No. Only the money arriving in your account is proof. Check the screenshot against the bank texts that really arrived, and treat your bank app as final.</p>
<p>If you want InstaPay payments, bookings or a loyalty card wired into your business, see <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and loyalty systems</a> or write to <a href="mailto:m@tawfik.tv">m@tawfik.tv</a>.</p>]]></content:encoded></item><item><title>What is a zero-knowledge proof? Explained simply, with a game you can play</title><link>https://tawfik.tv/notes/zero-knowledge-proof</link><guid>https://tawfik.tv/notes/zero-knowledge-proof</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A zero-knowledge proof convinces a checker that something is true while showing nothing else: they learn &quot;true&quot; and not why. Play one here.</description>
<content:encoded><![CDATA[<p>A zero-knowledge proof is a way to convince someone that a statement is true without showing them anything except that it&rsquo;s true. The checker ends up sure, and learns nothing they could repeat, such as your password, your birth date or which account is yours.</p>
<p>It&rsquo;s already moving real money. On 15 October 2026, <a href="https://l2beat.com/scaling/summary">L2BEAT</a> counted about $3.8 billion secured by the 12 ZK rollups it tracks on Ethereum, networks that use these proofs to show a whole batch of transactions was processed correctly.</p>
<p>I&rsquo;m Mo Tawfik Khalifa. I designed a zero-knowledge ID for players at PLAYERUNKNOWN Productions, and I&rsquo;ve led identity products where the right answer was no zero-knowledge at all. The long story of those builds is in <a href="https://tawfik.tv/notes/prove-the-fact">How to prove who someone is without seeing who they are</a>. This is the plain answer, with a proof you can run yourself.</p>
<h2>What is a zero-knowledge proof?</h2>
<p>There are always two sides. The <strong>prover</strong> knows a secret. The <strong>verifier</strong> wants to be sure the prover knows it, without hearing it.</p>
<p>The idea comes from a 1985 paper by Shafi Goldwasser, Silvio Micali and Charles Rackoff, <a href="https://doi.org/10.1145/22145.22178">The Knowledge Complexity of Interactive Proof-Systems</a>. Their question was how much a checker learns from a proof beyond the fact that it&rsquo;s true. Their answer: it can be nothing. Goldwasser and Micali <a href="https://news.mit.edu/2013/goldwasser-and-micali-win-turing-award-0313">won the Turing Award</a>, computing&rsquo;s top prize, partly for this work.</p>
<h2>How does a zero-knowledge proof work? The magic door</h2>
<p>The classic explanation is a cave from <a href="https://doi.org/10.1007/0-387-34805-0_60">How to Explain Zero-Knowledge Protocols to Your Children</a>, by Jean-Jacques Quisquater, Louis Guillou and Thomas Berson. The cave is a ring. One entrance splits into a left and a right passage, and they meet at a door at the far end that opens only for the magic words.</p>
<ol>
<li>You wait outside. The prover walks into the left or the right passage. You can&rsquo;t see which.</li>
<li>You shout which side they should come out of.</li>
<li>If they know the words, they always can: they walk back, or go through the door.</li>
<li>If they&rsquo;re bluffing, they only make it when they happened to pick the side you call. That&rsquo;s 1 chance in 2.</li>
<li>Repeat. A bluffer survives 10 rounds 1 time in 1,024, and 40 rounds about once in a million million.</li>
</ol>
<p>You end up sure, and you never hear the words. Try it.</p>
<p><a href="https://tawfik.tv/notes/zero-knowledge-proof">Open the interactive diagram on tawfik.tv</a></p>

<p>The tape at the end is the clever part. In the paper, a rival reporter films a bluffer, cuts out every failed scene, and ends up with a tape nobody can tell from the real one. So a recording proves nothing to anyone else. That&rsquo;s what &ldquo;zero knowledge&rdquo; means in the maths: anything the checker saw, they could have faked without the secret.</p>
<h2>What are the three properties of a zero-knowledge proof?</h2>
<p>Every one must pass three tests, and the cave shows all three.</p>
<ol>
<li><strong>Completeness.</strong> If the statement is true and both sides follow the rules, the checker is convinced. Someone who knows the words always comes out the right side.</li>
<li><strong>Soundness.</strong> If the statement is false, a cheater gets caught, except with a tiny chance you can make as small as you like. Each round halves a bluffer&rsquo;s luck.</li>
<li><strong>Zero-knowledge.</strong> The checker learns nothing except that the statement is true. The fake tape looks just like the real one.</li>
</ol>
<p>Soundness only works if the checker&rsquo;s questions are unpredictable. Shout &ldquo;left&rdquo; every time in the game above with Alex at the cave and see what happens. That&rsquo;s why the reporter in the story flipped a coin.</p>
<h2>What is the difference between interactive and non-interactive proofs?</h2>
<p>The cave is <strong>interactive</strong>: you have to be there, asking questions live. Fine for one checker, useless for a blockchain that thousands of computers check later.</p>
<p>A <strong>non-interactive</strong> proof is one message anyone can check, any time. In 1986 Amos Fiat and Adi Shamir <a href="https://doi.org/10.1007/3-540-47721-7_12">published the trick most systems still use</a>: the prover works out the &ldquo;coin flips&rdquo; from a hash of everything said so far, so nobody has to flip them live. In 1988 Manuel Blum, Paul Feldman and Silvio Micali showed <a href="https://doi.org/10.1145/62212.62222">non-interactive zero-knowledge proofs</a> work when both sides share a random string set up in advance. That shared setup comes back below as a cost.</p>
<h2>What are zk-SNARKs and zk-STARKs?</h2>
<p>They are the two main families of non-interactive proofs in use today.</p>
<ul>
<li><strong>zk-SNARKs</strong> make tiny proofs that are quick to check. In Jens Groth&rsquo;s widely used 2016 design, <a href="https://eprint.iacr.org/2016/260">a proof is only three group elements</a>, a few short numbers. Most need a <strong>trusted setup</strong>: a one-off ceremony that makes the shared random string. If the secret left over from it isn&rsquo;t destroyed, someone could forge proofs.</li>
<li><strong>zk-STARKs</strong>, from <a href="https://eprint.iacr.org/2018/046">Eli Ben-Sasson and colleagues in 2018</a>, are &ldquo;transparent&rdquo;: no trusted setup, only public randomness. Ethereum&rsquo;s developer docs say they <a href="https://ethereum.org/developers/docs/scaling/zk-rollups/">are also safe against quantum computers</a>, while the maths under most SNARKs is not. The price is bigger proofs that cost more to check on-chain.</li>
</ul>
<p>The line is blurring. Zcash, a private payments network, moved to a proving system called Halo 2 in May 2022 to <a href="https://z.cash/learn/what-are-zk-snarks/">remove its trusted setup</a>.</p>
<h2>Where are zero-knowledge proofs used today?</h2>
<ol>
<li><strong>Age and identity checks.</strong> Google <a href="https://blog.google/technology/safety-security/opening-up-zero-knowledge-proof-technology-to-promote-privacy-in-age-assurance/">open-sourced its zero-knowledge libraries</a> in July 2025 so a person can prove they&rsquo;re over 18 &ldquo;without sharing anything else at all&rdquo;. The EU&rsquo;s <a href="https://digital-strategy.ec.europa.eu/en/factpages/blueprint-age-verification-solution-help-protect-minors-online">age verification blueprint</a> has included zero-knowledge proofs since October 2025, and Denmark, France, Greece, Italy and Spain are building national apps on it. How that compares with ID uploads and face scans is in <a href="https://tawfik.tv/notes/prove-age-without-id">How to prove you&rsquo;re over 18 without showing your ID</a>.</li>
<li><strong>Blockchain rollups.</strong> A ZK rollup <a href="https://ethereum.org/developers/docs/scaling/zk-rollups/">runs a batch of transactions off the main chain</a> and posts a summary plus a proof that every one of them followed the rules. Ethereum checks the proof instead of redoing the work.</li>
<li><strong>Private payments.</strong> A normal payment on a public blockchain, like most <a href="https://tawfik.tv/notes/what-is-a-stablecoin">stablecoin</a> transfers, shows both addresses and the amount to anyone. Zcash&rsquo;s shielded payments <a href="https://z.cash/learn/what-are-zk-snarks/">are encrypted on the chain yet still checked as valid</a>.</li>
<li><strong>Players and accounts.</strong> At PLAYERUNKNOWN Productions, my design let a player prove &ldquo;I&rsquo;m a registered player and I hold this item&rdquo; without the game learning which player or which wallet. <a href="https://tawfik.tv/notes/prove-the-fact">The full build is here</a>.</li>
</ol>
<h2>What can a zero-knowledge proof prove, and what can&rsquo;t it?</h2>
<p>It can prove almost any statement a computer could check if it had the secret. In 1991 Oded Goldreich, Silvio Micali and Avi Wigderson showed that <a href="https://doi.org/10.1145/116825.116852">every such statement has a zero-knowledge proof</a>: &ldquo;this number is over 18&rdquo;, &ldquo;I know the password to this account&rdquo;, &ldquo;these 5,000 payments add up&rdquo;.</p>
<p>What it can&rsquo;t do:</p>
<ul>
<li><strong>Make bad data true.</strong> A proof that a signed card says &ldquo;over 18&rdquo; is only as good as whoever signed the card.</li>
<li><strong>Stop one person getting two IDs.</strong> That&rsquo;s decided when IDs are handed out, not in the proof.</li>
<li><strong>Hide everything around it.</strong> Your internet address, your device and a site that asks for too much are still there, as the <a href="https://www.eff.org/deeplinks/2025/07/zero-knowledge-proofs-alone-are-not-digital-id-solution-protecting-user-privacy">EFF points out</a>.</li>
</ul>
<h2>What does a zero-knowledge proof cost?</h2>
<p>Checking is cheap. Making the proof is not. Ethereum&rsquo;s docs say the cost of computing validity proofs <a href="https://ethereum.org/developers/docs/scaling/zk-rollups/">is substantial, can raise fees, and needs specialised hardware</a>, and that a mishandled trusted setup could compromise a rollup&rsquo;s security.</p>
<p>The cost I&rsquo;d plan for as a product lead is people. The statement has to be written as a &ldquo;circuit&rdquo;, a program the proof system understands, and a mistake there means proofs of the wrong thing still check out. That needs specialists and an outside audit before launch.</p>
<h2>When do you not need a zero-knowledge proof?</h2>
<p>Skip it in any of these four cases.</p>
<ol>
<li><strong>The checker must know who you are.</strong> A hospital can&rsquo;t hire an anonymous nurse. In the <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">credential passport for clinicians</a> I led, the licence is checked once at the source and the clinician picks which fields each employer sees, with no zero-knowledge part.</li>
<li><strong>A signed answer is enough.</strong> If the site only needs &ldquo;over 18: yes&rdquo; from a trusted issuer, a <a href="https://tawfik.tv/notes/verifiable-credentials">verifiable credential</a> with selective disclosure does the job with less engineering.</li>
<li><strong>The checker already holds the data.</strong> Your bank doesn&rsquo;t need a proof of your balance.</li>
<li><strong>Nothing private is at stake.</strong> An ordinary signature proves a file wasn&rsquo;t changed.</li>
</ol>
<p>Reach for zero-knowledge when the checker must be sure of a fact and must not be able to link it to a person or reuse it.</p>
<h2>Questions people ask</h2>
<h3>Who invented zero-knowledge proofs?</h3>
<p>Shafi Goldwasser, Silvio Micali and Charles Rackoff, in <a href="https://doi.org/10.1145/22145.22178">a paper presented in 1985</a>.</p>
<h3>Is a zero-knowledge proof the same as encryption?</h3>
<p>No. Encryption hides a message so only the key holder can read it. A zero-knowledge proof convinces someone a statement about hidden data is true, and they never read the data.</p>
<h3>Can a zero-knowledge proof be faked?</h3>
<p>Only with luck or broken maths. In the cave, a bluffer passes 40 fair rounds about once in a million million. Non-interactive systems set that chance far lower, and a SNARK can be forged if its trusted setup leaked.</p>
<h3>Are zero-knowledge proofs quantum safe?</h3>
<p>STARKs are believed to be. Most SNARKs rest on elliptic curve maths that a large quantum computer is <a href="https://ethereum.org/developers/docs/scaling/zk-rollups/">widely believed able to break</a>.</p>
<h3>Do you build this?</h3>
<p>Yes. I design identity and privacy products end to end, and decide where zero-knowledge earns its cost, as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> or hands on. If you need this built, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>SuperSplat tutorial: how to clean, crop and publish a 3D scan</title><link>https://tawfik.tv/notes/supersplat-tutorial</link><guid>https://tawfik.tv/notes/supersplat-tutorial</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>SuperSplat is a free, open-source splat editor from PlayCanvas in your browser. Open a scan, delete floaters, crop, export .spz, publish.</description>
<content:encoded><![CDATA[<p>SuperSplat is a free, open-source editor from PlayCanvas for Gaussian splat scans, and it runs in your browser with nothing to install. You drop in a .ply, .splat or .spz, paint over the stray blobs and delete them, crop to a box, turn the scan the right way up, then export a smaller file or publish it with a link.</p>
<p>It also got much lighter to run this autumn. PlayCanvas shipped <a href="https://blog.playcanvas.com/new-in-supersplat-editor-3-0-rebuilt-on-webgpu">SuperSplat Editor 3.0, rebuilt on WebGPU, on 9 September 2026</a>. On a 4.4 million splat scene, a 990 MB PLY, the editor&rsquo;s memory with the scene loaded fell from 1,557 MB to 105 MB.</p>
<p>I build real-time 3D for the web: my Hermès virtual store, the TAG Heuer showroom I built at Napster, and <a href="https://tawfik.tv/projects/seven-al-hamra">SEVEN Al Hamra</a>, a building you could walk through before it was built. For splats, my live demo is <a href="https://tawfik.tv/window">tawfik.tv/window</a>. It renders Spark&rsquo;s own sample scene, a fireplace, not a scan of mine, as if your screen were a pane of glass. What a splat is and how to capture one is in <a href="https://tawfik.tv/notes/gaussian-splatting-website">Gaussian splatting on a website</a>. This page is the step in between: cleaning a scan so it is fit to publish.</p>
<h2>What is SuperSplat?</h2>
<p>SuperSplat is PlayCanvas&rsquo;s tool for inspecting, editing, optimising and publishing Gaussian splats (<a href="https://github.com/playcanvas/supersplat">README</a>). Three things to know:</p>
<ul>
<li><strong>It is free and open source.</strong> The Editor&rsquo;s code is on GitHub under the MIT licence, and so are its viewer and the splat-transform converter. The hosting at superspl.at, where published scenes live, is run by PlayCanvas (<a href="https://developer.playcanvas.com/user-manual/supersplat/">overview</a>).</li>
<li><strong>Your scan stays on your machine until you publish.</strong> The Editor loads files locally. Only publishing needs a free PlayCanvas account.</li>
<li><strong>It needs WebGPU.</strong> Current Chrome or Edge, Safari 26 or later, or Firefox with WebGPU switched on (<a href="https://developer.playcanvas.com/user-manual/supersplat/getting-started/">getting started</a>).</li>
</ul>
<h2>How do I open a .ply, .splat or .spz in SuperSplat?</h2>
<ol>
<li>Go to <a href="https://superspl.at/editor">superspl.at/editor</a>.</li>
<li>Drag your file onto the window, or use File &gt; Import. It reads .ply, .compressed.ply, .sog, .splat, .ksplat, .spz and XGRIDS .lcc files (<a href="https://developer.playcanvas.com/user-manual/supersplat/editor/import-export/">formats</a>). A .ply must hold splat data: a mesh PLY from a modelling tool will fail to load.</li>
<li>Find your way round. Left-drag orbits, right-drag pans, the wheel zooms, double-click sets the point you orbit around, and <strong>F</strong> frames the selection.</li>
</ol>
<p>You can also open a scan straight from a link:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">https://superspl.at/editor?load=https://example.com/scans/postbox.ply</pre>

<h2>How do I delete floaters in SuperSplat?</h2>
<p>Floaters are stray blobs hanging in the air where the training software was unsure what it saw. PlayCanvas&rsquo;s own guide says most raw captures contain them, and that removing them is the single biggest quality win.</p>
<ol>
<li>Press <strong>N</strong> to turn on Selection Depth, so the tools stop at the visible surface instead of reaching through the scene. Press <strong>Tab</strong> to show each splat&rsquo;s centre.</li>
<li>Press <strong>B</strong> for the brush and paint over the floaters. <strong>[</strong> and <strong>]</strong> change its size. Hold Shift to add to the selection and Ctrl to take away from it.</li>
<li>For a lone clump, press <strong>O</strong> for Flood Selection, which grows a selection from where you click.</li>
<li>Press <strong>Delete</strong>. Turn the camera, look again, repeat.</li>
<li>Took too much? <strong>Ctrl+Z</strong> undoes (Cmd+Z on a Mac), and Select &gt; Reset brings back every deleted splat.</li>
</ol>
<p>When an area is finished, select it and press <strong>H</strong> to lock it, so a stray brush stroke cannot touch it. <strong>Shift+H</strong> unlocks everything. Every tool and key is in PlayCanvas&rsquo;s <a href="https://developer.playcanvas.com/user-manual/supersplat/editor/editing-splats/">selection guide</a> and <a href="https://developer.playcanvas.com/user-manual/supersplat/editor/keyboard-shortcuts/">shortcut list</a>.</p>
<p>Try it on a sample scan of a London post box. This brush reaches through the scan, as SuperSplat does with Selection Depth off, so turn the view when the post box gets caught.</p>
<p><a href="https://tawfik.tv/notes/supersplat-tutorial">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do I crop a splat in SuperSplat?</h2>
<p>Cropping keeps what is inside a shape and deletes the rest: the street behind your subject, the ring of blurry ground every outdoor scan drags in.</p>
<ol>
<li>Pick Box Selection, or Sphere Selection, and double-click in the scene to place it.</li>
<li>Shape it with the gizmo: <strong>1</strong> moves, <strong>2</strong> rotates, <strong>3</strong> scales. Or type its position and size.</li>
<li>Click <strong>Set</strong> to select everything inside. Leave Selection Depth off here, so the box reaches through the whole scene.</li>
<li>Choose Select &gt; Invert (<strong>Ctrl+I</strong>), then press <strong>Delete</strong>.</li>
</ol>
<h2>How do I fix the orientation and scale?</h2>
<p>Scans often load on their side or upside down, and at no real-world size. The <a href="https://developer.playcanvas.com/user-manual/supersplat/editor/transform-measure-align/">transform guide</a> covers three fixes:</p>
<ul>
<li><strong>Level it.</strong> Pick the Orient tool, click three points on something that should be flat, such as the floor or a table top, and press Align to Grid. If it comes out upside down, orbit underneath and press Align to Grid again.</li>
<li><strong>Move, turn or resize it by hand.</strong> Choose Select &gt; None first so the whole splat moves, then use Move, Rotate and Scale (1, 2, 3).</li>
<li><strong>Give it a true size.</strong> The Measure tool reports the distance between two points. Type the real distance, from a doorway you measured with a tape, and SuperSplat rescales the whole scan to match. The grid is in metres.</li>
</ul>
<h2>How do I compress and export from SuperSplat?</h2>
<p>File &gt; Export offers PLY, SOG, SPZ, Splat and Viewer App, and only visible splats are exported.</p>
<ul>
<li><strong>SPZ</strong> for a web page you build yourself. It is Niantic&rsquo;s compressed format; SuperSplat writes version 4 by default and version 3 for older readers.</li>
<li><strong>SOG</strong>, PlayCanvas&rsquo;s own compressed format: a zip of WebP images and a small JSON file, which its docs recommend for apps. Spark reads both SPZ and SOG.</li>
<li><strong>PLY</strong> as your full-size master copy. Tick Compress PLY to write a smaller .compressed.ply.</li>
<li><strong>SH Bands</strong> sets how many bands of spherical harmonics go in: the numbers that let colour change with viewing angle. Fewer bands means a smaller file and flatter shine.</li>
</ul>
<p><strong>Ctrl+Shift+E</strong> repeats the last export to the same file. File &gt; Save keeps an .ssproj project with your edits, so you can come back later.</p>
<p>What you delete counts twice. A full PLY stores about 248 bytes a splat, so every 100,000 floaters you cut is about 25 MB off the master.</p>
<h2>How do I publish or embed a SuperSplat scene?</h2>
<p>Three ways, from least work to most control.</p>
<ol>
<li><strong>Publish to superspl.at.</strong> Log in, frame the view people should see first, then File &gt; Publish with a title and a description. SuperSplat compresses the scan to SOG, which can take several minutes, and gives you a scene page. New scenes are unlisted: only people with the link can see them. On the scene page, <strong>Embed</strong> gives you an iframe for your own site, and later changes you make in Studio show up in it (<a href="https://developer.playcanvas.com/user-manual/supersplat/editor/publishing/">publishing guide</a>).</li>
<li><strong>Export a Viewer App.</strong> File &gt; Export &gt; Viewer App gives you one HTML file with the scan inside, or a ZIP with the viewer and an index.sog. The single file is about 30% larger, and PlayCanvas says files under 32 MB should load everywhere. The ZIP only runs over http://, so test it with a local server before you upload it to any web host (<a href="https://developer.playcanvas.com/user-manual/supersplat/viewer/self-hosting/">self-hosting guide</a>).</li>
<li><strong>Your own page, with Spark.</strong> See the next section.</li>
</ol>
<p>To test an unzipped Viewer App on your own machine:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">cd postbox-viewer        # the unzipped Viewer App
python3 -m http.server   # then open http://localhost:8000</pre>

<h2>How do I put a cleaned scan on my own website?</h2>
<p>Export SPZ and load it with Spark, the three.js splat renderer my window demo uses. The heart of it is one line:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">const scan = new SplatMesh({ url: "/scans/postbox.spz" });</pre>

<p>The whole page, about 20 lines, and what broke when I shipped mine are in <a href="https://tawfik.tv/notes/gaussian-splatting-website">Gaussian splatting on a website</a>. Which route to take:</p>
<ul>
<li><strong>The iframe</strong> when the scan is the whole story and PlayCanvas&rsquo;s viewer controls suit you.</li>
<li><strong>Your own page</strong> when the scan sits inside your design, next to other 3D objects, or needs controls of its own. My window demo moves the view with your cursor, your phone&rsquo;s tilt or your head, which a stock viewer does not do.</li>
</ul>
<p>Two cleanup habits pay off on your own page:</p>
<ul>
<li><strong>Crop to where people can look.</strong> Shipping the window demo taught me that a scan stops where the photos stopped, and people see black at the edges unless you limit how far the camera travels. Crop to that same limit and you stop shipping splats nobody can see.</li>
<li><strong>Count your splats.</strong> Spark&rsquo;s <a href="https://sparkjs.dev/docs/performance/">performance guide</a> suggests 1 to 3 million splats on an iPhone and 1 to 2 million on an Android phone. Cropping is the cheapest way under budget.</li>
</ul>
<p>If the scan is one room in a bigger 3D site, see <a href="https://tawfik.tv/notes/threejs-website">how I build three.js websites</a>. If you are pricing a walk-round of a property or venue, <a href="https://tawfik.tv/notes/3d-virtual-tour-cost">what a 3D virtual tour costs</a> compares splats with 360 photo tours and scanned tours.</p>
<h2>Questions people ask</h2>
<h3>Is SuperSplat free?</h3>
<p>Yes. The Editor is open source under the MIT licence and free to use in the browser. Publishing to superspl.at needs a free PlayCanvas account.</p>
<h3>Does SuperSplat upload my scan?</h3>
<p>Not while you edit. The Editor loads files locally, and nothing is uploaded until you choose Publish.</p>
<h3>Can SuperSplat convert PLY to SPZ?</h3>
<p>Yes. Open the PLY and choose File &gt; Export &gt; SPZ. PlayCanvas also runs a converter page at superspl.at/convert, built on its splat-transform tool.</p>
<h3>Why won&rsquo;t my PLY open in SuperSplat?</h3>
<p>It may be a mesh, not a splat: SuperSplat only loads PLY files that hold Gaussian splat data. It also needs a browser with WebGPU.</p>
<h3>Is SuperSplat the same as Spark?</h3>
<p>No. SuperSplat is PlayCanvas&rsquo;s editor and viewer. Spark is a separate splat renderer for three.js, built by World Labs.</p>
<p>If you want a scan cleaned and built into your own site, see <a href="https://tawfik.tv/hire/3d-web-experiences">3D web experiences</a> or write to me at m@tawfik.tv.</p>]]></content:encoded></item><item><title>Gaussian splatting on a website: how to put a 3D scan on your site</title><link>https://tawfik.tv/notes/gaussian-splatting-website</link><guid>https://tawfik.tv/notes/gaussian-splatting-website</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A Gaussian splat is a photo-real 3D scan made of soft blobs. Capture it with a phone, export .spz, and show it on your site with Spark and three.js.</description>
<content:encoded><![CDATA[<p>A Gaussian splat is a 3D scan made of hundreds of thousands of soft, coloured, see-through blobs, built from ordinary photos or a phone video. To put one on a website, capture it with a phone app, export a .spz or .ply file, and load it with a free web viewer such as Spark on three.js, in about 20 lines of code.</p>
<p>The method comes from a paper by Kerbl, Kopanas, Leimkühler and Drettakis, published in <a href="https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/">ACM Transactions on Graphics in July 2023</a> and shown at SIGGRAPH 2023. Before it, the authors wrote, no method could show a complete, unbounded scene at 1080p in real time. Theirs ran at 30 frames a second or more (<a href="https://arxiv.org/abs/2308.04079">abstract on arXiv</a>).</p>
<p>I built one you can try: <a href="https://tawfik.tv/window">tawfik.tv/window</a>. It renders a splat live in your browser with Spark, and the screen behaves like a pane of glass: the room shifts as you move the cursor on a laptop, or drag or tilt a phone. If you allow the camera, it follows your head instead, worked out on your own device. To be clear about the scene: it is Spark&rsquo;s own sample, a fireplace, not a scan of mine. It holds 301,000 splats in a 4.4 MB .spz file.</p>
<h2>What is a Gaussian splat, in plain words?</h2>
<p>Picture a 3D photo made of blobs instead of triangles. Each blob has a position, a size, a stretch and a direction, a colour, and how see-through it is. Blend enough of them from back to front and they add up to a photo-real picture you can walk round.</p>
<p>Three things make splats different from the 3D models in games:</p>
<ul>
<li><strong>They are made from photos, not modelled.</strong> Software learns the blobs by checking them against your photos thousands of times. The original research code runs 30,000 training steps.</li>
<li><strong>They look like the photos.</strong> Plants, hair and fabric, which are slow to model by hand, come out looking the way they did on the day.</li>
<li><strong>The light is baked in.</strong> You get the light that was there when you scanned. You cannot relight a splat the way you relight a model.</li>
</ul>
<h2>How do you capture a Gaussian splat with a phone?</h2>
<ol>
<li><strong>Pick an app.</strong> <a href="https://apps.apple.com/us/app/-/id1541433223">Scaniverse</a> from Niantic Spatial has a free tier, runs on <a href="https://www.nianticspatial.com/products/capture">iPhone and Android</a>, and exports splats as SPZ or PLY. <a href="https://poly.cam/tools/gaussian-splatting">Polycam</a> builds a splat from 20 to 200 photos or an MP4 video.</li>
<li><strong>Light it evenly.</strong> Overcast daylight or soft room light. Hard shadows get baked into the scan.</li>
<li><strong>Walk a full circle, slowly.</strong> Keep the subject in the middle of the frame and overlap each shot with the last. Then walk a second circle, higher or lower.</li>
<li><strong>Cover every side people will see.</strong> The software can only rebuild what the photos saw. Try &ldquo;front half only&rdquo; in the demo below and look round the back.</li>
<li><strong>Avoid what moves and what shines.</strong> People walking through, leaves in the wind, mirrors and glass all turn to blur.</li>
<li><strong>Clean it before you publish.</strong> Most scans have stray blobs floating at the edges. <a href="https://superspl.at/editor">SuperSplat</a>, a free, open-source editor that runs in the browser, crops them away.</li>
</ol>
<p>Here is the whole pipeline in one place. Walk round the pot to take photos, train it, then see what a real scan weighs.</p>
<p><a href="https://tawfik.tv/notes/gaussian-splatting-website">Open the interactive diagram on tawfik.tv</a></p>

<h2>Which file format: .ply, .splat or .spz?</h2>
<ul>
<li><strong>.ply</strong> is what training produces. In the <a href="https://github.com/graphdeco-inria/gaussian-splatting">original research code</a> every splat stores 62 numbers: position, a normal, 48 colour numbers that let the colour change with viewing angle, see-through, size and rotation. At 4 bytes each, that is 248 bytes a splat, so a million splats is about 248 MB.</li>
<li><strong>.splat</strong> is the simple format from <a href="https://github.com/antimatter15/splat">the first WebGL viewer</a>: 32 bytes a splat. It keeps one colour per blob, so shine does not move as you do.</li>
<li><strong>.spz</strong> is Niantic&rsquo;s open-source compressed format, MIT licensed. Its makers say SPZ files are <a href="https://github.com/nianticlabs/spz">typically about 10 times smaller than the PLY</a>, with minimal visual difference.</li>
</ul>
<p>PlayCanvas published a real example in December 2023: their guitar scan was <a href="https://blog.playcanvas.com/compressing-gaussian-splats/">132.8 MB as a PLY and 8.7 MB compressed</a>. Spark reads PLY, compressed PLY, SPZ, SPLAT, KSPLAT and PlayCanvas&rsquo;s newer SOG format.</p>
<p>My rule: ship .spz to the browser and keep the .ply as the master.</p>
<h2>How do I put a Gaussian splat on my website?</h2>
<p>Pick a viewer first.</p>
<ul>
<li><strong><a href="https://github.com/sparkjsdev/spark">Spark</a>.</strong> A Gaussian splat renderer for three.js, built by World Labs, MIT licence. It is what my demo uses. Choose it when your site already uses three.js, or when you want splats mixed with ordinary 3D objects.</li>
<li><strong><a href="https://github.com/playcanvas/supersplat">SuperSplat</a>.</strong> PlayCanvas&rsquo;s free, open-source editor for inspecting, editing, optimising and publishing splats, in the browser. The quickest route if you want no code.</li>
<li><strong><a href="https://github.com/mkkellogg/GaussianSplats3D">GaussianSplats3D</a>.</strong> An earlier three.js viewer you will find in older tutorials. Its author says it is no longer in active development and points people to Spark.</li>
</ul>
<p>With Spark, this is a complete page. It is Spark&rsquo;s own getting-started code, trimmed, with your scan in place of their sample:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">&lt;style&gt; body { margin: 0; } &lt;/style&gt;
&lt;script type="importmap"&gt;
{ "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.js",
    "@sparkjsdev/spark": "https://sparkjs.dev/releases/spark/2.3.1/spark.module.js" } }
&lt;/script&gt;
&lt;script type="module"&gt;
import * as THREE from "three";
import { SparkRenderer, SplatMesh } from "@sparkjsdev/spark";

const renderer = new THREE.WebGLRenderer({ antialias: false });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.01, 1000);
scene.add(new SparkRenderer({ renderer }));

const scan = new SplatMesh({ url: "/scans/room.spz" });
scan.quaternion.set(1, 0, 0, 0);   // turns the scan the right way up, as in Spark's example
scan.position.set(0, 0, -3);
scene.add(scan);

// the window effect, simplest version: the camera follows the cursor
addEventListener("pointermove", (e) =&gt; {
  camera.position.x = (e.clientX / innerWidth - 0.5) * 0.4;
  camera.position.y = (0.5 - e.clientY / innerHeight) * 0.2;
});

renderer.setAnimationLoop(() =&gt; renderer.render(scene, camera));
&lt;/script&gt;</pre>

<p>Source: <a href="https://sparkjs.dev/docs/">Spark getting started</a>. My live version goes one step further: the glass stays fixed and the eye moves in front of it, so the picture bends the way a real window does. Three things I hit shipping it:</p>
<ul>
<li><strong>Your Content Security Policy.</strong> Spark starts its workers from <code>data:</code> URLs, so <code>worker-src</code> must allow <code>data:</code>. My page may only load its own files, which is also the privacy proof for head tracking: face detection runs in the browser, and anyone can open the Network tab and see that no frames leave.</li>
<li><strong>Paths.</strong> tawfik.tv serves /window without a trailing slash, so relative paths broke. Load the scan by an absolute path or relative to <code>import.meta.url</code>.</li>
<li><strong>The edges of the scan.</strong> A scan stops where the photos stopped. Limit how far the camera can travel, or people see black at the edges.</li>
</ul>
<h2>Will a Gaussian splat run on a phone?</h2>
<p>Yes, if you keep the count down. Spark&rsquo;s <a href="https://sparkjs.dev/docs/performance/">performance guide</a> gives rule-of-thumb budgets:</p>
<ul>
<li><strong>iPhone:</strong> 1 to 3 million splats.</li>
<li><strong>Android phone:</strong> 1 to 2 million.</li>
<li><strong>Quest 3:</strong> 1 million or less.</li>
<li><strong>Computer:</strong> 1 to 5 million, and 10 to 20 million or more on some desktops.</li>
</ul>
<p>Over budget, turn on level of detail. With Spark 2.0, <code>new SplatMesh({ url, lod: true })</code> renders a smaller set of splats sized to the device: by default 1 million on Android, 1.5 million on iOS and 2.5 million on desktop (<a href="https://sparkjs.dev/docs/lod-getting-started/">level-of-detail guide</a>). For big scans, build the level-of-detail file ahead of time and stream it.</p>
<p>Two more settings matter. Keep antialiasing off, as Spark advises, because splats gain nothing from it. And watch the pixel ratio: my demo times its own frames, and when 60 frames average slower than 25 ms it lowers the resolution a step, then raises it again when there is room. It also shows a loading percentage, so nobody waits on a blank screen while the 4.4 MB scan arrives.</p>
<h2>What is a Gaussian splat website good for?</h2>
<ul>
<li><strong>Property.</strong> A walk-round of a real room on the listing, from a phone scan, with no 3D artist.</li>
<li><strong>Retail.</strong> A real product, a shop floor or a window display. In my <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores</a> the products were rebuilt in real-time 3D from CAD files or photogrammetry, so they could be lit and configured. A splat is the faster route when you want the real thing as it looks and do not need to relight it.</li>
<li><strong>Venues.</strong> A stage, a club or a view from a seat, scanned once and opened from a link, as a light first step towards a <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">digital twin</a>.</li>
<li><strong>Events.</strong> Scan the set or the stand after the build and the event lives on as a page. On a <a href="https://tawfik.tv/notes/fan-engagement-platform">fan platform</a>, a scanned room is the skin; the points, games and rewards do the work.</li>
</ul>
<p>Where splats fall short: anything you need to relight, offer in different colours as a product option, or drop into a game as a solid object. That still needs a modelled 3D asset.</p>
<h2>Questions people ask</h2>
<h3>What is 3D Gaussian splatting?</h3>
<p>A way to turn photos of a real place or object into a 3D scene made of soft, coloured blobs that render in real time. It comes from a 2023 research paper by Kerbl and colleagues.</p>
<h3>Can I view or edit a Gaussian splat online without code, in SuperSplat?</h3>
<p>Yes. Open the file in SuperSplat in your browser, or use the viewer in your scan app. To show it on your own site, in your own design, use a web viewer such as Spark.</p>
<h3>How big is a Gaussian splat file?</h3>
<p>About 248 bytes a splat as a raw PLY, so a million splats is about 248 MB. As SPZ it is roughly a tenth of that. My demo scene is 301,000 splats in 4.4 MB.</p>
<h3>Do Gaussian splats work on iPhone and Android?</h3>
<p>Yes, in a browser with WebGL2. Spark says it works on almost all devices, through WebGL2, and suggests 1 to 3 million splats on an iPhone and 1 to 2 million on an Android phone.</p>
<h3>Is a splat better than photogrammetry?</h3>
<p>They do different jobs. Photogrammetry gives you a mesh you can relight and use in a game engine. A splat looks more like the photos, but its lighting is fixed.</p>
<p>If you need a 3D scan on your site, or a whole 3D web experience around it, see <a href="https://tawfik.tv/hire/3d-web-experiences">3D web experiences</a> or write to me at m@tawfik.tv.</p>]]></content:encoded></item><item><title>AI customer service agent: what it can safely do, and what it costs</title><link>https://tawfik.tv/notes/ai-customer-service-agent</link><guid>https://tawfik.tv/notes/ai-customer-service-agent</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>An AI customer service agent answers from your help centre and hands the rest to a person. Start it read-only, write the articles first, pay per resolution.</description>
<content:encoded><![CDATA[<p>An AI customer service agent answers your customers from your own help centre, at any hour, and hands anything it cannot answer to a person with the details attached. Start it read-only: it can look things up and explain them, and it cannot refund, change or cancel anything until you have watched it work.</p>
<p>Customers are open to one, with a way out. In a <a href="https://www.gartner.com/en/newsroom/press-releases/2026-08-04-gartner-survey-finds-87-percent-of-customers-say-companies-using-genai-for-customer-service-must-provide-access-to-a-human-agent0">Gartner survey</a> of 3,566 customers, run in February and March 2026, 50% said service is easier when companies use generative AI, and 87% said it is essential to have an option to reach a human.</p>
<p>I set up an AI help desk for a fintech platform. I bought the agent instead of building one, wrote the help centre it answers from, and held one rule: the agent can read and explain, and it can never change an account. Anything that needs an action goes to a person.</p>
<h2>What can an AI customer service agent safely do?</h2>
<p>Three jobs, from day one:</p>
<ul>
<li><strong>Answer questions from your help centre</strong>, with a link to the article it used.</li>
<li><strong>Look up the signed-in customer&rsquo;s own records</strong>: order status, delivery dates, whether a payment went through.</li>
<li><strong>Collect the details and hand over</strong>, so your person starts with the full picture.</li>
</ul>
<p>Leave out anything that moves money or changes an account. You can add those later, one at a time, behind a guardrail.</p>
<p>On the fintech help desk, the platform&rsquo;s admin tools can move money between accounts and complete stuck cash-outs. The agent never gets those tools. When I tested it by asking it to send a customer&rsquo;s cash-out to a third party, it refused and passed the conversation to a person.</p>
<h2>Why does the knowledge base come first?</h2>
<p>When an article is missing, the model fills the gap with something that sounds right. Build the knowledge base before you switch anything on:</p>
<ol>
<li><strong>Export your last few hundred conversations</strong> and list every question that comes up more than once.</li>
<li><strong>Write one article per question</strong> in plain English, with the answer in the first line.</li>
<li><strong>Write down the rules your team knows by heart</strong>: the returns window, what counts as faulty, delivery cut-offs.</li>
<li><strong>Keep one source of truth.</strong> On the fintech desk one file publishes the public help centre, and the agent re-reads that site every week. Nobody edits answers inside the bot.</li>
</ol>
<p>I also keep a list of phrases the agent must never say, such as &ldquo;we&rsquo;ll cover it&rdquo;, and a check that fails if any article or saved reply contains one.</p>
<h2>Should the agent be read-only or allowed to take actions?</h2>
<p>Read-only first. Every action you add raises how much the agent resolves, and what one bad conversation can cost. When you add one, put the limits in a check that runs before the action, outside the model. The policy fits on one page:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">agent: website-chat
can_read:
  - help_centre
  - orders and payments: signed-in customer only
can_do:                        # day one: read-only
  refund:          ask_person
  change_address:  ask_person
later, one at a time:
  refund:          allow up to £100, own order, duplicate charge confirmed
  change_address:  allow own order, not yet dispatched
answers:
  - only from a help article, linked; otherwise hand over
  - never say: "we'll cover it", "refund approved", "I've sent you a link"</pre>

<p>This is the idea behind <a href="https://gvnr.io">GVNR</a>, the free, source-available guard I lead for AI agents in Claude Code, Cursor, Codex, Gemini CLI and other MCP clients. Before every action it answers allow, deny or ask a person, and it keeps a hash-chained record of each decision. A support agent needs the same three answers.</p>
<p>Try it on a small shop&rsquo;s inbox. Turn on refunds or address changes, or shrink the help centre, and watch each conversation and the monthly bill.</p>
<p><a href="https://tawfik.tv/notes/ai-customer-service-agent">Open the interactive diagram on tawfik.tv</a></p>

<h2>How should the handover to a human work?</h2>
<ul>
<li><strong>One step to a person, any time.</strong> Gartner warns that customers forced through failed AI attempts are less likely to use the tool again.</li>
<li><strong>The agent writes the summary</strong>: the question, the order, what it checked and anything a guardrail stopped. The customer never repeats themselves.</li>
<li><strong>Say what happens next without a promise.</strong> &ldquo;The team will pick this up&rdquo; is safe. &ldquo;You&rsquo;ll hear back in an hour&rdquo; is not.</li>
<li><strong>Say it is an AI.</strong> Under <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=OJ:L_202401689">Article 50 of the EU AI Act</a>, which applies from 2 August 2026, a system that talks to people must tell them they are dealing with an AI unless that is obvious.</li>
</ul>
<h2>How do you measure resolution?</h2>
<p>Vendors count resolutions differently, so read the definition before comparing rates. <a href="https://www.intercom.com/pricing">Intercom</a> bills an &ldquo;outcome&rdquo; when the customer confirms the issue is resolved, does not ask for more help after the agent replies, or the agent completes a workflow, handoffs included, once per conversation. <a href="https://www.zendesk.com/pricing/">Zendesk</a> bills an &ldquo;automated resolution&rdquo; only when the AI agent resolved the request without escalation to a human. Intercom <a href="https://fin.ai/">says</a> its agent averages 76% across 12,000+ customers. Yours depends on your articles and permissions.</p>
<p>What I track every week:</p>
<ol>
<li><strong>Resolution, by my own definition</strong>: no person touched it, and the customer did not come back about the same thing within 7 days.</li>
<li><strong>Handover reasons</strong>: each is a missing article or permission.</li>
<li><strong>20 resolved conversations, read in full.</strong> A customer who gave up looks resolved on a dashboard.</li>
<li><strong>Guardrail stops.</strong> Each one is either a bad request or a rule that needs fixing.</li>
</ol>
<h2>How much does an AI customer service agent cost?</h2>
<p>Seats for your people, plus a fee per AI resolution. Prices listed in October 2026:</p>
<ul>
<li><strong>Intercom</strong>: $29, $85 or $132 per seat a month, paid yearly, plus from $0.99 per outcome.</li>
<li><strong>Zendesk</strong>: $19, $55 or $115 per agent a month, paid yearly, with 5 or 10 automated resolutions per agent a month included, then $1.50 each committed or $2.00 pay as you go.</li>
</ul>
<p>Against people: Gartner&rsquo;s <a href="https://www.gartner.com/en/newsroom/press-releases/2019-09-25-gartner-says-only-9--of-customers-report-solving-thei">2019 poll</a> put a live contact (phone, chat or email) at $8.01 on average, against about $0.10 for self-service. For a small business it is staff time: the median US customer service wage was <a href="https://www.bls.gov/ooh/office-and-administrative-support/customer-service-representatives.htm">$21.53 an hour</a> in May 2025, so a 10-minute chat costs about $3.59 in wages alone.</p>
<p>So 1,000 chats a month with half resolved is 500 outcomes at $0.99: $495, plus a seat for the person who takes the rest.</p>
<p><strong>An AI receptionist for a small business</strong> is priced per call. Smith.ai&rsquo;s <a href="https://smith.ai/pricing/ai-receptionist">AI receptionist</a> is free for 25 calls a month, then $3.00 a call, or $150 a month for 75 calls and $500 a month for 300, with transfer to a live receptionist. The median US receptionist earned <a href="https://www.bls.gov/ooh/office-and-administrative-support/receptionists.htm">$18.27 an hour</a> in May 2025. The same rules apply: answers from your own notes, and anything involving money goes to a person.</p>
<h2>Which AI customer support software should you choose?</h2>
<p>Pick the one that sits on the help desk your team already works in, because the agent needs your articles, your customer records and a handover to a person in the same inbox. Intercom and Zendesk both sell an AI agent on top of their help desk, and both charge per seat plus a fee per resolution, so which is cheaper depends on your seat count and your volume. Compare how each counts a resolution before you compare prices, as above, since that definition sets the bill. Then test three things in a trial: can you lock it to read-only, does it link the article behind each answer, and where does it keep transcripts.</p>
<h2>A 2-week rollout plan</h2>
<p><strong>Week 1</strong></p>
<ol>
<li><strong>Day 1.</strong> Export recent conversations; list the questions and the actions asked for.</li>
<li><strong>Days 2 and 3.</strong> Write the articles and rules.</li>
<li><strong>Day 4.</strong> Set the agent up read-only on website chat, connected to the help centre, with signed-in customers verified by your own server before it reads any account.</li>
<li><strong>Day 5.</strong> Replay 50 real past questions, plus refund demands, requests for another customer&rsquo;s details and questions with no article. Fix what fails.</li>
</ol>
<p><strong>Week 2</strong></p>
<ol>
<li><strong>Day 6.</strong> Go live during office hours, with a person watching every conversation.</li>
<li><strong>Days 7 and 8.</strong> Read everything. Write articles for repeated handover reasons.</li>
<li><strong>Day 9.</strong> Extend to evenings and weekends.</li>
<li><strong>Day 10.</strong> Review the four numbers. Decide whether one action, with a limit, has earned its place.</li>
</ol>
<h2>What goes wrong?</h2>
<p><strong>Made-up answers.</strong> In February 2024 a Canadian tribunal ordered Air Canada to pay a customer C$812.02 after its website chatbot said the customer could claim a bereavement fare after travelling, which the airline&rsquo;s own policy page ruled out. The tribunal found the airline had not taken reasonable care to make its chatbot accurate, and rejected the argument that it could not be held liable for what the chatbot said (<a href="https://decisions.civilresolutionbc.ca/crt/crtd/en/item/525448/index.do">Moffatt v. Air Canada, 2024 BCCRT 149</a>). Answer only from articles, link the source, and hand over when nothing matches.</p>
<p><strong>Refunds and promises.</strong> Customers will say a colleague already agreed a refund. Cap the amount per conversation, check the order is the customer&rsquo;s own, and never let the agent promise money it has not moved.</p>
<p><strong>Privacy.</strong> An agent that reads accounts must know who it is talking to. My rule for the fintech desk: no account data until the chat carries an identity your server has signed, so nobody can type someone else&rsquo;s email address and ask about their money. Keep card numbers out of chat, and check where the vendor stores transcripts.</p>
<p>If you are connecting agents to tools over MCP, the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> covers that side, and <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop an AI agent deleting your database</a> covers coding agents. More of my field work is in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer: four AI and fintech builds</a>.</p>
<h2>Questions people ask</h2>
<h3>How much does an AI chatbot for a website cost?</h3>
<p>From about $1 to $2 per resolved conversation on the big help desks, plus $19 to $132 per seat a month for the people who handle the rest. Intercom charges from $0.99 per outcome; Zendesk charges $1.50 or $2.00 per automated resolution.</p>
<h3>How do I build an AI customer service agent?</h3>
<p>Buy the agent and build the parts that matter: the help centre, identity checks, the handover and the guardrail. Launch read-only and add actions one at a time.</p>
<h3>Is an AI customer service agent worth it for a small business?</h3>
<p>Run the cost numbers above with your own volume. If half your chats are the same ten questions, ten good articles and an agent take them off your team.</p>
<h3>Will an AI agent replace my support team?</h3>
<p>It takes the repeat questions. People still handle money, exceptions and upset customers, and 87% of customers in Gartner&rsquo;s 2026 survey want the option to reach one.</p>
<p>If you need an AI help desk set up with these guardrails, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>Wedding photo sharing with a QR code: how to collect every guest’s photos</title><link>https://tawfik.tv/notes/wedding-photo-sharing-qr</link><guid>https://tawfik.tv/notes/wedding-photo-sharing-qr</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>Put one QR code on every table that opens the camera in the guest&#x27;s browser. With no app to download, more guests join and every photo lands in one album.</description>
<content:encoded><![CDATA[<p>The simplest way to collect photos from wedding guests is one QR code on every table that opens a shared album in the phone&rsquo;s browser, with no app to download. Guests point their camera at the card, tap the link and shoot, and every photo lands in one live album.</p>
<p>Couples still book the professional: 88% of US couples who married in 2025 hired a photographer, and the average wedding had 117 guests, according to <a href="https://www.theknotww.com/press-releases/the-knot-worldwide-unveils-2026-real-weddings-study">The Knot Worldwide&rsquo;s 2026 Real Weddings Study</a>, published on 18 February 2026. That is up to 117 phones in the room as well, and the photos on them usually scatter across group chats.</p>
<p>I built <a href="https://laqtaa.app">Laqtaa</a> for a friend&rsquo;s wedding: one shared camera for your event. Guests scan a QR code and every photo lands in one live album. About 100 guests used it on the day and nothing broke, and it spread to more weddings by word of mouth. Here is what I learned, checked against Apple&rsquo;s, Google&rsquo;s and MDN&rsquo;s own docs.</p>
<h2>How do you collect photos from all your wedding guests?</h2>
<ol>
<li><strong>Pick one album for the whole day.</strong> One link, one QR code, every guest.</li>
<li><strong>Make joining one step.</strong> The QR code should open the camera or the album straight away, with no app, account or event code.</li>
<li><strong>Put a card on every table</strong>, plus the bar and the guest book.</li>
<li><strong>Decide who can see the album</strong> before you print, and say so on the card.</li>
<li><strong>Ask the best man or the DJ to mention it once.</strong></li>
<li><strong>Download everything in the week after</strong>, before the link is forgotten.</li>
</ol>
<p><a href="https://tawfik.tv/notes/wedding-photo-sharing-qr">Open the interactive diagram on tawfik.tv</a></p>

<h2>Why does a no-download wedding photo app matter?</h2>
<p>Every step between seeing the card and the first photo loses guests. An app means finding it in the store, downloading it on venue wifi, making an account and typing a code, drink in hand. A web album asks for one thing: point the camera.</p>
<p>Phones are ready for that one step:</p>
<ul>
<li><strong>iPhone.</strong> The built-in Camera app reads QR codes: hold the phone so the code appears, then tap the link (<a href="https://support.apple.com/en-gb/102680">Apple</a>).</li>
<li><strong>Android.</strong> The built-in camera scans QR codes on Android 9 or higher (<a href="https://support.google.com/accounts/answer/9283368">Google</a>), and on a Pixel the camera shows a link bubble as soon as it sees one (<a href="https://support.google.com/pixelphone/answer/16561572">Google</a>).</li>
<li><strong>The camera in the browser.</strong> A web page can open the phone&rsquo;s rear camera with one HTML attribute, <code>capture</code>. MDN&rsquo;s compatibility data lists it in Safari on iOS since version 10 and in Chrome for Android since version 25 (<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/capture">MDN</a>). A live viewfinder inside the page uses <code>getUserMedia()</code>, which only works on pages served over HTTPS (<a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia">MDN</a>).</li>
</ul>
<p>The simplest version is one line of HTML:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">&lt;input type="file" accept="image/*" capture="environment"&gt;</pre>

<p>On Laqtaa, the QR code opens the camera in the guest&rsquo;s browser and each shot goes straight into the shared album. No app, no login, and personal events are free.</p>
<p>The demo&rsquo;s drop-off rates are made up, so read the shape: every step loses people, and an app adds four.</p>
<h2>Shared Google Photos album, iCloud, an app or a web QR album: which is best?</h2>
<p><strong>A shared Google Photos album.</strong> Free and familiar. Share an album by link and anyone with it can view the photos and add to the album, and Google Photos can make a QR code for it (<a href="https://support.google.com/photos/answer/6131416">Google</a>). The catch for a wedding: a link can be passed on by others, and if you remove someone while link sharing is on, anyone with the original link can still view the album (<a href="https://support.google.com/photos/answer/9789702">Google</a>).</p>
<p><strong>An iCloud shared album.</strong> Apple changed these with iOS 27. Albums created on version 27 or later share photos at full resolution, and friends can join and add photos on the web, even without an Apple Account or Apple device. The owner decides whether people need approval or anyone with the link can join (<a href="https://support.apple.com/en-gb/108314">Apple</a>). The catches: those photos count towards the owner&rsquo;s iCloud storage, albums made on version 26 or earlier reduce shared photos to 2,048 pixels on the long edge (<a href="https://support.apple.com/en-gb/148868">Apple</a>), and guests whose devices are not on the latest software have to update or view the album on iCloud.com.</p>
<p><strong>A dedicated wedding app.</strong> Usually the most features, paid for by every guest in downloads, accounts and codes before the first photo.</p>
<p><strong>A web QR album.</strong> What I built. Scan, shoot, done, on any phone with a browser. It lives on someone&rsquo;s server, so check who runs it, how long the photos stay and how you get them out.</p>
<p>For a mixed room of iPhones and Android phones, the web QR album gets the most guests in. If most guests use Apple devices on the latest software, an iCloud shared album made on iOS 27 is a good free option.</p>
<h2>What should you put on the wedding table cards?</h2>
<ul>
<li><strong>One instruction:</strong> &ldquo;Point your phone camera here and tap the link.&rdquo;</li>
<li><strong>&ldquo;No app needed&rdquo;</strong> in plain words. It is the line that gets people to try.</li>
<li><strong>Who sees the photos:</strong> &ldquo;Everyone here can see the album&rdquo; or &ldquo;Only Harriet and Tom will see your photos.&rdquo;</li>
<li><strong>A short link</strong> under the code, for anyone whose camera will not scan.</li>
<li><strong>Until when</strong> the album takes photos, if it closes.</li>
</ul>
<p>Print the code large, on matte card, and scan the printed proof under the venue&rsquo;s lighting before you print the rest. Google&rsquo;s own tips for a failed scan are a steady hand, good light, no shadows or glare, and the whole code on screen (<a href="https://support.google.com/pixelphone/answer/16561572">Google</a>). Candlelight and glossy card fight all of those.</p>
<h2>Who can see the wedding photo album?</h2>
<ul>
<li><strong>Guests at the wedding.</strong> Everyone sees everything, live. It is the fun option: people scroll at the table and shoot more when they see others doing it. On Laqtaa, every photo lands in one live album that everyone at the event can see.</li>
<li><strong>Couple only.</strong> Guests see their own photos and the couple sees all of them. Better with children, colleagues or guests who would rather not be shared.</li>
</ul>
<p>Either way, treat the link as a key: check that you can reset it and remove people, and ask guests not to post the QR code online.</p>
<h2>How do you get full-quality originals of guest photos?</h2>
<p>Ask whether the album keeps original files or resized copies, then test it: upload one photo, download it again and compare the pixel size with the one on your phone.</p>
<p>iCloud shared albums made on version 27 or later keep photos at full resolution, while albums made on version 26 or earlier reduce them to 2,048 pixels on the long edge (<a href="https://support.apple.com/en-gb/148868">Apple</a>). Laqtaa puts a film look on every shot, like a disposable camera: part of the fun, and worth knowing if you want untouched files. For the few photos that matter most, such as the first dance from the front row, ask the guests who took them to send you the originals afterwards.</p>
<h2>What happens to the photos after the wedding?</h2>
<ol>
<li><strong>Download the whole album</strong> within a week, and keep two copies.</li>
<li><strong>Close the album.</strong> Turn off uploads or link sharing, so an old link cannot add to it or browse it.</li>
<li><strong>Send the best ones back</strong> to the guests who took them, with your thank-you notes.</li>
</ol>
<p>On Laqtaa the album closes when the event ends and guests receive the full album on WhatsApp, so nobody has to remember a link.</p>
<h2>A checklist for couples and planners</h2>
<p><strong>Before the day</strong></p>
<ul>
<li>Choose the album and test it on one iPhone and one Android phone.</li>
<li>Decide who can see the photos.</li>
<li>Print one card per table, plus the bar and the guest book.</li>
<li>Scan a printed proof in the venue&rsquo;s light.</li>
<li>Check the mobile signal and wifi where people will sit.</li>
</ul>
<p><strong>On the day</strong></p>
<ul>
<li>Put the cards out before dinner.</li>
<li>Get it mentioned once, after the speeches.</li>
<li>Give one person the job of checking the album is filling up.</li>
</ul>
<p><strong>After the day</strong></p>
<ul>
<li>Download everything within a week and keep two copies.</li>
<li>Close uploads or link sharing.</li>
<li>Ask for the originals of the photos you will frame.</li>
</ul>
<p>I built Laqtaa on my own with AI in the loop, and wrote up what that taught me in <a href="https://tawfik.tv/notes/one-person-ai-team">can one person with AI do a whole team&rsquo;s work</a>. The same no-download rule runs through my <a href="https://tawfik.tv/notes/digital-stamp-card">Wallet stamp cards</a> and <a href="https://tawfik.tv/notes/fan-engagement-platform">fan engagement platforms</a>.</p>
<h2>Questions people ask</h2>
<h3>Do guests need to download an app to share wedding photos?</h3>
<p>No. A web album opens from the QR code in the phone&rsquo;s browser, and the built-in camera on an iPhone or on Android 9 or higher reads the code.</p>
<h3>What is the best wedding photo sharing app?</h3>
<p>The one your guests actually use: no download, no account, one scan. Then check who can see the album, how you download it, and whether you get original files.</p>
<h3>Can we keep our wedding photo album private?</h3>
<p>Yes. Use a couple-only album, where guests see only their own photos, or share with invited people only.</p>
<h3>Can I use a shared Google Photos album for my wedding?</h3>
<p>Yes. Share it by link or QR code and anyone with the link can view and add photos. To stop new photos, turn off Collaborate. To make it private again, remove the collaborators and turn off link sharing (<a href="https://support.google.com/photos/answer/9789702">Google</a>).</p>
<p>If you need a QR album, online booking or a guest app built for your venue or business, see <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and loyalty builds for local businesses</a> or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>How much does a digital twin cost? Build, run and payback, line by line</title><link>https://tawfik.tv/notes/digital-twin-cost</link><guid>https://tawfik.tv/notes/digital-twin-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A building digital twin costs about $32,000 to $200,000 to build and $750 to $1,100 a month to run, set by the model, the sensors and the platform.</description>
<content:encoded><![CDATA[<p>A digital twin of one office building costs roughly $32,000 to $200,000 to build and about $750 to $1,100 a month to run, on today&rsquo;s published price lists. The biggest one-off cost is the 3D model: if you already have the BIM, you skip most of it.</p>
<p>That range is for a sample 40,000 sq ft office with sensors in 40 rooms, 24 energy meters, a maintenance app and fault-finding software. Every number below links to the vendor or government page it came from. None of them are my prices.</p>
<p>The interest is real. In an <a href="https://www.mckinsey.com/featured-insights/mckinsey-explainers/what-is-digital-twin-technology">August 2024 explainer</a>, McKinsey reported that 70 percent of C-suite technology executives at large enterprises are already exploring and investing in digital twins, and projected the market to reach $73.5 billion by 2027.</p>
<h2>What are the levels of a digital twin?</h2>
<p>The <a href="https://www.digitaltwinconsortium.org/initiatives/the-definition-of-a-digital-twin/">Digital Twin Consortium</a> defines a twin as a virtual representation of real things and processes, synchronised at a specified frequency and fidelity. In practice a building twin comes in three levels, and each one costs more than the last.</p>
<ol>
<li><strong>Visual model.</strong> A real-time 3D copy you can walk through, built from the construction files. I turned SEVEN&rsquo;s Revit, IFC and Navisworks models for <a href="https://tawfik.tv/projects/seven-al-hamra">Al Hamra in Riyadh</a> into a building you can walk in a browser, before it was built. At Expo 2020 Dubai my team of 12 worked on <a href="https://virtualexpodubai.com">Virtual Expo Dubai</a>, the whole site in real-time 3D. The Expo closed. The twin is still live.</li>
<li><strong>Live data twin.</strong> The same model with real readings on it: who is in which room, what each circuit draws, which work orders are open. This is the &ldquo;synchronised&rdquo; half of the definition.</li>
<li><strong>Simulation twin.</strong> The live twin plus a model that predicts: what happens to energy use if you change a setpoint, and which equipment is quietly wasting power.</li>
</ol>
<p>For the FIFA World Cup in Qatar, Expo 2020 and SEVEN, I turned engineering models into live Unreal and Unity environments. That is the first level. The other two levels are where sensors, platforms and monthly fees come in.</p>
<h2>How much does it cost to build a digital twin?</h2>
<p>These are the lines for the sample office, from published prices checked in October 2026, in US dollars.</p>
<ul>
<li><strong>Laser scan of the building:</strong> <a href="https://www.thefuture3d.com/blog/scan-to-bim-cost-guide/">$0.20 to $0.70 per sq ft</a>, so $8,000 to $28,000 (The Future 3D, March 2026).</li>
<li><strong>BIM model from the scan, at LOD 300:</strong> <a href="https://www.thefuture3d.com/blog/scan-to-bim-cost-guide/">$1.50 to $3.50 per sq ft</a>, so $60,000 to $140,000. Skip both lines if you already have the BIM, as SEVEN did. You still pay for the clean-up that makes it run in real time.</li>
<li><strong>Occupancy sensors:</strong> <a href="https://www.density.io/">$229 per sensor plus $8 per room a month</a> on Density&rsquo;s published price list: $9,160 for 40 rooms, then $320 a month.</li>
<li><strong>Energy submeters:</strong> in a <a href="https://www.gsa.gov/system/files/046-Submeters%20and%20Analytics-%20Single%20circuit%20meter-Findings-508.pdf">GSA field test</a> (January 2021), each measured load cost $900 installed, $470 for equipment and $431 for the electrician, with analytics at $12 to $48 per meter a year. For 24 loads: $21,600.</li>
<li><strong>Maintenance tickets:</strong> MaintainX Premium is <a href="https://www.getmaintainx.com/pricing">$65 per user a month</a>, billed annually, and it is the plan with API access, which you need to put tickets on the model. Five technicians: $325 a month.</li>
<li><strong>Fault-finding and analytics software:</strong> across Lawrence Berkeley National Laboratory&rsquo;s campaign, the <a href="https://www.energy.gov/sites/default/files/2019/05/f62/bto-peer%E2%80%932019-lbnl-smart-energy-analytics-campaign.pdf">median cost was $0.03 per sq ft to install and $0.02 per sq ft a year</a> (2019). For this office: $1,200, then about $67 a month.</li>
<li><strong>Energy simulation engine:</strong> <a href="https://www.energy.gov/eere/buildings/articles/energyplus">EnergyPlus</a> is the US Department of Energy&rsquo;s open-source engine, so the software is free. Building and calibrating the model is engineering time, quoted per project.</li>
</ul>
<p>Switch layers on below and watch the plan, the ledger and the timeline change. The figures are the ones above.</p>
<p><a href="https://tawfik.tv/notes/digital-twin-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>How much does a digital twin platform cost?</h2>
<p>The platform holds the model and the live data and is the smallest line on the bill.</p>
<ul>
<li><strong><a href="https://www.autodesk.com/products/tandem/overview">Autodesk Tandem</a>:</strong> from $267 a month, with a free tier to try it. Built around BIM, so it suits facilities that already have Revit models.</li>
<li><strong><a href="https://aws.amazon.com/iot-twinmaker/pricing/">AWS IoT TwinMaker</a>:</strong> $1.50 per million data calls, $0.05 per entity a month and $0.50 per 10,000 queries. AWS&rsquo;s own 800-entity example comes to $197.53 a month, or $220 on the fixed bundle.</li>
<li><strong><a href="https://prices.azure.com/api/retail/prices?$filter=serviceName%20eq%20%27Digital%20Twins%27">Azure Digital Twins</a>:</strong> pay per use. In East US, $2.50 per million operations, $1.00 per million messages and $0.50 per million query units. 64 devices sending one reading a minute is about 2.8 million operations and as many messages a month, roughly $10.</li>
</ul>
<h3>Which digital twin software is best?</h3>
<p>It depends on who runs it. Tandem if your facilities team has the BIM and wants a product on day one. Azure Digital Twins if you have developers and want your own app on a graph you control. TwinMaker if your data already lives on AWS. For the 3D people actually walk through, on a phone or in a browser, I use Unity and Unreal; how I get a 650 MB model down to a 74 MB build is in <a href="https://tawfik.tv/notes/unity-webgl-mobile">Unity WebGL on mobile</a>.</p>
<h2>How long does a digital twin take?</h2>
<ul>
<li><strong>3D model from existing BIM:</strong> SEVEN Al Hamra took just under 12 weeks from first access to sign-off, by hand.</li>
<li><strong>Laser scan:</strong> 1 to 21 days of turnaround, before the modelling starts.</li>
<li><strong>Energy meters:</strong> at the GSA test, an electrician installed 6 meters in 6 hours. In a <a href="https://origin-www.gsa.gov/system/files/19-Submetering%20and%20Analytics%20%28Full%20Panel%29.pdf">GSA full-panel test</a> (May 2019), 5 panels with 96 breakers took 14 hours, and connecting the data to GSA&rsquo;s analytics platform took 12 hours.</li>
</ul>
<p>Sensors, tickets and simulation have no public install times. They run alongside the model, so the model sets the date.</p>
<h2>Where do digital twin cost savings come from?</h2>
<p>The savings come from the data layers. These are the published results.</p>
<ul>
<li><strong>Fault detection:</strong> in LBNL&rsquo;s campaign of 96 organisations and nearly 6,000 buildings, <a href="https://www.energy.gov/cmei/buildings/articles/smart-energy-analytics-campaign-reveals-continued-energy-and-cost-savings">fault detection tools gave a median 9% energy saving</a>, $0.24 per sq ft a year, with a one to two year simple payback (US DOE, November 2019). For 40,000 sq ft that is about $9,600 a year.</li>
<li><strong>Energy information:</strong> the same campaign found a median 4% saving, $0.04 per sq ft, from energy information systems alone.</li>
<li><strong>Submeters:</strong> at a courthouse in Salt Lake City, circuit-level submeters paid back in 0.6 years, from fairer tenant billing and a 10% average cut in HVAC load in the <a href="https://origin-www.gsa.gov/system/files/19-Submetering%20and%20Analytics%20%28Full%20Panel%29.pdf">GSA test</a>.</li>
<li><strong>Maintenance:</strong> the DOE&rsquo;s <a href="https://www.energy.gov/sites/default/files/2020/04/f74/omguide_complete_w-eo-disclaimer.pdf">O&amp;M Best Practices Guide</a> estimates preventive maintenance saves 12% to 18% over fixing things when they break, and predictive maintenance 8% to 12% more.</li>
</ul>
<p>The visual model pays back differently. Before opening, a model like SEVEN Al Hamra&rsquo;s does leasing, pre-opening marketing and design reviews.</p>
<h2>How do you start a digital twin small?</h2>
<ol>
<li><strong>Pick one number.</strong> Energy cost per sq ft, open work orders, or rooms booked but empty. Every layer has to move it.</li>
<li><strong>Use the files you have.</strong> BIM, CAD, floor plans. On SEVEN Al Hamra the construction models were the start: the building was not built yet, so there was nothing to scan.</li>
<li><strong>Start on one floor.</strong> Meter the big loads and put sensors in the meeting rooms. That is under $8,000 on the lists above.</li>
<li><strong>Rent the platform month to month.</strong> The platform is the cheapest line. Change it later if you outgrow it.</li>
<li><strong>Add fault detection before simulation.</strong> Its published payback is one to two years.</li>
<li><strong>Scale floor by floor</strong> once the number moves.</li>
</ol>
<p>If you want the 3D side, I compare engines, devices and costs for stores, shows and venues in <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores, live shows and 3D worlds</a>.</p>
<h2>Questions people ask</h2>
<h3>What is a digital twin?</h3>
<p>A live, virtual copy of a real building, machine or process, kept in step with the real thing by sensor data, so you can see, test and plan on the copy first. The <a href="https://www.digitaltwinconsortium.org/initiatives/the-definition-of-a-digital-twin/">Digital Twin Consortium</a> defines it as a virtual representation synchronised at a specified frequency and fidelity.</p>
<h3>How much does a digital twin cost?</h3>
<p>For a 40,000 sq ft office, about $32,000 for sensors, meters and software if you already have the BIM, and about $100,000 to $200,000 if you have to scan and model it first. Running it costs about $750 to $1,100 a month with every layer on.</p>
<h3>What is the cheapest digital twin platform?</h3>
<p>On usage, Azure Digital Twins: a small building can run for tens of dollars a month. Autodesk Tandem starts at $267 a month and AWS IoT TwinMaker&rsquo;s bundle at $220 in AWS&rsquo;s own example.</p>
<h3>Do I need a 3D model for a digital twin?</h3>
<p>For the live data, no: a floor plan can show it. For people to walk the building before it opens, or to see where a fault sits behind a ceiling, yes.</p>
<h3>What are the cost savings of a digital twin for buildings?</h3>
<p>Published medians are 9% of energy cost from fault detection and 4% from energy information systems, with one to two year paybacks. Preventive maintenance saves 12% to 18% over fixing things when they break.</p>
<h3>How long does it take to build a digital twin?</h3>
<p>The model sets the pace. SEVEN Al Hamra took just under 12 weeks from construction models to a signed-off build. Meters go in within days.</p>
<p>If you have the BIM and want a twin people can walk through, see <a href="https://tawfik.tv/hire/3d-web-experiences">how I take on 3D web projects</a> or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>What is an AI agent? The parts, real examples, and the one rule</title><link>https://tawfik.tv/notes/what-is-an-ai-agent</link><guid>https://tawfik.tv/notes/what-is-an-ai-agent</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>An AI agent is an AI model given a job, tools and a loop so it can act for you. Its parts, everyday examples, and why its tools set what it can break.</description>
<content:encoded><![CDATA[<p>An AI agent is an AI model that takes actions for you. You give it a job and some tools, such as a web browser, your files or your email, and it works in a loop: look, decide, act, check, until the job is done or it gets stuck.</p>
<p>Agents are still new, even for software developers. In the <a href="https://survey.stackoverflow.co/2025/ai">Stack Overflow 2025 Developer Survey</a> (July 2025), 14.1% said they use AI agents at work daily and 9% weekly, while 52% either don&rsquo;t use agents or stick to simpler AI tools.</p>
<p>I build agents and the guards around them. I set up an AI help desk for a fintech platform that can read and explain, and can never change an account. I built <a href="https://github.com/tawfff/mlx-agent">mlx-agent</a>, an open-source agent that runs open models on a Mac, searches the web and runs commands you approve. And I lead product for <a href="https://gvnr.io">GVNR</a>, a free, source-available guard that checks what an agent is about to do before it does it.</p>
<h2>What is an AI agent?</h2>
<p>Anthropic, which makes Claude, describes agents as &ldquo;systems where LLMs dynamically direct their own processes and tool usage&rdquo; (<a href="https://www.anthropic.com/engineering/building-effective-agents">Building effective agents</a>, December 2024). OpenAI&rsquo;s <a href="https://cdn.openai.com/business-guides-and-resources/a-practical-guide-to-building-agents.pdf">practical guide to building agents</a> is shorter: &ldquo;Agents are systems that independently accomplish tasks on your behalf.&rdquo;</p>
<p>In plain words: a chatbot gives you an answer and you do the work. An agent does the work. Ask a chatbot to book a table for four on Friday and it suggests restaurants. Ask an agent and it opens the booking site, picks a time, fills in the form, and should ask you before it pays the deposit.</p>
<p>&ldquo;Agentic AI&rdquo; is the wider term, for systems of several agents and how a business puts them to work. That has its own page: <a href="https://tawfik.tv/notes/agentic-ai">what agentic AI is and how companies deploy it</a>. This page is about one agent and what it is made of.</p>
<h2>What are the parts of an AI agent?</h2>
<p>Five parts. OpenAI&rsquo;s guide names the first three as an agent&rsquo;s core components.</p>
<ol>
<li><strong>The model.</strong> A language model that reads, writes and decides the next step. It can come from any provider, or run on your own computer.</li>
<li><strong>Instructions.</strong> The job description: what to do, what to avoid, when to stop. Instructions are a request, and the model can get them wrong. Claude Code&rsquo;s own documentation says it treats its instruction files &ldquo;as context, not enforced configuration&rdquo;, and points you to a hook if you need to block an action whatever the model decides (<a href="https://code.claude.com/docs/en/memory">How Claude remembers your project</a>).</li>
<li><strong>Tools.</strong> Each tool is a key to something: a browser, a folder of code, a terminal, an email account, a database, a payment card. Without tools, an agent can only talk. Many tools now plug in through MCP, the Model Context Protocol, which is why the <a href="https://tawfik.tv/notes/mcp-security-checklist">MCP security checklist</a> matters.</li>
<li><strong>Memory.</strong> Most agents start every session blank. In Claude Code&rsquo;s words, &ldquo;each Claude Code session begins with a fresh context window.&rdquo; What carries over is usually a notes file the agent reads at the start: <a href="https://agents.md/">AGENTS.md</a>, &ldquo;a README for agents&rdquo; supported by Codex, Cursor and Gemini CLI, or CLAUDE.md for Claude Code.</li>
<li><strong>The loop.</strong> The agent looks at the situation, decides one step, takes it with a tool, checks the result, and goes round again. It stops when the job is done, when it runs out of steps, or when it has to ask you.</li>
</ol>
<p>Try it on an office. Pick a job for the agent, hand it keys from the cabinet, and see which rooms it can now reach and what it could break in each. Then run a shift and watch the loop.</p>
<p><a href="https://tawfik.tv/notes/what-is-an-ai-agent">Open the interactive diagram on tawfik.tv</a></p>

<h2>What AI agents do people use today?</h2>
<p><strong>Coding agents.</strong> Claude Code, Cursor, Codex and Gemini CLI read a project, edit files and run commands in a terminal. Each has approval settings that decide which commands need a yes from you first. I list the settings for all four in <a href="https://tawfik.tv/notes/ai-agent-deleted-database">how to stop an AI agent deleting your database</a>.</p>
<p><strong>Customer support agents.</strong> They answer customers from a help centre, look up the customer&rsquo;s own orders and hand anything else to a person. On the fintech help desk I set up, the agent never gets the platform&rsquo;s tools that move money. When I tested it by asking it to send a customer&rsquo;s cash-out to a third party, it refused and passed the conversation to a person. The setup and the prices are in <a href="https://tawfik.tv/notes/ai-customer-service-agent">AI customer service agent: what it can safely do</a>.</p>
<p><strong>Browser agents.</strong> These drive a web browser for you: search, click, fill in forms. OpenAI says its <a href="https://openai.com/index/introducing-chatgpt-agent/">ChatGPT agent</a> (July 2025) asks permission before actions of consequence, and you can interrupt it or take over the browser at any point. Anthropic says <a href="https://claude.com/blog/claude-for-chrome">Claude in Chrome</a> (August 2025) asks you before publishing, purchasing or sharing personal data.</p>
<p><strong>Agents on your own computer.</strong> mlx-agent runs open models on a Mac, searches the web, reads pages, and runs only the shell commands you approve.</p>
<h2>What can an AI agent do, and what can&rsquo;t it?</h2>
<p>It does well at jobs with many small steps and a clear finish line: find the bug and run the tests, answer the question from the help article, compare five pages and fill in one form. It works at any hour and does not get bored of the hundredth look-up.</p>
<p>It cannot:</p>
<ul>
<li><strong>Tell your instructions apart from text it reads.</strong> A web page, an email or a support ticket can hide orders aimed at the agent. This is called prompt injection. In Anthropic&rsquo;s own tests of Claude in Chrome, 123 attack cases across 29 scenarios, attacks succeeded 23.6% of the time without its new safety measures and 11.2% with them (<a href="https://claude.com/blog/claude-for-chrome">Claude in Chrome</a>, August 2025).</li>
<li><strong>Know that it is right.</strong> It can sound certain and be wrong, so the answer should come from a source it links to.</li>
<li><strong>Remember last week</strong>, unless someone wrote it into its notes file.</li>
<li><strong>Do anything without a tool.</strong> Every action goes through a key you handed it.</li>
<li><strong>Take the blame.</strong> A person owns what the agent does, so a person should own its keys.</li>
</ul>
<h2>What is the one rule for AI agents?</h2>
<p>Whatever its tools can reach, it can break.</p>
<p>An agent with a read-only key to your help centre can, at worst, quote the wrong article. The same agent with the refund button can send money to the wrong place, and with your live database password one command can delete your customer data. In July 2025 an agent on Replit <a href="https://tawfik.tv/notes/ai-agent-deleted-database">deleted a founder&rsquo;s database during a code freeze</a>. Telling an agent &ldquo;don&rsquo;t&rdquo; is a request. Taking the key away is a control.</p>
<p>So the safe way to start is short:</p>
<ol>
<li><strong>Give it one job</strong> with a clear finish line.</li>
<li><strong>Hand over read-only keys first.</strong> Add a key only when the job proves it needs one.</li>
<li><strong>Make it ask a person</strong> before anything it cannot undo: deleting, paying, sending, publishing.</li>
<li><strong>Keep a record</strong> of what it did, and read it.</li>
</ol>
<p>That is what GVNR does. It is free and source-available under FSL-1.1-ALv2 (<a href="https://github.com/instruxi-io/enforcer-governor">code on GitHub</a>), runs on your own machine, and works with Claude Code, Cursor, Codex, Gemini CLI and any other MCP client. Before each action it answers allow, deny or ask a person, and it keeps a hash-chained record of every decision, so an edited line shows. When you have more than one agent, the <a href="https://tawfik.tv/notes/ai-agent-governance">AI agent governance framework</a> covers owners, identities, limits and reviews.</p>
<h2>Questions people ask</h2>
<h3>What is an AI agent in simple terms?</h3>
<p>An AI that does tasks for you instead of only answering. It has a job, a set of tools and a loop: look, decide, act, check, repeat.</p>
<h3>What is the difference between an AI agent and a chatbot?</h3>
<p>A chatbot answers and you act. An agent holds tools, so it can act itself: edit a file, fill in a form, send an email or issue a refund.</p>
<h3>What are examples of AI agents?</h3>
<p>Coding agents such as Claude Code, Cursor, Codex and Gemini CLI; customer support agents that answer from a help centre; and browser agents such as ChatGPT agent and Claude in Chrome.</p>
<h3>Are AI agents safe?</h3>
<p>As safe as the keys you hand them. Start read-only, make anything irreversible wait for a person, and keep a record. A prompt that says &ldquo;be careful&rdquo; is not a control.</p>
<h3>What is the difference between an AI agent and agentic AI?</h3>
<p>An AI agent is one worker with a job and tools. Agentic AI is the wider idea of systems that act on their own, often several agents together. See <a href="https://tawfik.tv/notes/agentic-ai">agentic AI</a>.</p>
<p>If you need an agent built, or guardrails around the agents you already run, <a href="https://tawfik.tv/hire/fractional-cpo">write to me</a> at m@tawfik.tv.</p>]]></content:encoded></item><item><title>How to put a loyalty stamp card in Apple and Google Wallet, and pair it with online booking</title><link>https://tawfik.tv/notes/digital-stamp-card</link><guid>https://tawfik.tv/notes/digital-stamp-card</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A Wallet stamp card is a pass customers add from a link, with no app. After each visit your server updates it and the phone shows the new stamp.</description>
<content:encoded><![CDATA[<p>To put a stamp card in Apple Wallet and Google Wallet, you give each customer a pass from a link, and your booking system updates that pass every time they visit. There is no app to download: Apple calls it a store card, Google calls it a loyalty object, and both phones redraw the card with the new stamp on their own.</p>
<p>Most UK adults are already set up to pay with their phone: 65% of them were registered for at least one mobile payment service in 2025, up from 57% in 2024, according to <a href="https://www.ukfinance.org.uk/news-and-insight/press-release/digital-payments-continue-grow-mobile-wallets-become-more-popular">UK Finance&rsquo;s UK Payment Markets Report 2025</a>, published in August 2026.</p>
<p>I build online booking with Wallet stamp cards for local service businesses: a car care business where every car gets its own card, and a dog club where every dog has a membership. Here is how the pieces work, checked against Apple&rsquo;s and Google&rsquo;s developer docs.</p>
<h2>How does a digital loyalty card (stamp card) in Wallet work?</h2>
<ol>
<li><strong>The customer books online.</strong> The booking creates their record, and the confirmation page shows an Add to Apple Wallet or Add to Google Wallet button.</li>
<li><strong>They tap it once.</strong> The card sits in Wallet next to their bank cards, with the business name, the stamps and a barcode.</li>
<li><strong>They turn up.</strong> Staff scan the barcode or open the booking and mark the visit done.</li>
<li><strong>The server adds the stamp.</strong> Apple or Google tells the phone, and the card redraws.</li>
<li><strong>The card fills up.</strong> The reward shows. Staff scan it to use the reward, and the count starts again.</li>
</ol>
<p>The server holds the count and the card only shows it.</p>
<p><a href="https://tawfik.tv/notes/digital-stamp-card">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you make an Apple Wallet loyalty card?</h2>
<p>Apple&rsquo;s format is a pass: a signed bundle with a <code>.pkpass</code> extension. For loyalty you use the <a href="https://developer.apple.com/documentation/walletpasses/pass/storecard-data.dictionary">store card</a> style, Apple&rsquo;s pass type for loyalty, gift and points cards. The steps, from Apple&rsquo;s <a href="https://developer.apple.com/documentation/walletpasses/building-a-pass">Building a Pass</a>:</p>
<ol>
<li><strong>Join the Apple Developer Program</strong>, at <a href="https://developer.apple.com/programs/whats-included/">$99 a year</a>, for access to Certificates, Identifiers and Profiles.</li>
<li><strong>Create a pass type identifier</strong>, a reverse-DNS string for your business and card.</li>
<li><strong>Generate a Pass Type ID certificate</strong> from a certificate signing request.</li>
<li><strong>Write <code>pass.json</code></strong>: name, serial number, colours, stamp count, barcode, and the <code>webServiceURL</code> and <code>authenticationToken</code> that let you update it later.</li>
<li><strong>Add the images.</strong> On store cards, a <a href="https://developer.apple.com/design/human-interface-guidelines/wallet">strip image</a> runs across the card, a natural place for the row of stamps.</li>
<li><strong>Sign and package it.</strong> Write <code>manifest.json</code> with a SHA-1 hash of every file, sign it with a PKCS #7 detached signature using the certificate, zip the folder and rename it to <code>.pkpass</code>.</li>
</ol>
<p>Apple treats each pass type identifier plus serial number as one unique pass. So one card per car is simply one serial number per car.</p>
<p>Passes can be handed out from a web page, by email or from an app (<a href="https://developer.apple.com/documentation/walletpasses/distributing-and-updating-a-pass">Apple</a>). For a local business, the booking confirmation page is the one that matters.</p>
<h2>How does an Apple Wallet pass update after each visit?</h2>
<p>Apple&rsquo;s <a href="https://developer.apple.com/documentation/walletpasses/adding-a-web-service-to-update-passes">web service guide</a> sets out the loop:</p>
<ol>
<li>When the customer adds the pass, their phone registers it with your server and sends a device ID and a push token.</li>
<li>After a visit, your server sends a push through Apple&rsquo;s push service, with an empty payload.</li>
<li>The phone asks your server which passes changed, then downloads each new version.</li>
</ol>
<p>The lock-screen message comes from a field&rsquo;s <a href="https://developer.apple.com/documentation/walletpasses/passfieldcontent"><code>changeMessage</code></a>, a format string such as <code>Stamps: %@</code>, where Wallet fills in the new value. Leave it out and the card updates quietly. Two catches from the same guide: the web service must use HTTPS in production, and update pushes only work in the production environment.</p>
<h2>How do you make a Google Wallet loyalty card?</h2>
<p>Google splits the card in two. A <a href="https://developers.google.com/wallet/retail/loyalty-cards/resources/terminology">loyalty class</a> is the programme, shared by everyone: name, logo, colours. A loyalty object is one customer&rsquo;s card in that programme, with their account, points balance and barcode. The <a href="https://developers.google.com/wallet/retail/loyalty-cards/overview/add-to-google-wallet-flow">flow</a>:</p>
<ol>
<li><strong>Set up an issuer account</strong> in the Google Pay and Wallet console.</li>
<li><strong>Create the loyalty class</strong> once.</li>
<li><strong>Create a loyalty object</strong> per customer, or per car, or per dog.</li>
<li><strong>Sign it.</strong> Put the object in a JSON Web Token signed with your Google Cloud service account key. That token becomes the <a href="https://developers.google.com/wallet/retail/loyalty-cards/use-cases/jwt">Add to Google Wallet link</a>.</li>
<li><strong>Ask to go live.</strong> New issuer accounts start in <a href="https://developers.google.com/wallet/retail/loyalty-cards/test-and-go-live/request-publishing-access">demo mode</a>, where only test accounts can save passes and each pass is marked &ldquo;[TEST ONLY]&rdquo;, until the Google Wallet team grants publishing access.</li>
</ol>
<p>To add a stamp, you patch the object&rsquo;s <code>loyaltyPoints.balance</code>. Per Google&rsquo;s <a href="https://developers.google.com/pay-wallet/products/wallet/retail/loyalty-cards/use-cases/updates">update guide</a>, changing the class updates every holder, while changing an object affects only that customer.</p>
<h2>Can Google Wallet send a notification when a stamp is added?</h2>
<p>Yes, within a limit set out in Google&rsquo;s <a href="https://developers.google.com/wallet/retail/loyalty-cards/use-cases/trigger-push-notifications">push notification guide</a>. Add <code>notifyPreference: notifyOnUpdate</code> to the update, and a change to <code>loyaltyPoints.balance</code> puts a notification on the lock screen. You can also add a message with the type <code>TEXT_AND_NOTIFY</code>. Both share one cap: 3 notifications per pass in 24 hours, and the customer must have Wallet notifications switched on.</p>
<p>So I spend Wallet notifications on the stamp and the reward, and send booking confirmations by email or message. Switch the demo above to Android and book a few times to watch the cap kick in.</p>
<h2>Can the card show up when the customer is nearby?</h2>
<ul>
<li><strong>Apple</strong> lets a pass list up to 10 locations, and Wallet can put it on the lock screen near one of them. Test on a real phone: Simulator does not show passes on the lock screen (<a href="https://developer.apple.com/documentation/walletpasses/showing-a-pass-on-the-lock-screen">Apple</a>).</li>
<li><strong>Google</strong> takes up to 10 locations per class and 10 per object, and reminds customers who gave Google Wallet precise, always-on location access. Google decides the distance and the wording (<a href="https://developers.google.com/wallet/retail/loyalty-cards/use-cases/trigger-push-notifications">Google</a>).</li>
</ul>
<p>A good extra, not the business case.</p>
<h2>Can customers tap the card on a reader?</h2>
<p>They can, and a small business rarely needs it. Apple&rsquo;s NFC passes <a href="https://developer.apple.com/documentation/walletpasses/pass/nfc-data.dictionary">need a special entitlement issued by Apple</a>, and Google&rsquo;s <a href="https://developers.google.com/wallet/smart-tap">Smart Tap</a> needs a certified terminal. Staff scanning the barcode with a phone does the same job on day one.</p>
<h2>Wallet card, paper card or loyalty app: which is better?</h2>
<ul>
<li><strong>Paper stamp card.</strong> Cheap, and everyone takes one. It gets lost, is easy to fill by hand, and tells the owner nothing: no name, no visit history, no way to invite someone back.</li>
<li><strong>Loyalty app.</strong> It can do the most, but the customer has to find it, download it and make an account before the first stamp. A local business is asking for space next to apps people already use.</li>
<li><strong>Wallet card.</strong> One tap from the booking page, no account, and it updates itself. The limits: Apple&rsquo;s and Google&rsquo;s templates decide the layout, Google caps notifications, and you run a small server.</li>
</ul>
<h2>Why pair the stamp card with online booking?</h2>
<p>Because the booking is where the card gets its data.</p>
<ul>
<li><strong>Every customer gets a card.</strong> It is issued with the booking, so nobody has to remember to offer one.</li>
<li><strong>A stamp is a tap on a booking.</strong> The visit is already in the system, so staff close it and the stamp follows.</li>
<li><strong>No-shows are visible.</strong> A missed slot is recorded against the card, so the owner sees who books and does not come.</li>
<li><strong>Repeat visits become a number</strong>, not a feeling.</li>
<li><strong>The card can belong to the thing.</strong> One card per car, per dog or per member, each with its own count.</li>
</ul>
<h2>What&rsquo;s the best booking system for a small business or salon?</h2>
<p>For most small salons, a ready-made system is the right start, and several have a free plan. A custom booking system with a Wallet card pays off when loyalty is part of what you sell, or when the card has to belong to a car, a dog or a membership instead of a person.</p>
<p>Here is what the main options charge, from their own pricing pages on 15 October 2026.</p>
<ul>
<li><strong><a href="https://squareup.com/gb/en/appointments/pricing">Square Appointments</a>, UK.</strong> Free plan at £0 a month for a single location. Plus is £29 and Premium £69 a month per location. In-person card payments are 1.75% on Free and 1.6% on the paid plans, and online UK cards are 1.4% + 25p. <a href="https://squareup.com/gb/en/software/loyalty">Square Loyalty</a> is separate: £25 to £65 a month per location, depending on loyalty visits.</li>
<li><strong><a href="https://www.fresha.com/for-business/salon/best-salon-software">Fresha</a>.</strong> $19.95 a month for a one-person business, or $14.95 per team member a month, in US dollars; prices differ by country. Client loyalty is a paid add-on per location.</li>
<li><strong><a href="https://biz.booksy.com/en-gb/pricing">Booksy</a>, UK.</strong> £40 a month with all features, plus £5 a month for each extra staff member. Its Boost marketplace charges a one-time 30% fee, minimum £5, on a new client&rsquo;s first visit. Card payments are 1.29% + 20p + VAT.</li>
<li><strong><a href="https://simplybook.me/en/pricing">SimplyBook.me</a>.</strong> Free for 50 bookings a month and one provider. Basic is €11.90 a month billed yearly (100 bookings, 5 providers), Standard €24.90 (500 bookings, 15 providers) and Premium €49.90 (2,000 bookings, 30 providers). SimplyBook itself takes no fee per booking.</li>
<li><strong><a href="https://calendly.com/pricing">Calendly</a>.</strong> Free for one event type and one calendar connection. Standard is $10 and Teams $16 a seat a month, billed yearly. It is made for scheduling meetings, so it suits a consultant better than a salon with chairs, staff and services.</li>
</ul>
<p><a href="https://tawfik.tv/notes/digital-stamp-card">Open the interactive diagram on tawfik.tv</a></p>

<p>How I&rsquo;d pick between them:</p>
<ol>
<li><strong>One person, standard services.</strong> Start on a free plan and pay the card fees.</li>
<li><strong>A team.</strong> Price it per person, since Fresha, Booksy and Calendly all charge more as you add staff.</li>
<li><strong>New clients from a marketplace.</strong> Booksy&rsquo;s Boost fee is what a new client costs you, so compare it with what else you spend to win one.</li>
<li><strong>Loyalty.</strong> Check whether it is built in or an add-on, and whether the card can live in Apple and Google Wallet.</li>
</ol>
<h2>Is there a free booking system?</h2>
<p>Yes. Square Appointments, SimplyBook.me and Calendly all have free plans that cost nothing a month. Each has a limit: one location on Square, 50 bookings a month on SimplyBook.me, one event type on Calendly. You still pay card processing fees when customers pay online.</p>
<h2>How much does it cost to create a loyalty app?</h2>
<p>There is no fixed price, since it depends on what you build. The fixed parts are small and published.</p>
<ul>
<li><strong>Apple Developer Program:</strong> <a href="https://developer.apple.com/programs/whats-included/">$99 a year</a>, needed for Wallet passes and for an iPhone app.</li>
<li><strong>Google Play developer account:</strong> a <a href="https://support.google.com/googleplay/android-developer/answer/6112435?hl=en">one-time US$25 registration fee</a>, needed only for an Android app. A Google Wallet card comes from an issuer account in the Google Pay and Wallet console instead.</li>
<li><strong>Ready-made Wallet stamp cards:</strong> <a href="https://www.loopyloyalty.com/pricing">Loopy Loyalty</a> lists $25 a month for one card design and one location, up to $95 a month for ten of each.</li>
</ul>
<p>The rest is the build and a small server. A Wallet card skips the app store, the download and the account, which is why I build loyalty as a card first.</p>
<h2>When does a custom booking system with a Wallet card make sense?</h2>
<ul>
<li><strong>The card belongs to a thing.</strong> One card per car, per dog or per membership, each with its own count.</li>
<li><strong>Your rewards follow your own rules,</strong> such as bigger jobs earning more stamps, which a ready-made loyalty add-on may not offer.</li>
<li><strong>You pay for several tools that don&rsquo;t talk to each other:</strong> booking, loyalty and messages, each charged per staff member or per location.</li>
<li><strong>You want your own brand and your own customer list,</strong> kept in your own database and locked down (<a href="https://tawfik.tv/notes/supabase-security-checklist">this is how I check that</a>), not a listing next to other businesses on a marketplace.</li>
<li><strong>You want the visit, the no-show and the stamp in one record,</strong> as in the pairing above.</li>
</ul>
<p>If none of those apply, a ready-made system on a free or low plan is the right call.</p>
<h2>What I built for a car care business and a dog club</h2>
<p><strong>A car care business.</strong> Booking in any phone browser, a staff view to run the day, and a Wallet stamp card per car, not per person. Bigger jobs earn more stamps, so more work on the car earns better offers.</p>
<p><strong>A dog club.</strong> Every dog has a member card. Owners book stays and day care online, staff run the day from one dashboard, and the card belongs to the dog, not the owner.</p>
<p>Both run in the browser with no app to install. I built them with AI in the loop as I describe in <a href="https://tawfik.tv/notes/one-person-ai-team">can one person with AI do a whole team&rsquo;s work</a>.</p>
<h2>Questions people ask</h2>
<h3>Do customers need to download an app for a Wallet loyalty card?</h3>
<p>No. Apple Wallet is built into the iPhone, and on Android the customer saves the card to Google Wallet from a link. One tap from the booking page in both cases.</p>
<h3>Does a digital stamp card work on both iPhone and Android?</h3>
<p>Yes, as two builds: a <code>.pkpass</code> for Apple Wallet, and a loyalty class with one object per card for Google Wallet.</p>
<h3>What does it cost to issue Apple Wallet passes?</h3>
<p>Apple requires an Apple Developer Program membership, $99 a year, for the pass type ID and signing certificate. On top of that you pay for the build and a small server that holds the counts and sends the updates.</p>
<h3>What stops someone faking stamps?</h3>
<p>The count lives on your server, not on the card. A stamp only lands when staff close a booking, and the card shows whatever the server says.</p>
<h3>What happens if a customer deletes the card or changes phone?</h3>
<p>They add it again from the same link. The stamps are on your server, so the new card shows the same count.</p>
<h3>What is the best free booking system for a small business?</h3>
<p>Square Appointments, SimplyBook.me and Calendly all have free plans. Square&rsquo;s covers a single location, SimplyBook.me&rsquo;s covers 50 bookings a month and Calendly&rsquo;s covers one event type. Card fees still apply when customers pay.</p>
<h3>How much does a loyalty app cost?</h3>
<p>The published fixed costs are Apple&rsquo;s $99 a year and, for an Android app, Google Play&rsquo;s US$25 once. Ready-made Wallet stamp card services start at $25 a month. A custom build adds design, build and a small server on top.</p>
<h3>How much does loyalty program software cost?</h3>
<p>On their own pricing pages, Square Loyalty is £25 to £65 a month per location, depending on loyalty visits, and Loopy Loyalty lists $25 a month for one card design and one location, up to $95 a month for ten of each. Fresha sells client loyalty as a paid add-on per location. Before you compare prices, check whether the card can live in Apple and Google Wallet and whether it is tied to your bookings.</p>
<p>If you need online booking and a Wallet stamp card built for your business, see <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and Wallet loyalty cards</a> or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>How much does a small business website cost in 2026? Three routes, priced from the source</title><link>https://tawfik.tv/notes/small-business-website-cost</link><guid>https://tawfik.tv/notes/small-business-website-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A small business website costs $17 to $29 a month on a builder, most often $1,500 to $5,000 from a freelancer, and $1,000 to $50,000 from an agency.</description>
<content:encoded><![CDATA[<p>A small business website costs $17 to $29 a month if you build it yourself on Squarespace, Wix or Shopify, most often $1,500 to $5,000 if a freelancer builds it on one of them, and $1,000 to $20,000 from an agency, rising to $50,000 for a shop or a custom booking system. On top of the build you pay every month: the plan or hosting, the domain, email, booking and upkeep.</p>
<p>In GoodFirms&rsquo; survey of more than 300 web development firms in 31 countries, run in April and May 2026, 60% quote $1,000 to $3,000 for a basic website and 54% quote $5,000 to $20,000 for a mid-sized business site (<a href="https://www.goodfirms.co/resources/website-construction-cost-survey">GoodFirms, web development cost survey</a>).</p>
<p>I build websites, online booking and Wallet loyalty cards for local service businesses, and I run this site myself. Every price below is a US list price before tax, checked at its source on 15 October 2026.</p>
<h2>How much does a website for a small business cost?</h2>
<p>It depends on who builds it. Three routes:</p>
<ol>
<li><strong>Do it yourself on a builder.</strong> Nothing up front except your time. On annual billing, <a href="https://www.squarespace.com/pricing">Squarespace</a> Basic is $19 a month and Core $29, <a href="https://www.wix.com/plans">Wix</a> Light is $17 and Core $29, and <a href="https://www.shopify.com/pricing">Shopify</a> Basic is $29. Paying month to month costs more: Squarespace Basic is $25 and Shopify Basic $39.</li>
<li><strong>A freelancer on a builder.</strong> The most common price for a low-code or no-code build in the GoodFirms survey is $1,500 to $5,000. <a href="https://clutch.co/web-designers/pricing">Clutch</a> puts designers who build on Wix, WordPress, Squarespace, Webflow and Shopify at $25 to $49 an hour. You still pay the builder plan.</li>
<li><strong>An agency or custom build.</strong> GoodFirms&rsquo; most common ranges: $1,000 to $3,000 for a basic website, $5,000 to $20,000 for a mid-sized business site, $5,000 to $50,000 for ecommerce and $20,000 to $50,000 for a custom web application. Hourly rates in the US and UK sit at $50 to $100 in that survey. Clutch puts US agencies at $100 to $149 an hour and UK agencies at $50 to $99, and says most web design projects reviewed on its site cost under $10,000.</li>
</ol>
<p>Tick what your business needs and switch routes. The preview builds the site for a made-up London dog groomer, and every quote line links to its source.</p>
<p><a href="https://tawfik.tv/notes/small-business-website-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>How much does a small business website cost per month?</h2>
<p>About $37 to $53 a month on a builder once you add email, a domain and booking, before card fees. These are the lines people forget:</p>
<ul>
<li><strong>The plan or the hosting.</strong> $17 to $29 a month on a builder. A custom site needs hosting, for example <a href="https://vercel.com/docs/plans/pro-plan">Vercel Pro</a> at $20 a month, which is what this site runs on, and a database, for example <a href="https://supabase.com/pricing">Supabase Pro</a> from $25 a month, once it stores bookings or orders.</li>
<li><strong>The domain.</strong> A .com is $11.08 a year at <a href="https://porkbun.com/tld/com">Porkbun</a>. Squarespace and Wix include the first year free on annual plans, then it renews at their standard rate.</li>
<li><strong>Email at your domain.</strong> <a href="https://workspace.google.com/pricing">Google Workspace</a> Business Starter is $7 per person a month on an annual plan. Squarespace includes the first year on Core and above.</li>
<li><strong>Booking.</strong> Squarespace uses <a href="https://www.acuityscheduling.com/pricing">Acuity Scheduling</a>: Starter is $16 a month billed yearly, $20 monthly. Wix includes booking from Core.</li>
<li><strong>Card fees.</strong> 2.9% + 30¢ per online card sale with Squarespace Payments on Basic and Core, <a href="https://support.wix.com/en/article/wix-payments-transaction-fees">Wix Payments</a>, Shopify Payments on Basic and <a href="https://stripe.com/pricing">Stripe</a>. Squarespace Basic adds a 2% fee on online store sales.</li>
<li><strong>Maintenance.</strong> GoodFirms says to plan for 15% to 20% of the build cost each year. Retainers run $500 to $1,500 a month at 30% of firms and $1,500 to $3,000 at 28%, and the two-year cost of a professionally built site typically runs 150% to 200% of the build.</li>
<li><strong>A Wallet loyalty card.</strong> Issuing Apple Wallet passes needs the <a href="https://developer.apple.com/programs/whats-included/">Apple Developer Program</a>, $99 a year.</li>
</ul>
<p>Example: Wix Core with booking, one email address and a .com is about $37 a month after year one, plus card fees.</p>
<h2>What does a small business website actually need?</h2>
<p>Fewer pages than you think, and five things:</p>
<ul>
<li><strong>Fast on a phone.</strong> Google&rsquo;s <a href="https://web.dev/articles/vitals">Core Web Vitals</a> set the bar: the main content loads within 2.5 seconds, the page responds to a tap within 200 milliseconds, and the layout does not jump (a layout shift score of 0.1 or less), for 75% of visits.</li>
<li><strong>Booking that takes two taps.</strong> Pick a time, confirm, get an email.</li>
<li><strong>A Google Business Profile.</strong> It is <a href="https://www.google.com/business/">free</a>, it puts you on Search and Maps, and it carries your Google reviews. Point its website and booking links at your booking page.</li>
<li><strong>Prices, hours, address and a phone number you can tap.</strong></li>
<li><strong>A reason to come back.</strong> A stamp card in the customer&rsquo;s phone works well for repeat visits. I wrote up <a href="https://tawfik.tv/notes/digital-stamp-card">how Apple and Google Wallet stamp cards work</a>.</li>
</ul>
<h2>Which route should you pick?</h2>
<ul>
<li><strong>Do it yourself</strong> if you have one location, simple services and some evenings.</li>
<li><strong>A freelancer on a builder</strong> if you want it done properly and still be able to change your prices yourself afterwards.</li>
<li><strong>An agency or custom build</strong> if your booking has rules a builder cannot follow, you want a loyalty card in Apple and Google Wallet, staff need their own view of the day, or you want customers and bookings in your own database.</li>
</ul>
<p>That last route is my work. For a car care business I built booking in any phone browser, a staff view to run the day and a Wallet stamp card per car, where bigger jobs earn more stamps. For a dog club, every dog has its own member card and owners book stays and day care online. Neither needs an app.</p>
<h2>What should you check before you pay?</h2>
<ol>
<li><strong>The domain is registered in your business&rsquo;s name, in your account.</strong></li>
<li><strong>You own every account:</strong> the builder or hosting, the Google Business Profile, analytics and email.</li>
<li><strong>The quote says what it leaves out.</strong> GoodFirms names the four items most often missing from first quotes: content, SEO setup, third-party licences and post-launch maintenance.</li>
<li><strong>Running costs are written down, line by line, per month.</strong></li>
<li><strong>Who fixes it when it breaks, how fast, and at what rate.</strong></li>
<li><strong>You can export your pages, customers and bookings</strong> if you leave.</li>
<li><strong>Booking and payment fees per transaction are on paper.</strong></li>
<li><strong>You tested it on your own phone</strong> before signing off.</li>
</ol>
<h2>How do I fix my website? A quick security and speed check</h2>
<p>When a small business site needs fixing, start with these checks. Each one takes minutes.</p>
<ol>
<li><strong>Speed.</strong> Run your home page and booking page through <a href="https://pagespeed.web.dev/">PageSpeed Insights</a> on mobile and look at the three Core Web Vitals above.</li>
<li><strong>HTTPS and security headers.</strong> Run the two commands below the list.</li>
<li><strong>Book yourself.</strong> Make a real booking and send the contact form from your phone, then check the emails arrive, for you and for the customer.</li>
<li><strong>Two-step sign-in</strong> on the builder, the domain registrar, email and the Google Business Profile.</li>
<li><strong>Updates.</strong> On WordPress, update plugins and themes and delete the ones you do not use.</li>
<li><strong>Backups you have restored once.</strong></li>
<li><strong>Customer data.</strong> Check who can read your bookings. Open your site, view the page source and search for <code>secret</code>: no secret key belongs there. If your site keeps data in Supabase, work through my <a href="https://tawfik.tv/notes/supabase-security-checklist">Supabase security checklist</a>, the same checks I run when I fix database security on live apps.</li>
</ol>
<p>The commands for step 2, from any Mac or Linux terminal, with example.com replaced by your domain:</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere"># does plain http send visitors to https?
curl -sI http://example.com | grep -i -E "^http|^location"

# which security headers does the site send?
curl -sI https://example.com | grep -i -E "strict-transport-security|content-security-policy|x-content-type-options|x-frame-options|referrer-policy"</pre>

<p>The first command should show a redirect to an <code>https://</code> address. In the second, <code>strict-transport-security</code> keeps browsers on HTTPS, and <code>content-security-policy</code> limits which scripts can run on your pages.</p>
<h2>Questions people ask</h2>
<h3>How much does a small business website cost in 2026?</h3>
<p>$17 to $29 a month on a builder if you build it yourself, most often $1,500 to $5,000 for a freelancer on a builder, and $1,000 to $20,000 from an agency, up to $50,000 for ecommerce or a custom web application.</p>
<h3>How much does a small business website cost per month?</h3>
<p>About $37 to $53 on a builder with email, a domain and booking, plus card fees. A custom site adds hosting, a database and maintenance at 15% to 20% of the build each year.</p>
<h3>Is Wix or Squarespace cheaper for a small business?</h3>
<p>For a plain site, Wix Light is $17 a month and Squarespace Basic $19, both billed yearly. With booking, Wix Core is $29 with booking included, while Squarespace Basic plus Acuity Starter is $35.</p>
<h3>What is the cheapest way to get a small business website?</h3>
<p>Wix has a free plan with Wix branding and its own web address. The cheapest plan on your own domain is Wix Light at $17 a month, billed yearly.</p>
<h3>How much does it cost to fix a website?</h3>
<p>By the hour. Clutch puts builder specialists at $25 to $49 an hour, and GoodFirms puts US and UK firms at $50 to $100.</p>
<h3>Do I need a website if I have a Google Business Profile?</h3>
<p>The profile is free and gets you found on Maps. A website is where people book, see your prices and add your loyalty card, Most local businesses need both.</p>
<p>If you need online booking, a Wallet stamp card or a site fixed for your business, see <a href="https://tawfik.tv/hire/booking-and-loyalty">booking and Wallet loyalty cards</a> or write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>What is a stablecoin? How the peg holds, the types, and why some broke</title><link>https://tawfik.tv/notes/what-is-a-stablecoin</link><guid>https://tawfik.tv/notes/what-is-a-stablecoin</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A stablecoin is a token built to stay worth one dollar: the issuer holds cash and Treasury bills behind every coin and buys coins back on demand.</description>
<content:encoded><![CDATA[<p>A stablecoin is a token on a blockchain built to stay worth a fixed amount of normal money, almost always one US dollar. The issuer holds a reserve of cash and short-dated government debt behind every coin, and buys coins back for dollars at that fixed price.</p>
<p>Two issuers hold most of the market. Tether reported about $184.6 billion of USDT in circulation on 30 June 2026, over 60% of all stablecoins, in its <a href="https://tether.io/news/tether-posts-strong-q2-performance-generates-1-5b-net-operating-profit-maintains-4-11b-reserve-buffer-and-expands-gold-holdings-to-more-than-146-tons/">Q2 2026 attestation</a> prepared by the accounting firm BDO. Circle reported $73.3 billion of USDC at the end of the same quarter in its <a href="https://www.circle.com/pressroom/circle-reports-second-quarter-2026-results">second quarter results</a>.</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I have built the customer side of this twice: dollars, stablecoins and tokenized gold in one balance, with a checkpoint in front of every move. This is the plain version: what it is, what holds it at a dollar, and what breaks it.</p>
<h2>What is a stablecoin?</h2>
<p>Think of it as a digital dollar bill that a company prints and promises to buy back. You send the issuer $100 by bank transfer, it creates 100 coins in your wallet, and they move like any other token: wallet to wallet, at any hour, across borders, in minutes. When you want dollars back, you send the coins to the issuer, it destroys them and wires you $100.</p>
<p>Creating coins is minting, handing them back is redeeming. In between, the issuer&rsquo;s whole job is keeping enough safe assets to buy every coin back.</p>
<p>It is not a bank deposit: it is not insured, and under US law it is unlawful to say it is. And unlike bitcoin, whose price floats, it is built so that its price does not move.</p>
<pre style="margin:0 0 24px;padding:14px 16px;background:#15171b;border:1px solid #262a31;border-radius:10px;font:400 13.5px/1.6 'Geist Mono',ui-monospace,Menlo,monospace;color:#f4f5f7;white-space:pre-wrap;overflow-wrap:anywhere">mint(x):    customer pays $x in      reserve + x    coins + x
redeem(x):  customer hands x back    coins - x      reserve pays $x out
the peg holds while:  reserve you can reach today  >=  coins out</pre>

<h2>How does a stablecoin keep its $1 peg?</h2>
<p>Two things hold it: a reserve that covers every coin, and a redemption door that stays open.</p>
<ul>
<li><strong>The reserve.</strong> For every coin out, the issuer holds at least a dollar of safe assets that sell quickly: cash at banks, Treasury bills that mature within weeks, overnight repo and government money market funds.</li>
<li><strong>Redemption.</strong> If a coin trades at 99.7 cents, a trader who can redeem buys it and hands it to the issuer for a full dollar. At $1.003, they mint at a dollar and sell. Both trades push the price back to $1.</li>
<li><strong>Proof.</strong> The issuer publishes the reserve every month and an accounting firm checks the report, so holders know the door will open tomorrow.</li>
</ul>
<p>The weak spot is the word &ldquo;reach&rdquo;. A reserve stuck in a failed bank, or in assets that only sell at a loss, pays nobody back that week. That is when a coin slips below a dollar.</p>
<p>Try it on a sample issuer&rsquo;s monthly reserve report: mint, redeem, start a run, fail a reserve bank, and switch the backing to see which designs hold.</p>
<p><a href="https://tawfik.tv/notes/what-is-a-stablecoin">Open the interactive diagram on tawfik.tv</a></p>

<h2>What are the types of stablecoins?</h2>
<p>Three designs, sorted by what sits behind the coin.</p>
<ol>
<li><strong>Fiat-backed.</strong> Cash, bank deposits and Treasury bills, held by a company. USDC works this way, and Tether says the majority of USDT&rsquo;s reserve is in US government-backed instruments. It is the only design the US law accepts for a payment stablecoin.</li>
<li><strong>Crypto-backed.</strong> Software holds other crypto, such as ether, as collateral, more than a dollar of it per coin because its price swings. When cover gets thin, the software sells collateral to buy back and burn coins. It survives slow falls, not falls faster than those sales.</li>
<li><strong>Algorithmic.</strong> No outside reserve. The coin is held at a dollar by a promise to swap it for a dollar&rsquo;s worth of a sister token from the same issuer, printed on demand. It works while people want the sister token.</li>
</ol>
<h2>Why did algorithmic stablecoins fail?</h2>
<p>Because the only thing behind the coin was another token from the same people, and it loses value in the same panic.</p>
<p>TerraUSD (UST) is the case everyone points to. Per the US Attorney&rsquo;s Office in New York, Terraform&rsquo;s <a href="https://www.justice.gov/usao-sdny/pr/crypto-enabled-fraudster-sentenced-orchestrating-40-billion-fraud">promotional materials claimed</a> that one UST could always be exchanged for $1 worth of LUNA, its sister token. UST had already fallen below 92 cents in May 2021, and the peg came back only after a trading firm secretly bought millions of dollars of UST to prop it up. In May 2022 the peg broke again, UST and LUNA crashed, and investors lost over $40 billion. The <a href="https://www.sec.gov/newsroom/press-releases/2023-32">SEC said</a> the price of UST and its sister tokens &ldquo;plummeted to close to zero&rdquo;. Terraform&rsquo;s founder, Do Kwon, was sentenced to 15 years in prison on 11 December 2025.</p>
<p>Switch the report above to algorithmic and start a run to see why: every coin handed back prints sister tokens, they get sold, the sister price falls, and the next coin needs even more of them.</p>
<p>Section 14 of the <a href="https://www.govinfo.gov/content/pkg/PLAW-119publ27/html/PLAW-119publ27.htm">GENIUS Act</a> orders a Treasury study of exactly this design, which it calls &ldquo;endogenously collateralized&rdquo;.</p>
<h2>Who issues the biggest stablecoins?</h2>
<p>Tether issues USDT, the largest, and reported reserves exceeding liabilities by about $4.11 billion at 30 June 2026. Circle, listed on the New York Stock Exchange, issues USDC. Both earn the interest on the reserve, and holders get none of it.</p>
<h2>What does the GENIUS Act require of a stablecoin issuer?</h2>
<p>The US <a href="https://www.govinfo.gov/content/pkg/PLAW-119publ27/html/PLAW-119publ27.htm">GENIUS Act</a>, signed on 18 July 2025, sets the rules for a &ldquo;payment stablecoin&rdquo;. What it means for a holder:</p>
<ul>
<li><strong>One for one reserves</strong> from a short list: cash, insured bank deposits, Treasury bills with 93 days or less to run, overnight repo and government money market funds. Reserves cannot be pledged or lent out, except in narrow cases.</li>
<li><strong>A monthly report</strong> of coins out and reserves, examined by an accounting firm.</li>
<li><strong>Timely redemption</strong> under a published policy. Only regulators can limit it.</li>
<li><strong>No interest and no deposit insurance.</strong></li>
<li><strong>Holders first in a failure.</strong> Their claims on the reserve come before everyone else&rsquo;s.</li>
<li><strong>Freeze on a lawful order.</strong> An issuer must be able to seize, freeze or burn coins when ordered, and run a full sanctions programme.</li>
</ul>
<p>It takes effect by 18 January 2027 at the latest. What it means for a bank is in <a href="https://tawfik.tv/notes/bank-stablecoin">can a bank issue its own stablecoin</a>.</p>
<h2>How does a business or a bank use a stablecoin?</h2>
<ul>
<li><strong>Paying suppliers abroad.</strong> Faster than a wire almost every time, cheaper only sometimes: <a href="https://tawfik.tv/notes/stablecoin-cross-border-payments">cross-border payments with stablecoins</a>.</li>
<li><strong>Settling between companies.</strong> On 16 December 2025 Visa <a href="https://usa.visa.com/about-visa/newsroom/press-releases.releaseId.21951.html">launched USDC settlement</a> with US banks.</li>
<li><strong>Paying out income.</strong> Rent from a tokenized property can go to each holder&rsquo;s wallet in a stablecoin, as I describe in <a href="https://tawfik.tv/notes/tokenize-real-estate">how to tokenize real estate</a>.</li>
<li><strong>Offering it to customers.</strong> A bank can let customers buy, hold and send stablecoins in its app, keep them safe, or issue its own.</li>
</ul>
<p>That last one is my work. The first build was a bank-in-a-box for a listed gold company: a white-label app where a bank&rsquo;s customers hold dollars, stablecoins and tokenized gold in one balance. Every send or purchase goes through a checkpoint of 11 ordered rules with three outcomes: allowed, held, or unavailable when a fact it needs, such as the gold price, has gone stale. I also built a cross-border payments pitch for a network that settles between member banks in seconds: an interactive page where you switch one part off and watch the payment fail. Both are in <a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">forward deployed engineer: four AI and fintech builds</a>.</p>
<p>Access to a stablecoin is easy to buy. The rules for who may send, mint or redeem, checked before the money moves and recorded, are the part you build.</p>
<h2>What are the risks of a stablecoin?</h2>
<ul>
<li><strong>Depeg.</strong> In March 2023 more than $3 billion of USDC&rsquo;s reserve cash was at Silicon Valley Bank when it failed. Circle&rsquo;s <a href="https://www.sec.gov/Archives/edgar/data/1876042/000119312525070481/d737521ds1.htm">own filing</a> says USDC saw &ldquo;a temporary price dislocation&rdquo; on some markets until the funds were released. Put the reserve bank into failure in the report above to see the same shape.</li>
<li><strong>Issuer.</strong> You are trusting a company&rsquo;s reserve, its banks and its report. Read the monthly report: what it holds, where, and who examined it.</li>
<li><strong>Sanctions.</strong> Issuers can freeze coins in a wallet. OFAC&rsquo;s <a href="https://ofac.treasury.gov/media/913571/download?inline">guidance</a> says blocked virtual currency must be frozen and reported within 10 business days. Screen who pays you: a frozen coin pays no one.</li>
</ul>
<h2>Questions people ask</h2>
<h3>Is a stablecoin a cryptocurrency?</h3>
<p>Yes, a token on a blockchain, but built not to move in price. A reserve and the issuer&rsquo;s promise to buy coins back hold it at one dollar.</p>
<h3>Are stablecoins safe?</h3>
<p>As safe as the reserve and the issuer behind them. A coin backed by cash and short Treasury bills, reported monthly, is a different thing from an algorithmic one. Neither is insured.</p>
<h3>Can a stablecoin lose its peg?</h3>
<p>Yes. USDC slipped in March 2023 while part of its reserve was stuck at a failed bank, then recovered. TerraUSD broke in May 2022 and fell close to zero.</p>
<h3>How do stablecoin issuers make money?</h3>
<p>From interest on the reserve: Circle reported $668 million of it in the second quarter of 2026. Under the GENIUS Act, holders get no interest.</p>
<h3>What is the difference between USDT and USDC?</h3>
<p>Both are reserve-backed dollar stablecoins. Tether&rsquo;s USDT is larger, about $184.6 billion in mid 2026, against $73.3 billion for Circle&rsquo;s USDC. Each publishes its own reserve reports.</p>
<p>If you need this built, write to m@tawfik.tv, or see how I work as a <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a>.</p>]]></content:encoded></item><item><title>How much does it cost to live stream an event?</title><link>https://tawfik.tv/notes/live-stream-event-cost</link><guid>https://tawfik.tv/notes/live-stream-event-cost</guid>
<pubDate>Thu, 15 Oct 2026 09:00:00 +0000</pubDate><description>A phone stream needs about $174 of kit, three cameras about $517 to hire for three days, and a crewed day adds crew from £1,780. Prices sourced.</description>
<content:encoded><![CDATA[<p>Live streaming an event costs from about $174 for a phone kit you own, to about $517 to hire a three-camera kit for three days, to a crewed production where people cost more than the kit: from about £1,780 a day for five crew in London. The platform can be free.</p>
<p>What usually breaks a stream is the venue&rsquo;s internet, not the budget. In March 2024 the FCC raised its definition of broadband to <a href="https://docs.fcc.gov/public/attachments/DOC-401205A1.pdf">100 Mbps down and 20 Mbps up</a>. YouTube recommends <a href="https://support.google.com/youtube/answer/2853702?hl=en">14 Mbps for a 1080p stream at 30 frames a second</a>, and Vimeo&rsquo;s rule of thumb is to stream at <a href="https://help.vimeo.com/hc/en-us/articles/31111615882641-Choose-a-Streaming-Quality-in-Livestream-Studio">half of your upload speed</a>. So a line that counts as broadband in the US does not leave enough headroom for that stream.</p>
<p>I&rsquo;m Mo Tawfik Khalifa. I have worked at both ends of a live broadcast: as a technical producer on live F1 race coverage, as technical and transmission manager at the PyeongChang Winter Olympics for Olympic Broadcasting Services, and as a streaming manager at Amazon, including live music streams for Amazon Music. The same rules apply to a wedding: test the line, mic the voices, record a backup, rehearse. Every price below links to its source, checked on 15 October 2026.</p>
<h2>How much does it cost to live stream an event?</h2>
<p>Three tiers. Prices are US list prices from the maker, or three-day hire prices from <a href="https://www.lensrentals.com/">Lensrentals</a>, a US rental house. Crew rates are Bectu&rsquo;s <a href="https://union.bectu.org.uk/resource/london-live-events-rates-guidance-corporate-venues-2026.html">London live events guidance for 2025/26</a>, for a 10-hour corporate day.</p>
<ol>
<li><strong>Phone and gimbal: about $174.</strong> Your phone, a <a href="https://store.dji.com/product/osmo-mobile-7">DJI Osmo Mobile 7 gimbal at $75</a> and a <a href="https://store.dji.com/product/dji-mic-mini">DJI Mic Mini kit with two transmitters at $99</a>.</li>
<li><strong>A small multi-camera kit: about $517 to hire for three days.</strong> Three <a href="https://www.lensrentals.com/rent/canon-xa60">Canon XA60 camcorders at $103 each</a>, three <a href="https://www.lensrentals.com/rent/manfrotto-502ah-video-head-mt055xpro3-aluminum-tripod-kit">video tripods at $43 each</a>, an <a href="https://www.lensrentals.com/rent/blackmagic-design-atem-mini-pro-hdmi-live-stream-switcher">ATEM Mini Pro switcher at $29</a> and a <a href="https://www.lensrentals.com/rent/dji-mic-2-wireless-microphone-2-person-system-w-lav-mics">DJI Mic 2 kit at $50</a>. To buy instead: the <a href="https://www.blackmagicdesign.com/products/atemmini">ATEM Mini Pro is $349</a> and streams to YouTube, Facebook and Twitch over Ethernet without a computer, and a <a href="https://www.blackmagicdesign.com/products/blackmagicstudiocamera">Blackmagic Studio Camera 4K Plus G2 is $1,555</a>, lens extra.</li>
<li><strong>A crewed production: kit plus people.</strong> Four cameras on hire, three camera operators, a video tech on the switcher and the stream, and a sound technician. Bectu&rsquo;s professional minimums are £360 for a camera operator and £350 each for a sound technician and a video tech, so those five crew start at £1,780 a day. For a field or a venue with no wired line, add bonded cellular: a <a href="https://videoguys.com/products/liveu-solo-pro-hdmi">LiveU Solo PRO HDMI at $1,795</a> from a US reseller, plus LiveU&rsquo;s <a href="https://www.liveu.tv/products/create/solo-pro">two-modem Connect kit at $450</a>.</li>
</ol>
<p>Build your own order below. Pick the event, cameras, sound, venue internet and audience; the kit list, the upload meter and the run of show follow.</p>
<p><a href="https://tawfik.tv/notes/live-stream-event-cost">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you live stream an event, step by step?</h2>
<ol>
<li><strong>Test the venue&rsquo;s upload speed</strong> at the same time of day as the event, from where your kit will sit. Ask for a wired port. Vimeo advises <a href="https://help.vimeo.com/hc/en-us/articles/12426939452817-Recommended-network-configuration-for-live-events">Ethernet on a dedicated, unshared network</a>.</li>
<li><strong>Pick the quality the line can carry.</strong> Set the encoder to half your measured upload or less.</li>
<li><strong>Mic the voices,</strong> not the room.</li>
<li><strong>Rehearse a real stream</strong> to a private or unlisted link and watch it on a phone on mobile data.</li>
<li><strong>Record locally</strong> on the switcher, the camera or the laptop. Vimeo says you should <a href="https://help.vimeo.com/hc/en-us/articles/12426939452817-Recommended-network-configuration-for-live-events">always record your stream locally</a>, whatever your network.</li>
<li><strong>Go live early</strong> with a holding slide, and keep one person watching the stream on headphones.</li>
</ol>
<h2>What upload speed do you need to live stream?</h2>
<p>These are YouTube&rsquo;s recommended bitrates for H.264, with the upload that leaves Vimeo&rsquo;s half for headroom:</p>
<ul>
<li><strong>720p, 30 fps:</strong> 8 Mbps recommended, 3 minimum. Upload: 16 Mbps.</li>
<li><strong>1080p, 30 fps:</strong> 14 Mbps recommended, 5 minimum. Upload: 28 Mbps.</li>
<li><strong>1080p, 60 fps:</strong> 17 Mbps recommended, 6 minimum. Upload: 34 Mbps.</li>
<li><strong>4K, 30 fps:</strong> 42 Mbps recommended, 11 minimum. Upload: 84 Mbps.</li>
</ul>
<p>If the line is slower, lower the bitrate before anything else: a steady 1080p stream at 8 Mbps on a 16 Mbps line is better than 14 Mbps that stalls. Your audience size does not change the upload you need. The platform copies your one stream to every viewer. How viewers&rsquo; players add delay is in <a href="https://tawfik.tv/notes/broadcast-workflows">why my stream is behind live TV</a> and in <a href="https://tawfik.tv/notes/low-latency-streaming">low-latency streaming</a>.</p>
<h2>What is the best platform to live stream an event?</h2>
<ul>
<li><strong>YouTube.</strong> Free. You need a <a href="https://support.google.com/youtube/answer/2474026?hl=en">verified channel with no live streaming restrictions in the past 90 days</a>, and your first stream <a href="https://support.google.com/youtube/answer/9228390?hl=en">may take up to 24 hours to enable</a>. Going live from the YouTube phone app needs <a href="https://support.google.com/youtube/answer/9228390?hl=en">at least 50 subscribers</a>. An encoder, like the ATEM or OBS on a laptop, does not.</li>
<li><strong>Restream.</strong> Sends one stream to several platforms. <a href="https://restream.io/pricing">Free for two channels with Restream branding, $19 a month for three, $49 a month for five channels in Full HD</a>, billed monthly.</li>
<li><strong>Vimeo.</strong> Live streaming needs the <a href="https://vimeo.com/upgrade">Advanced plan, $75 a month billed annually or $125 monthly</a>, with registration for up to 100 attendees, Q&amp;A and polls.</li>
</ul>
<p>For a wedding or a family service, an unlisted YouTube link is enough. For a conference with sign-ups, Vimeo. For reaching people on several platforms at once, Restream.</p>
<h2>Audio is the thing people forget</h2>
<p>A soft picture is still watchable. A voice you cannot hear is not. A camera mic at the back records the room: echo, chairs, air conditioning. Live TV treats sound as its own job. When F1 went remote it was <a href="https://corp.formula1.com/f1-steers-future-sustainable-broadcasting-with-innovative-remote-operations/">rigging 90 cameras and 147 microphones at every race</a>, more microphones than cameras.</p>
<p>For your event:</p>
<ul>
<li><strong>Wireless lapel mics</strong> on whoever speaks: the officiant, the pastor, the speaker.</li>
<li><strong>A feed from the venue&rsquo;s sound desk</strong> when there is one. Whatever reaches the PA reaches your stream. The ATEM Mini Pro has <a href="https://www.blackmagicdesign.com/products/atemmini/techspecs/W-APS-14">two 3.5 mm microphone inputs</a> for it.</li>
<li><strong>Headphones on the stream,</strong> not the room, all the way through.</li>
</ul>
<h2>Rehearsals and backups</h2>
<p>Live TV plans for the link failing. F1 <a href="https://www.the-race.com/formula-1/behind-the-scenes-most-advanced-sport-broadcast-hq-f1/">rehearses switching to its backup every Thursday before a race weekend</a>. At Channel 4, as product owner of the on-demand service, nothing shipped until every release gate passed. Scale that down:</p>
<ul>
<li>A rehearsal at the venue, with the real line, at least a day before.</li>
<li>A local recording running the whole time.</li>
<li>A second connection: a phone hotspot on a different network, or bonded cellular.</li>
<li>Charged spare batteries and a second of every cable that matters.</li>
</ul>
<h2>Do you need permission to stream music?</h2>
<p>Yes, usually. YouTube scans live streams, and when it finds third-party content <a href="https://support.google.com/youtube/answer/3367684?hl=en">a placeholder image may replace your stream</a>, then the stream can be interrupted or ended. That catches a wedding&rsquo;s first dance and a band playing covers.</p>
<ul>
<li><strong>Churches</strong> in the US can add a <a href="https://ccli.com/us/en/streaming">CCLI Streaming License</a> to the Church Copyright License: it covers songs played live by your musicians, from $84 a year for churches already licensed with CCLI, or $108 for an average church of 100 to 199 people. Backing tracks and multitracks need Streaming Plus.</li>
<li><strong>Sports:</strong> the league, club or organiser often controls the streaming rights. Get it in writing.</li>
<li><strong>Conferences:</strong> get speakers&rsquo; agreement to stream and record, and to keep the recording up afterwards.</li>
</ul>
<h2>Checklists by event</h2>
<p><strong>Weddings.</strong> Agree with the couple which parts go out live. Lapel mic on the officiant. One camera on the aisle, one on the couple. Unlisted link sent to guests the week before. Take the first dance off the stream, or expect the platform to cut it.</p>
<p><strong>Church services.</strong> Sound desk feed, not a room mic. Licence for the songs. One wide camera, one on the pulpit. The same start time every week, so people can find it. Lifeway Research found <a href="https://research.lifeway.com/2023/06/20/churchgoers-still-watch-livestream-services-at-least-occasionally/">39% of Protestant churchgoers</a> watched a livestream instead of attending in person on more than five occasions in a year (survey of September 2022).</p>
<p><strong>Conferences.</strong> The slides as a direct feed from the lectern laptop into the switcher. Sound from the venue desk. Speaker consent. A registration page if attendance matters.</p>
<p><strong>Sports.</strong> Rights first. One camera high and central for the wide view. A score on screen. Bonded cellular if there is no wired line at the ground.</p>
<p>The same drawing runs from a phone on a gimbal to a world feed: <a href="https://tawfik.tv/notes/broadcast-workflows">how live TV and streaming work</a>. Live shows built for the browser are in <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores, live shows and 3D worlds</a>.</p>
<h2>Questions people ask</h2>
<h3>How much does it cost to live stream a wedding?</h3>
<p>From about $174 in kit with your own phone: a $75 gimbal and $99 of wireless mics, streaming free to an unlisted YouTube link. A three-camera kit hires for about $517 for three days. Crew is extra.</p>
<h3>How much does it cost to live stream a church service?</h3>
<p>The same kit as any event, from about $174. US churches streaming worship songs also need a CCLI Streaming License, from $84 a year if already licensed with CCLI.</p>
<h3>How do you stream a conference live?</h3>
<p>Cameras and the lectern laptop into a switcher, sound from the venue desk, a wired line with twice your stream&rsquo;s bitrate, a local recording and a rehearsal the day before.</p>
<h3>What is the best way to live stream an event?</h3>
<p>The cheapest setup that meets three tests: you can hear every voice clearly, the venue&rsquo;s upload is twice your stream&rsquo;s bitrate, and a backup recording runs the whole time.</p>
<h3>Can I live stream an event from my phone?</h3>
<p>Yes. On YouTube, going live from the app needs at least 50 subscribers. Below that, stream from an encoder app or a laptop with a stream key.</p>
<p>If you need a live event or a live product built, write to m@tawfik.tv, or see <a href="https://tawfik.tv/hire/3d-web-experiences">what I build</a>.</p>]]></content:encoded></item><item><title>Forward deployed engineer: four AI and fintech builds, from first call to production</title><link>https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech</link><guid>https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech</guid>
<pubDate>Sat, 10 Oct 2026 09:00:00 +0000</pubDate><description>What a forward deployed engineer does, shown through four real AI and fintech builds: agent guardrails, credentials, bank money and tokenised homes.</description>
<content:encoded><![CDATA[<p>A forward deployed engineer goes to the customer, finds the problem that matters, and builds the software that fixes it inside the customer&rsquo;s own systems, all the way to production.</p>
<p>The role was invented at Palantir. It is now one of the fastest-growing jobs in tech. On Indeed, postings for it in April 2026 were roughly 729% higher than in April 2025, <a href="https://www.businessinsider.com/forward-deployed-engineer-jobs-in-demand-2026-5">according to Business Insider</a>. The reason: getting AI to work inside a real company turns out to be a deployment problem, not a model problem.</p>
<p>I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. I lead product and the teams, and I still build: I come from coding and design, and I ship with AI at every step. Here are four builds from the field. I built them, but the clients can’t be named under NDA.</p>
<h2>What is a forward deployed engineer (FDE), and what do they do?</h2>
<p>A forward deployed engineer sits between the customer and the product team. They write production code in systems they did not build, scope problems the customer cannot yet put into words, and explain trade-offs to executives who do not care about the tech stack. In practice it is five steps, in this order.</p>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<h2>1. Guardrails for AI coding agents</h2>
<p><strong>The problem.</strong> Teams wanted AI coding agents working with real access: the shell, git, cloud credentials, a company card. One bad loop can burn a budget in minutes. One confident command can wipe a folder or push over a colleague&rsquo;s work. &ldquo;Be careful&rdquo; in a prompt is not a control.</p>
<p><strong>What I built.</strong> A free, source-available guard that sits between the agent and its tools and answers one question before every action: is this allowed? Each call gets one of three answers: allow, deny, or stop and ask the person.</p>
<ul>
<li><strong>Spend caps per minute and per session.</strong> Hitting the per-minute cap pauses the agent and asks you. It does not throw the work away.</li>
<li><strong>Loop detection.</strong> An agent repeating the same failing step gets stopped.</li>
<li><strong>Command rules.</strong> Piping a script from the internet into a shell is denied outright. Deleting folders, force-pushing, touching credentials and deploying stop and ask first.</li>
<li><strong>A record you can prove.</strong> Every decision goes on a hash-chained record, so afterwards you can show exactly what the agent was and was not allowed to do.</li>
<li><strong>Local and locked.</strong> It runs on the developer&rsquo;s own machine, plugs into agents over MCP, and none of its agent-facing tools can loosen a limit.</li>
</ul>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<p><strong>Result.</strong> Published free and source-available, with a live dashboard and a one-line install. The rule I held to: the agent can never talk its way past its own limits.</p>
<h2>2. A credential passport for clinicians</h2>
<p><strong>The problem.</strong> Doctors, nurses and paramedics prove the same licences again for every new hospital, agency and shift. Every time means forms, scans and weeks of waiting while someone checks the licensing board by hand.</p>
<p><strong>What I built.</strong> A mobile app for iOS, Android and the web where a clinician&rsquo;s licences and certifications live in one encrypted vault, verified at the source.</p>
<ul>
<li><strong>Identity check</strong> built into sign-up.</li>
<li><strong>Licences verified</strong> against the issuing authority, with an alert before one expires.</li>
<li><strong>Sharing that gives away only what you choose.</strong> Tick the fields, name the one recipient, pick how long the link lives, from one hour up to 30 days or never, and revoke it any time.</li>
<li><strong>A portal</strong> for the verification company to publish new credential types, and a checkout to order new checks.</li>
<li><strong>Underneath</strong>, a governance layer that decides who can see what, and decentralised encrypted storage for the files.</li>
</ul>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<p><strong>Result.</strong> Through QA and submitted to App Store beta, with the publishing portal in the verification team&rsquo;s hands.</p>
<h2>3. Digital dollars and gold for community banks</h2>
<p><strong>The problem.</strong> U.S. community banks are watching deposits leave for stablecoins and crypto apps. Their own trade body puts the deposits at risk from yield-bearing stablecoins at $1.3 trillion. Access is easy to buy now: large exchanges already resell custody and stablecoin payments to thousands of banks. What a bank cannot buy off the shelf is the decision layer: who passed identity checks, who can send, mint or redeem, what the limits are, and a record an examiner will accept.</p>
<p><strong>What I built.</strong> Three working pieces, for three different conversations.</p>
<ul>
<li><strong>A bank-in-a-box for a listed gold company.</strong> A white-label app where a bank&rsquo;s customers hold dollars, stablecoins and tokenised gold in one balance. The demo is a money path: press send or buy gold and watch the value travel from the customer to the bank, through a checkpoint, onto the payment rails and into the ledger. The checkpoint opens or holds the money with a plain-English reason, from 11 ordered rules with three outcomes, including &ldquo;unavailable&rdquo; when a fact it needs has gone stale. The technical record sits one tap away, never in the customer&rsquo;s face.</li>
<li><strong>A partner-bank app, explained for bank people.</strong> Customers fund, invest in and track digital assets from the bank they already trust. They keep the keys to their own wallet, the bank chooses what is on the menu, and every move is checked before it happens. It ends in a three-step pilot.</li>
<li><strong>A cross-border payments pitch</strong> for a network that settles between member banks in seconds: an interactive page where you switch one part off and watch the payment fail, so the buyer sees what each piece is for.</li>
</ul>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<p><strong>Result.</strong> Each one turned a slide-deck conversation into something a bank could press. The money-path and partner-bank demos each ship with a test script that checks every claim on the page, so the numbers on screen never drift from the engine behind them.</p>
<h2>4. A street of homes, read from the blockchain</h2>
<p><strong>The problem.</strong> A client turns rented homes into tokens that back a loan. On their test network every piece existed: house, token, vault, loan, rent. Nobody outside could see how a dollar of rent moved through them, and the team could not see where the live data and the app disagreed.</p>
<p><strong>What I built.</strong> A working prototype that reads the client&rsquo;s live test network and draws every home as a plaster model on a 3D street, each one built from its own listing: storeys, floor area, garage. Hover over a house to see the real photo, or collect a month of rent and follow the coins.</p>
<ul>
<li><strong>A scroll journey</strong> from house to token to vault to loan to rent.</li>
<li><strong>Four break-it gates.</strong> Switch off the title check, the valuation, the rent feed or the holder check and see what fails.</li>
<li><strong>The client&rsquo;s own yield formula</strong> as sliders.</li>
<li><strong>Every token</strong> explained in one plain sentence.</li>
<li><strong>A ship list</strong> of fixes, each with screenshot evidence, and a check script that fails the moment the client fixes one, which is the signal to update the page.</li>
</ul>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<p><strong>Result.</strong> One page that explains the product to an investor in a minute and doubles as a bug list for the engineers.</p>
<h2>What the four builds have in common</h2>
<ul>
<li>Start with the customer&rsquo;s problem in their words, not with the product.</li>
<li>Put a check in front of every risky move: an agent command, a shared licence, a payment, a loan.</li>
<li>Give a plain-English reason for every decision, and keep the technical record one tap away.</li>
<li>Build demos the buyer can break, not slides they sit through.</li>
<li>Ship a test with every claim, so what the page says stays true.</li>
</ul>
<h2>How fast is demand for forward deployed engineers growing?</h2>
<p>Fast. Two dated numbers, from two sources:</p>
<ul>
<li><strong>More than 800%</strong> growth in forward deployed engineer job postings from the start of 2025 through September 2025, <a href="https://www.fastcompany.com/91435680/postings-for-this-ai-job-are-up-800">reported by the Financial Times and covered by Fast Company</a>.</li>
<li><strong>Roughly 729%</strong> year on year: Indeed&rsquo;s postings for the role in April 2026 against April 2025, <a href="https://www.businessinsider.com/forward-deployed-engineer-jobs-in-demand-2026-5">shared with Business Insider</a>.</li>
</ul>
<p>Both reports tie the growth to the same need: companies bought AI, and someone has to make it work inside their own systems.</p>
<h2>Forward deployed engineer vs product manager vs solutions engineer vs consultant</h2>
<p>I do two of these jobs at once: I&rsquo;m chief product officer and forward deployed engineer at Instruxi. So this is how I tell them apart from the inside.</p>
<ul>
<li><strong>Forward deployed engineer.</strong> Works inside one customer&rsquo;s systems and writes the production code that makes the product run there. Stays until it runs, then feeds what they learned back to the product team.</li>
<li><strong>Product manager.</strong> Decides what to build next and why, across every customer. The output is priorities and specs, and the engineers write the code.</li>
<li><strong>Solutions engineer.</strong> Works before the sale. Shows a buyer how the product fits, runs demos and proofs of concept, answers the technical questions, then hands over at signature.</li>
<li><strong>Consultant.</strong> Studies the problem from outside and recommends what to do. The output is a report and a plan, usually independent of any one product, and someone else builds it.</li>
<li><strong>Fractional CPO.</strong> Runs product and the product team part-time: one priority list, the team, and how it ships. That is the <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> work.</li>
</ul>
<p>The quick test: if your customers cannot get the product working in their own systems, or you need code shipped inside a client&rsquo;s stack, you need a forward deployed engineer. If you do not know what to build, a product manager. If you need a demo to win a deal, a solutions engineer. If you want an outside plan before you spend, a consultant. If nobody runs product, a fractional CPO.</p>
<p><a href="https://tawfik.tv/notes/forward-deployed-engineer-ai-fintech">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you become a forward deployed engineer?</h2>
<p>I came through three eras, and each one gave me part of the job.</p>
<ol>
<li><strong>Live broadcast systems.</strong> I started as a broadcast engineer at the BBC and Channel 4, then worked on live Formula 1 coverage, as technical and transmission manager at the Winter Olympics, as a technical manager at Sky and as a streaming manager at Amazon. Live TV teaches you to work inside systems other people built, to draw the workflow before you build it, and to ship things that cannot fail in front of an audience. More in <a href="https://tawfik.tv/notes/broadcast-workflows">how live TV and streaming work</a>.</li>
<li><strong>Immersive 3D.</strong> I turned engineering models into live Unreal and Unity environments, real-time digital twins for the FIFA World Cup in Qatar, Expo 2020 and <a href="https://tawfik.tv/projects/seven-al-hamra">SEVEN</a>. Then I led teams: technical director at Sensorium, VP production at Expo 2020 Dubai, VP delivery at Napster with 24 developers, designers and producers. That is the customer-facing half: taking a client&rsquo;s own data and making something they can walk through. More in <a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">virtual stores, live shows and 3D worlds</a>.</li>
<li><strong>AI and fintech.</strong> Blockchain work at Theta Labs and PLAYERUNKNOWN Productions, head of growth at OKX, and now Instruxi, where I ship the four builds above with AI at every step. This era adds the hardening: identity, permissions, limits and a record you can prove. More in <a href="https://tawfik.tv/notes/one-person-ai-team">can one person with AI do a whole team&rsquo;s work</a>.</li>
</ol>
<p>You do not need my route. You need what it added up to. If I were starting now, I would do it in this order:</p>
<ol>
<li><strong>Ship one real product on one stack.</strong> Something people use, that you deployed and kept running.</li>
<li><strong>Work inside systems you did not build.</strong> Integrations, legacy code, other people&rsquo;s data and permissions.</li>
<li><strong>Get close to customers.</strong> Support, delivery, implementation or solutions roles all count.</li>
<li><strong>Learn to write it down.</strong> A one-page scope with a demo date, and trade-offs in plain English for someone who does not care about the stack.</li>
<li><strong>Build with AI in the loop, and harden what you build.</strong> Fast prototypes are easy now. Production is the skill.</li>
<li><strong>Show your work.</strong> Demos people can press beat a CV line.</li>
</ol>
<h3>The skills, concretely</h3>
<ul>
<li>One backend language to production standard, Python or TypeScript, plus enough front end to put a working screen in front of a customer.</li>
<li>APIs, webhooks and sign-in: OAuth, single sign-on, API keys and how to scope them.</li>
<li>Databases and SQL, and reading a data model you did not design.</li>
<li>Deployment: containers, CI, cloud, logs and monitoring.</li>
<li>LLM work: prompts, tool calling, AI agents, MCP, and tests that catch a bad answer before a customer does.</li>
<li>Security basics: least privilege, secrets handling, audit trails.</li>
<li>Scoping: turning &ldquo;we want AI&rdquo; into one problem, one owner and one date.</li>
<li>Explaining: a trade-off in two sentences to an executive, and the same trade-off in detail to their engineers.</li>
<li>One domain deeply. For fintech that means identity checks, payment rails, ledgers and what a regulator will ask to see.</li>
</ul>
<h2>Questions people ask</h2>
<h3>What does FDE stand for?</h3>
<p>FDE stands for forward deployed engineer: an engineer who works inside the customer&rsquo;s team, on the customer&rsquo;s systems, until the product works there. It is also searched as &ldquo;forward deployment engineer&rdquo;.</p>
<h3>What is the difference between a forward deployed engineer and a solutions engineer?</h3>
<p>A solutions engineer shows how the product fits and helps sell it. A forward deployed engineer builds production software inside the customer&rsquo;s environment and stays until it runs. Many forward deployed engineers start where a solutions engineer stops.</p>
<h3>What is the difference between a forward deployed engineer and a sales engineer?</h3>
<p>A sales engineer runs demos and answers technical questions during the sale. A forward deployed engineer writes and ships the code after the contract, and often builds the prototype that wins it.</p>
<h3>What skills does a forward deployed engineer need?</h3>
<p>Writing production code in systems you did not build, scoping vague problems, explaining trade-offs to executives, and shipping fast without breaking security. In AI work, add LLM integration, AI agents and MCP, data access and permissions, and deployment.</p>
<h3>How fast can a forward deployed engineer ship a prototype?</h3>
<p>Days, with AI in the loop. The slow part is hardening: identity, permissions, limits and an audit trail. Skip it and the prototype stays a demo.</p>
<h3>What is the difference between a forward deployed engineer and a product manager?</h3>
<p>A product manager decides what to build for all customers. A forward deployed engineer builds it into one customer&rsquo;s systems and writes the code. Good forward deployed engineers feed what they learn back to the product manager.</p>
<h3>What is the difference between a forward deployed engineer and a consultant?</h3>
<p>A consultant recommends what to do and hands over a plan. A forward deployed engineer ships the working software inside your systems and stays until it runs.</p>
<h3>Is a fractional CPO the same as a forward deployed engineer?</h3>
<p>No. A fractional CPO runs product and the product team part-time across the company. A forward deployed engineer works on one customer deployment at a time. I do both kinds of work, and the <a href="https://tawfik.tv/hire/fractional-cpo">fractional CPO</a> page covers the part-time product role.</p>
<h3>How do I become a forward deployed engineer?</h3>
<p>Ship one real product, then get good at working inside systems you did not build, close to the customers who use them. Add plain writing, AI in the loop and the hardening work: identity, permissions, limits and an audit trail.</p>
<h3>Is forward deployed engineering in demand?</h3>
<p>Yes. Postings grew more than 800% from the start of 2025 through September 2025, per the Financial Times, and Indeed&rsquo;s postings for the role in April 2026 were roughly 729% above April 2025.</p>
<h3>Do you take on forward deployed work?</h3>
<p>Yes. If you have an AI or fintech problem that needs someone to sit with your team and ship it, write to m@tawfik.tv.</p>]]></content:encoded></item><item><title>How live TV and streaming work: broadcast workflows from tape to the cloud</title><link>https://tawfik.tv/notes/broadcast-workflows</link><guid>https://tawfik.tv/notes/broadcast-workflows</guid>
<pubDate>Wed, 07 Oct 2026 09:00:00 +0000</pubDate><description>How live TV and streaming work, from camera to cloud to your phone. Why streams lag the TV, and how broadcast workflows moved from tape to files to AI.</description>
<content:encoded><![CDATA[<p><img src="https://tawfik.tv/notes/broadcast-workflows/img/og.png" alt="How live TV and streaming work: broadcast workflows from tape to the cloud"></p><p>How live TV and streaming work, from camera to cloud to your phone. Why streams lag the TV, and how broadcast workflows moved from tape to files to AI.</p><p><a href="https://tawfik.tv/notes/broadcast-workflows">Read it on tawfik.tv, with the interactive explainers</a></p>]]></content:encoded></item><item><title>How to prove who someone is without seeing who they are</title><link>https://tawfik.tv/notes/prove-the-fact</link><guid>https://tawfik.tv/notes/prove-the-fact</guid>
<pubDate>Wed, 07 Oct 2026 09:00:00 +0000</pubDate><description>How I built private identity three times: a zero-knowledge player ID, a game login on Holochain, and a licence nurses share without their whole file.</description>
<content:encoded><![CDATA[<p><img src="https://tawfik.tv/notes/prove-the-fact/img/og.png" alt="How to prove who someone is without seeing who they are"></p><p>How I built private identity three times: a zero-knowledge player ID, a game login on Holochain, and a licence nurses share without their whole file.</p><p><a href="https://tawfik.tv/notes/prove-the-fact">Read it on tawfik.tv, with the interactive explainers</a></p>]]></content:encoded></item><item><title>Virtual stores, live shows and 3D worlds people actually use</title><link>https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds</link><guid>https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds</guid>
<pubDate>Wed, 07 Oct 2026 09:00:00 +0000</pubDate><description>How to build a 3D virtual store, a virtual concert and a digital twin that open in a browser, and how to get 1,000 people into one virtual event.</description>
<content:encoded><![CDATA[<p>People stopped calling it the metaverse. Brands never stopped building it.</p>
<p>I&rsquo;m Mo Tawfik Khalifa. For 20+ years I have built live systems and real-time worlds: for the BBC, Formula 1, the Winter Olympics and Expo 2020 Dubai, and in games including PUBG. Today I build virtual stores, live shows, digital twins and games that open from a link on a laptop, phone, tablet or handheld. Call it a virtual world, a 3D world or the metaverse: clients ask me the same questions. Here are my answers, with the work.</p>
<h2>How do you build a 3D virtual store?</h2>
<p>A woman on a sofa picks up a tablet. One tap on a red-brick townhouse and she is inside a Hermès store, as an avatar with her own live video above her head. A digital host in a silk scarf walks over. She turns a bag in 3D and moves in close on the leather and the clasp.</p>
<p>That was my own Hermès build, and it is the recipe for a 3D virtual store: rebuild the products in real-time 3D, set them in a world that tells the brand&rsquo;s story, open it on the screen the customer already holds, and end every room in an action.</p>
<figure><video controls playsinline preload="none" poster="https://tawfik.tv/work/hermes.jpg" src="https://tawfik.tv/work/hermes.mp4" width="848" height="432"></video><figcaption>My Hermès virtual store</figcaption></figure>

<p>At Napster I built a TAG Heuer virtual showroom. A round room under a giant watch movement opens onto a racing garage with a Porsche race car, and onto a golf course by the sea where a virtual try-on puts the sunglasses on your own face, with the product page beside them.</p>
<figure><video controls playsinline preload="none" poster="https://tawfik.tv/work/tag-heuer.jpg" src="https://tawfik.tv/work/tag-heuer.mp4" width="848" height="480"></video><figcaption>The TAG Heuer virtual showroom I built at Napster</figcaption></figure>

<p>I judge immersive retail by one number: taps through to a product page per visitor. Whatever does not move it gets cut.</p>
<ul>
<li><strong>Spend the polygons on the product.</strong> CAD files or photogrammetry, rebuilt to a polygon budget with the fine detail baked into normal maps. Nobody zooms in on a wall. They zoom in on the clasp.</li>
<li><strong>Bake the room.</strong> Baked lighting and shared materials keep draw calls and texture memory down, so the tablet spends its effort on the bag.</li>
<li><strong>Load the first room first.</strong> Draco-compressed meshes and KTX2 textures stream from a CDN while the customer looks around. Every second on a loading bar is a visitor deciding to leave.</li>
<li><strong>Build the world, buy the till.</strong> The basket stays on the brand&rsquo;s ecommerce site, one tap away. A 3D product configurator earns its place only when a choice changes the product: strap, dial, colour.</li>
</ul>
<h2>How to create a 3D virtual store, step by step</h2>
<p>These are the steps behind my Hermès virtual store and the TAG Heuer showroom I built at Napster, in the order they happen.</p>
<ol>
<li><strong>Pick the one number.</strong> For a store, mine is taps through to a product page per visitor. Every later step gets checked against it.</li>
<li><strong>Start from the screen the customer holds.</strong> The Hermès store opens on a tablet on the sofa. Name the weakest device your customers use and give it a budget for frame rate, draw calls and texture memory.</li>
<li><strong>Get the real product files.</strong> CAD files or photogrammetry, rebuilt to a polygon budget, with the fine detail baked into normal maps. The leather and the clasp of the bag get the polygons. The walls do not.</li>
<li><strong>Build a world that tells the brand&rsquo;s story.</strong> A red-brick townhouse for Hermès. For TAG Heuer, a round room under a giant watch movement that opens onto a racing garage with a Porsche race car and onto a golf course by the sea.</li>
<li><strong>Bake the rooms and load the first one first.</strong> Baked lighting, shared materials, Draco meshes and KTX2 textures streamed from a CDN, so the first room opens while the rest loads.</li>
<li><strong>Add people where they help sell.</strong> In the Hermès store, visitors are avatars with their own live video above their heads, and a digital host walks over to help.</li>
<li><strong>Add try-on where the product sits on the body.</strong> In the TAG Heuer showroom, the sunglasses go on your own face through the camera.</li>
<li><strong>End every room in an action.</strong> The product page sits beside the try-on, and the basket stays on the brand&rsquo;s own shop, one tap away.</li>
<li><strong>Test on every device, open the doors, and watch the number.</strong> Whatever does not move taps to a product page gets cut.</li>
</ol>
<h2>How is a virtual concert made?</h2>
<p>Romain Pissenem asked me to come and meet him at his office in Ushuaïa Ibiza. Romain directs High Scream, the show design studio behind the Ushuaïa and Hï Ibiza stages and David Guetta&rsquo;s shows. High Scream designed PRISM, the virtual club world inside Sensorium Galaxy. Romain brought me in to run the technical production and workflow of PRISM: the builds, the team, the shows and the tech.</p>
<p>On the Ushuaïa main stage, the LED walls showed test grids, each zone named: DJ BOOTH, DJ BACK 2, L TOP, R TOP.</p>
<figure class="tall"><img src="https://tawfik.tv/notes/media/ushuaia-stage-mapping.jpg" alt="Mapping the LED walls on the Ushuaïa main stage" loading="lazy" width="768" height="1024"><figcaption>Mapping the LED walls on the Ushuaïa main stage</figcaption></figure>

<p>Those grids are the answer. A real stage is mapped panel by panel, so every cue lands where the designer meant it. A virtual concert, or metaverse concert if you still use the word, needs the same map, cue list and rehearsals. Only the stage is built in Unreal Engine instead of steel. Unreal reads DMX, the signal a real lighting desk sends, so the lighting designer programmes the virtual show from the desk they already use.</p>
<figure class="tall"><img src="https://tawfik.tv/notes/media/ushuaia-stage-build-night.jpg" alt="The Ushuaïa stage going up at night" loading="lazy" width="768" height="1024"><figcaption>The Ushuaïa stage going up at night</figcaption></figure>

<p>With High Scream, I made the DJ booth concept for David Guetta&rsquo;s show in PRISM.</p>
<figure><img src="https://tawfik.tv/notes/media/guetta-booth.jpg" alt="The DJ booth concept for David Guetta’s show in PRISM, with High Scream" loading="lazy" width="1400" height="666"><figcaption>The DJ booth concept for David Guetta’s show in PRISM, with High Scream</figcaption></figure>

<p>Running a virtual show means running 4 things at once:</p>
<ul>
<li><strong>Builds.</strong> Club, booth and effects in Unreal Engine, with a build for each device.</li>
<li><strong>Team.</strong> One plan for design, engineering and show people, one name on each part.</li>
<li><strong>Shows.</strong> Lights and visuals on timecode, rehearsed like a real show.</li>
<li><strong>Tech.</strong> A budget per device for frame rate, draw calls and texture memory. Dropped frames in a headset make people feel sick, so the headset budget wins every argument.</li>
</ul>
<p><a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">Open the interactive diagram on tawfik.tv</a></p>

<p>Carl Cox&rsquo;s show, Intermundium, premiered in PRISM as a free 30-minute set. His avatar was built with <a href="https://www.uploadvr.com/discover-sensorium-galaxys-carl-cox-intermundium-show/">photogrammetry and motion capture</a>, and the show ran in Unreal Engine, in VR on Steam and as <a href="https://mixmagnl.com/read/carl-coxs-digital-debut-in-sensorium-galaxy-">2D streams from YouTube to TikTok Live</a>. <a href="https://mixmag.net/read/watch-carl-coxs-virtual-reality-set-with-sensorium-galaxy-news">Mixmag reported</a> over 1 million viewers in the opening weekend, and the <a href="https://www.youtube.com/watch?v=YlTBRkurWAE">full show on YouTube</a> has since passed 10 million views.</p>
<figure><a href="https://www.youtube.com/watch?v=CukrZYWtT0A"><img src="https://tawfik.tv/work/carlcox-bts.jpg" alt="Play the behind-the-scenes film" width="960" height="540"></a><figcaption>Behind the scenes: making Carl Cox’s avatar for Sensorium Galaxy. Video: Sensorium.</figcaption></figure>

<p>Carl Cox&rsquo;s show was a successful test. David Guetta&rsquo;s show is next, date to be confirmed.</p>
<h2>How do virtual concerts work?</h2>
<p>A virtual concert is a live show played inside a real-time 3D world. The artist is captured and turned into an avatar, the venue is built in a game engine, the show runs from one cue list, and the audience arrives at the same moment from headsets, phones, browsers and video streams. Carl Cox&rsquo;s show above is a worked example.</p>
<p>To make a virtual concert, you go through 6 steps. In PRISM, the first 2 belonged to the artist&rsquo;s team and Sensorium&rsquo;s motion capture studio. I ran the technical production from the build onward.</p>
<ol>
<li><strong>Capture.</strong> Cameras photograph the artist from every side (photogrammetry), and a marker suit records how they move (motion capture).</li>
<li><strong>Avatar.</strong> 3D artists clean up the scan, rig it to the captured motion and cut it to a budget each device can draw.</li>
<li><strong>World build.</strong> The venue, stage, screens and crowd are built in a game engine, one build per device. PRISM was built in Unreal Engine.</li>
<li><strong>Show control.</strong> Lights, visuals and effects are cued to the music on one timeline. Unreal&rsquo;s <a href="https://dev.epicgames.com/documentation/en-us/unreal-engine/dmx-in-unreal-engine">DMX plugin</a> lets the lighting designer run the virtual rig from a real desk.</li>
<li><strong>Streaming to thousands.</strong> The audience is split into rooms of 50 to 100, all locked to one show timeline, with a video stream for everyone else. The next section explains why.</li>
<li><strong>Chat and interaction.</strong> Chat, emotes and nearby voice inside each room, and shared moments fired to every room at once from the show timeline.</li>
</ol>
<p><a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">Open the interactive diagram on tawfik.tv</a></p>

<h2>How do you get 1,000 people into one virtual experience?</h2>
<p>You don&rsquo;t put them in one room. With 1,000 avatars in one space, every device draws 999 others and the server sends about 1 million position updates every tick. No phone survives that, which is why a <a href="https://dev.epicgames.com/documentation/en-us/unreal-engine/replication-graph-in-unreal-engine">Fortnite match holds 100 players</a> and Travis Scott&rsquo;s Fortnite concert drew <a href="https://www.pcgamesn.com/fortnite/concurrent-player-record">over 12.3 million players at once</a> in <a href="https://matthewball.co/all/fortnitetravisscott">copies capped at 50</a>.</p>
<p>So I build one show and many rooms:</p>
<ul>
<li><strong>Shard.</strong> Rooms of 50 to 100, locked to one show timeline, so every room hits the drop together.</li>
<li><strong>Cull.</strong> Interest management syncs only the people near you. The server (Photon, Nakama or Unreal dedicated servers) holds the truth.</li>
<li><strong>Instance.</strong> Distant avatars share one low-detail mesh, drawn with GPU instancing. Voice only carries nearby.</li>
<li><strong>Overflow.</strong> Past capacity, or on a weak device, you get the live stream.</li>
<li><strong>Load-test.</strong> Bots fill every room before the doors open.</li>
</ul>
<p>On the night I watch who is still there for the last track. Peak concurrency makes the press release. Retention says the show worked.</p>
<h2>Do you need a virtual event platform or a custom build?</h2>
<p>If your event is mostly talks on video, a ready-made virtual event platform will do the job. A custom build earns its place when the venue itself is the point: my team of 12 worked on <a href="https://virtualexpodubai.com">Virtual Expo Dubai</a>, the whole Expo site in real-time 3D, and DMCC&rsquo;s Crypto Centre, launched with Napster, opens from a link in a desktop browser with nothing to install. Whichever you choose, ask three questions before you sign: does it open from a link on a phone, how does it split a big audience into rooms on one show timeline, and what happens past capacity? My answer for 1,000 people is above: rooms of 50 to 100 locked to one timeline, with a live stream for the overflow.</p>
<h2>What is a digital twin of an event?</h2>
<p>Months before the gates of Expo 2020 Dubai opened, the master plan model stood next to a tablet running the interactive plan. You could already find your way round pavilions that did not exist yet.</p>
<figure class="tall"><img src="https://tawfik.tv/notes/media/expo2020-masterplan-model.jpg" alt="The Expo 2020 master plan model next to the interactive plan on a tablet, before the gates opened" loading="lazy" width="1200" height="1600"><figcaption>The Expo 2020 master plan model next to the interactive plan on a tablet, before the gates opened</figcaption></figure>

<p>That is a digital twin: a real-time 3D copy of a venue that people can visit before the doors open and after they close. At Expo, my team of 12 worked on <a href="https://virtualexpodubai.com">Virtual Expo Dubai</a>, the whole Expo site in real-time 3D. The Expo closed. The twin is still live. If you want digital twin examples, start there.</p>
<p>A twin earns its keep 3 times. Before opening, it sells the place to sponsors. During the live event, it lets people who cannot travel walk in. After closing, it keeps the doors open.</p>
<h2>Do people need a VR headset?</h2>
<p>No. Open a laptop, click a link, and you are in the lobby of DMCC&rsquo;s Crypto Centre, looking out over Dubai. Walk into a boardroom where avatars meet, or join the treasure hunt. Nothing to install: it runs on WebGL in a desktop browser. DMCC launched it with Napster, where I led a 24-person team.</p>
<figure><video controls playsinline preload="none" poster="https://tawfik.tv/work/dmcc.jpg" src="https://tawfik.tv/work/dmcc.mp4" width="848" height="480"></video><figcaption>The DMCC Crypto Centre in a desktop browser, with Napster</figcaption></figure>

<p>The big audiences point the same way. Carl Cox&rsquo;s show was built for VR, and its biggest numbers came on YouTube. Bruno Mars drew <a href="https://www.musicbusinessworldwide.com/bruno-mars-pulls-record-12-8m-concurrent-users-to-roblox-concert/">over 12.8 million players at once</a> to a concert on Roblox. Meta is taking Horizon Worlds <a href="https://roadtovr.com/meta-horizon-worlds-goes-mobile-quest-support-cancelled/">almost exclusively to mobile</a>.</p>
<p>Every step up in fidelity costs reach, so I pick the engine by where the audience already is:</p>
<ul>
<li><strong>WebGL (three.js):</strong> an interactive 3D website that opens from a link on almost any device. Most reach, tightest budget.</li>
<li><strong>Unity:</strong> apps on phones and handhelds, with more headroom.</li>
<li><strong>Unreal Engine:</strong> the best visuals, downloaded or streamed as video through Pixel Streaming, which reaches any phone but rents a cloud GPU for every viewer, about $0.53 an hour each on AWS.</li>
</ul>
<h2>What should you bring if you want one built?</h2>
<p>Bring 5 things.</p>
<ol>
<li><strong>The goal and its one number.</strong> Sales, appointments, minutes inside, people still there at the end. Pick one, and every build decision gets checked against it.</li>
<li><strong>Who it is for, on which devices.</strong> If your customers live on their phones, the phone is the spec.</li>
<li><strong>The assets you have.</strong> CAD and 3D files, packshots, brand guidelines, footage, floor plans. Every real file is one I don&rsquo;t rebuild by eye.</li>
<li><strong>The moment it has to work live.</strong> A premiere, a store opening, a product drop. I plan back from that minute, the way live TV plans back from air.</li>
<li><strong>Who signs off.</strong> Everyone will have a view. One person owns the yes.</li>
</ol>
<p>From those 5, I write the brief back to you on one page: the number, the devices, the performance budget for the weakest device, what we build, what we buy (multiplayer, voice, checkout) and what we cut. That page sets the cost and the timeline.</p>
<h2>How much does a 3D website or product configurator cost?</h2>
<p>On published price lists, a 3D product showcase starts at about $2,000, a product configurator at about $25,000, and a custom 3D store you walk through reaches $200,000 and more. The 3D models of your products usually come on top.</p>
<p>These are market ranges from agency and vendor pricing pages, checked in October 2026. They are not my prices.</p>
<ul>
<li><strong>3D product viewer or tap-through showcase:</strong> <a href="https://www.glamar.io/pricing/virtual-store">$2,000 to $5,000, built in 3 to 4 weeks</a> from a template (GlamAR).</li>
<li><strong>Product configurator with variants:</strong> <a href="https://program-ace.com/blog/product-configurator-cost/">from $25,000 up to $150,000</a> (Program-Ace). Twikit tells small and mid-size businesses to <a href="https://twikit.com/what-does-it-cost-to-add-a-3d-product-configurator-to-your-webshop/">budget $25,000 to $75,000</a>, and Kolonell quotes <a href="https://kolonell.com/en/blog/3d-product-configurator-b2b-website-cost-2026">25,000 to 80,000 EUR over 3 to 5 months</a>.</li>
<li><strong>3D virtual store or virtual showroom:</strong> <a href="https://www.glamar.io/pricing/virtual-store">$5,000 to $25,000 from a template in 4 to 8 weeks</a> (GlamAR), or <a href="https://zolak.tech/blog/cost-to-build-a-virtual-showroom-for-furniture">$50,000 to $200,000+ built custom</a> (Zolak).</li>
<li><strong>Multiplayer world or live event:</strong> <a href="https://300mind.studio/blog/metaverse-game-development-cost/">$100,000 to $1 million</a> for simulation and sandbox metaverse projects (300Mind, 2023).</li>
<li><strong>Each 3D product model:</strong> <a href="https://talo.com/costs/3d-modeling-price">$200 to $1,000, or $150 to $500 each from 10 products up</a> (Talo), and <a href="https://twikit.com/what-does-it-cost-to-add-a-3d-product-configurator-to-your-webshop/">$500 to $5,000+ per variant</a> at configurator quality (Twikit).</li>
<li><strong>AR try-on:</strong> <a href="https://www.raftlabs.com/blog/ar-vr-app-development-guide">$20,000 to $60,000 and 8 to 12 weeks</a> as one feature added to an app (RaftLabs), or <a href="https://www.zakeke.com/pricing/">from $40 a month</a> as an add-on to a rented configurator (Zakeke).</li>
<li><strong>Checkout and shop integration:</strong> <a href="https://twikit.com/what-does-it-cost-to-add-a-3d-product-configurator-to-your-webshop/">$15,000 to $50,000</a> for a standard implementation (Twikit).</li>
</ul>
<p>Three things drive every one of those numbers:</p>
<ol>
<li><strong>Asset creation.</strong> How many products, and how close people look. A product people zoom into costs more to model than one seen across a room.</li>
<li><strong>Optimising for phones.</strong> Polygon budgets, baked lighting, compressed textures and testing on the weakest device. It has no price of its own in these lists. It sits inside the build line and is a big reason that line is wide.</li>
<li><strong>Integration.</strong> Basket, prices, stock, a CMS your team edits, analytics. Twikit warns hidden costs can <a href="https://twikit.com/what-does-it-cost-to-add-a-3d-product-configurator-to-your-webshop/">add 30 to 50%</a> to a first estimate.</li>
</ol>
<p>Pick a scope below and the range rebuilds from those sources, line by line.</p>
<p><a href="https://tawfik.tv/notes/virtual-stores-live-shows-3d-worlds">Open the interactive diagram on tawfik.tv</a></p>

<p>If you want a range for your own products, see <a href="https://tawfik.tv/hire/3d-web-experiences">how I take on 3D web projects</a>.</p>
<h2>So what happened to the metaverse?</h2>
<p>Only the word went away. People never stopped shopping from the sofa, dancing in clubs that do not exist or visiting venues before they open. Those worlds now live in browsers, on phones and on handhelds, with the headset as one screen among many. Your audience does not need new hardware. They need a link worth opening.</p>
<p>Live TV taught me to make things work on the night, the first time. A virtual store, a live show and a game ask for exactly that.</p>
<h2>Frequently asked questions</h2>
<h3>Unreal or Unity?</h3>
<p>Unreal when visuals come first. Unity for apps on phones and handhelds. WebGL when it has to open from a link.</p>
<h3>Can Unreal Engine run in a browser?</h3>
<p>Yes, through Pixel Streaming: it renders on a cloud GPU and streams video to the browser. When each viewer controls their own session, each needs their own instance, so <a href="https://learn.microsoft.com/en-us/gaming/azure/reference-architectures/unreal-pixel-streaming-in-azure">cost grows with every viewer</a>. It gets expensive fast: one streaming GPU server on AWS costs <a href="https://instances.vantage.sh/aws/ec2/g4dn.xlarge">about $0.53 an hour</a>, so 1,000 people exploring at once is roughly $526 an hour in GPUs alone, before bandwidth and the spare servers you keep warm for the rush. A WebGL build costs one download per visitor instead, so I only stream when the visuals are worth the bill.</p>
<h3>How much does a virtual store or virtual event cost?</h3>
<p>It depends on 4 things: how many products are rebuilt in 3D, how real they must look, how many people join at once, and whether it runs live once or stays open. The same 4 set how long it takes.</p>
<h3>How much does a 3D website cost?</h3>
<p>On published price lists, from about $2,000 for a 3D product showcase built from a template to $200,000 and more for a custom 3D store, before the 3D models of your products. The calculator above shows which choices move the number.</p>
<h3>How much does a 3D product configurator cost?</h3>
<p>Public ranges run from about $25,000 to $150,000 to build, plus $150 to $5,000 or more for each product model, depending on how close people look. Renting one from a platform such as <a href="https://www.zakeke.com/pricing/">Zakeke</a> starts at $59 a month for 10 products.</p>
<h3>How long does it take to build a 3D virtual store?</h3>
<p>Published timelines run from 4 to 8 weeks for a store built from a template to 3 to 5 months for a configurator with pricing and shop integration. Modelling the products runs alongside, at 3 to 10 days per model for one modeller.</p>
<h3>How do you make a virtual concert?</h3>
<p>Capture the artist, build the avatar and the venue in a game engine, run the show from one cue list, then split the audience into rooms locked to one timeline, with a video stream for everyone else. The 6 steps are above.</p>
<h3>Can a virtual concert run in a browser?</h3>
<p>Yes. A WebGL build opens from a link on almost any device. Unreal Engine can stream to a browser through Pixel Streaming, at about $0.53 an hour in cloud GPUs for every viewer. Carl Cox&rsquo;s show reached its biggest audience on YouTube.</p>
<h3>Is a digital twin the same as a 3D virtual tour?</h3>
<p>No. A virtual tour is photos you click through. A digital twin is a real-time 3D model you can walk through and run live.</p>
<h3>Can customers try products on?</h3>
<p>Yes. Glasses and sunglasses can be tried on through the camera, as in the TAG Heuer build.</p>
<p>If you want a virtual store, a live experience or a game built, email <a href="mailto:m@tawfik.tv">m@tawfik.tv</a>.</p>]]></content:encoded></item><item><title>Can one person with AI do a whole team’s work? What live systems taught me</title><link>https://tawfik.tv/notes/one-person-ai-team</link><guid>https://tawfik.tv/notes/one-person-ai-team</guid>
<pubDate>Tue, 06 Oct 2026 09:00:00 +0000</pubDate><description>Can one person with AI do a whole team’s work? What 20 years of live systems taught me, and what happened when I built and shipped an app alone with AI.</description>
<content:encoded><![CDATA[<p>One person with AI can now build and ship a product that real people use. One person cannot do a whole team&rsquo;s work. I&rsquo;m Mo Tawfik Khalifa, chief product officer and forward deployed engineer at Instruxi. For 20+ years I have built live systems, starting at the BBC, then Formula 1, Sky, the Winter Olympics, real-time worlds for the FIFA World Cup and Expo 2020, games including PUBG, then Napster and OKX. Recently I built <a href="https://laqtaa.app">Laqtaa</a>, a shared wedding photo app, on my own, and used Claude to test my code and my thesis. AI replaced the typing. It did not replace the team.</p>
<h2>Can one person build a real app with AI?</h2>
<p>Yes. I built Laqtaa on my own for a friend&rsquo;s wedding. About 100 guests used it on the day and nothing broke.</p>
<p>The problem: people pay the equivalent of about $1,000 for a wedding photographer, the pictures rarely get shared, and they end up forgotten. Guests&rsquo; own phone photos scatter across chats.</p>
<p>The solution: guests scan one QR code and every photo lands in one shared live album. No app to install. 10 languages, including Arabic. It is live at <a href="https://laqtaa.app">laqtaa.app</a>.</p>
<figure><img src="https://tawfik.tv/work/laqtaa.jpg" alt="Laqtaa, the shared wedding album: one QR code, every guest's photos in one place" loading="lazy"><figcaption>Laqtaa, the shared wedding album: one QR code, every guest's photos in one place</figcaption></figure>
<p>Before any code I wrote a 780-line brief with a hard deadline days before the wedding. On the first day, 6 milestones were built and deployed in 53 minutes. A couple of hours later the next commit read &ldquo;resolve all critical runtime bugs&rdquo;. Fast, then humbling.</p>
<p>Over 5 weeks that became 188 commits: 93 fixes and 69 features.</p>
<h2>How much does an app like this cost to run?</h2>
<p>Laqtaa costs about $46 a month to run, against the roughly $1,000 people pay for one wedding photographer.</p>
<p>That is $20 for a Vercel Pro plan, $25 for a Supabase Pro database and about $1 for the domain, and the two plans also carry my other projects.</p>
<h2>Did Laqtaa make money?</h2>
<p>No, and it was never meant to. It was a test of a product thesis and of market fit. I built no funnels and no go-to-market plan. It spread locally anyway, to more weddings and to friends of friends, and people still use it today. Word of mouth did that, not marketing.</p>
<h2>What breaks when you build an app with AI?</h2>
<p>When you build alone, what breaks is everything a team normally catches: scope, testing on real phones and the fallback plan.</p>
<p>Nobody said no. The brief scoped 2 languages and I shipped 10. A 3D iris animation went in and came out 10 days later. Late one night the design flipped to a new direction and back again inside half an hour. On a team, somebody would have asked why.</p>
<p>Bugs came back after QA was called done. The camera froze after a phone call. &ldquo;Download all&rdquo; crashed phones. Events were created as &ldquo;open&rdquo; while the database only showed &ldquo;live&rdquo; ones.</p>
<p>And no slate was loaded. In live TV, the &ldquo;technical problems&rdquo; slate is ready before you go on air. My brief planned 11 acceptance tests and a fallback switch. The repo ended with 1 test file and no fallback. I noticed, had no time to build it, and did not need it. That was luck. It was not a plan.</p>
<h2>Will AI replace product teams?</h2>
<p>No. AI replaced the typing. It did not replace the person who says no, testing on real phones, a fallback plan, or the person who catches the wrong name on screen.</p>
<p>At the PyeongChang Winter Olympics I worked on the transmission side of the host broadcaster&rsquo;s Olympic news channel. My sticky note from that job had lines like &ldquo;uplink from van 26 is weak, needs a stronger antenna&rdquo; and &ldquo;I need Monday off&rdquo;. Every line on it was somebody else&rsquo;s job. That is what a live system is: a room of people who each own one thing.</p>
<figure><img src="https://tawfik.tv/work/olympics-racks.jpg" alt="The equipment room at the PyeongChang Winter Olympics" loading="lazy"><figcaption>The equipment room at the PyeongChang Winter Olympics</figcaption></figure>
<p>During a World Cup football match, a slug, the caption on screen, went up with the wrong player&rsquo;s name. That is the mistake a live team exists to catch. Faster typing does not catch it. On Laqtaa there was one pair of eyes on the monitor. Mine.</p>
<h2>What does a product leader do when AI does the typing?</h2>
<p>The same job as before: decide what not to build, test on real devices, and load the fallback. When the typing is cheap, judgement is the job.</p>
<p>I have led teams across countries, on site and remote, for more than 11 years. At Napster I led a 24-person team of developers, designers and producers across Unreal, Unity and WebGL, including the DMCC Crypto Centre metaverse in Dubai, which we launched.</p>
<p>On Laqtaa I was the whole team, and the gaps showed where those people would have stood: the producer who cuts scope, the tester on real phones, the engineer who loads the slate before air.</p>
<h2>So can one person with AI do a whole team&rsquo;s work?</h2>
<p>The building, yes. I have 188 commits and about 100 wedding guests to show for it. The catching, no. That still takes other people. If you build alone, write down who would have said no, then say it to yourself. Load the slate before you go on air. And get someone else to watch for the wrong name.</p>]]></content:encoded></item></channel></rss>
