<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rhomn journal</title>
    <link>https://www.rhomn.com/blog</link>
    <description>Rhomn is a creation studio building brands, products and the AI systems that run them. Personal brands, client brands, SaaS products, AI systems.</description>
    <language>en</language>
    <lastBuildDate>Sun, 20 Sep 2026 09:23:41 GMT</lastBuildDate>
    <atom:link href="https://www.rhomn.com/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Making Montenegro's law searchable</title>
      <link>https://www.rhomn.com/blog/making-montenegros-law-searchable</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/making-montenegros-law-searchable</guid>
      <pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>Montenegro publishes every law as page images. This is how 78,308 of them were read back into text, and why the newest law is not always the one that applies.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Montenegro's Official Gazette publishes every law the country passes, and its register of 78,308 acts is complete and current. What it does not publish is text. Each act arrives as a set of page images, so the country's entire body of law can be looked at but not searched, quoted or handed to an AI.</strong></p>

<p dir="auto">The obvious workaround had already died. A private publisher, paragraf.me, carried clean consolidated text for 81 core statutes, then left the market, and its collection stopped on 31 March 2021. Building <a href="/works/pitaj" style="text-decoration:underline">Pitaj</a>, an assistant that answers legal questions and quotes back the articles it relied on, on top of text more than five years stale was not an option, so the law had to be read out of the Gazette's own pictures.</p>

<p dir="auto">That turned out to be possible because of a detail the Gazette never mentions. The page images are renders of its own digital typesetting rather than scans of paper, clean enough that upscaled three times and run through Tesseract's Croatian model they come back with the diacritics intact and under two percent error on modern issues. The difficult part was the Gazette itself, which answers heavy traffic with HTTP 403, so the pipeline caches every page it has read, backs off instead of skipping, and publishes any act with a missing page flagged as incomplete rather than quietly broken.</p>

<p dir="auto">Montenegro's 2026 VAT law raises the registration threshold to 30,000 euros, but it only applies from EU accession, so the 18,000 euro threshold in the older law is the one that applies today, and an assistant that trusted the most recent document would hand small businesses the wrong number. Every article in the vault therefore carries flags for whether it is actually in force, whether its text is the 2021 consolidated version or the current Gazette as published, and whether it has been repealed, and repealed articles never reach the assistant at all.</p>

<p dir="auto">Each article is its own note, filed into one of thirteen categories and cross-linked to the laws it cites, so a person browsing <a href="/works/montenegro-legal-vault" style="text-decoration:underline">the vault</a> and the assistant answering a question are reading exactly the same words. As of 19 September 2026 about half the register, 38,696 acts, has full text, and the ingestion is still working through the long tail of municipal decisions.</p>]]></content:encoded>
    </item>
    <item>
      <title>The client who rejected the AI film</title>
      <link>https://www.rhomn.com/blog/the-client-who-rejected-the-ai-film</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/the-client-who-rejected-the-ai-film</guid>
      <pubDate>Sat, 12 Sep 2026 00:00:00 GMT</pubDate>
      <category>Craft</category>
      <description>A rendered 4K film lost to phone footage shot on the trail, because the product was a rough ride and rendering smooths exactly the thing being sold.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Quadomania runs off-road quad tours in Durmitor. The film Rhomn made for them was a rendered 4K piece built to drive a site that plays as the visitor scrolls, which was the format everyone reached for this year and, technically, the strongest thing in the deliverable.</strong></p>

<p dir="auto">They did not use it. They had phone footage from actual rides, shot on the trail by people who were on the trail, and next to the render it simply looked more like the thing customers were paying for. Mud on the lens, someone laughing off frame, the shake of a machine crossing rough ground.</p>

<p dir="auto">The rendered film had a problem that more resolution makes worse rather than better. What it was selling is a ride people book because it is rough, and rendering smooths precisely the qualities being sold. The phone footage lost on every measurable axis and won on the only one that mattered, which was whether it looked true.</p>

<p dir="auto">The scroll format was the second mistake sitting on top of the first. A film that advances as the visitor scrolls is an argument for slow and deliberate pacing, and it is the right frame for a watch, a building or a perfume. A tour whose product is being thrown around a mountain does not want a controlled reveal, it wants the thing itself, at the speed it actually happens.</p>

<p dir="auto">The trend was real and the craft was real, and neither was the right answer here. The client was right, and the reason they were right carries past this one job: the format has to agree with what the thing actually is, and <a href="/services" style="text-decoration:underline">AI rendering</a> is extremely good at making anything look expensive, which is a different quality from making it look true, and not always the one being sold.</p>]]></content:encoded>
    </item>
    <item>
      <title>Scores nobody calibrated are not judgements</title>
      <link>https://www.rhomn.com/blog/scores-nobody-calibrated-are-not-judgements</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/scores-nobody-calibrated-are-not-judgements</guid>
      <pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate>
      <category>Labs</category>
      <description>Every saved post gets a score, a verdict and a next step. None of it has been tested against real saved content, and the tool says so on its own screen.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Saved posts are where good ideas go to die. Dozens accumulate every week with the intention of coming back to them, and nothing distinguishes the one worth ten minutes from the one saved on autopilot without rewatching every single one.</strong></p>

<p dir="auto"><a href="/works/reelfilter" style="text-decoration:underline">ReelFilter</a> was built to triage that. A post forwarded to yourself gets downloaded, its audio transcribed, and the whole thing scored against your own context, coming back with one of three verdicts: act, read, or noise. Nothing gets buried without a reason attached, and every item carries a next step rather than just a number.</p>

<p dir="auto">That is the design. What actually exists has never run against a real saved feed, and the calibration step its own notes describe as mandatory, which is scoring thirty real items by hand and checking the model against them, was never carried out.</p>

<p dir="auto">So the interface says so. A banner across the top states that the scores are uncalibrated and should be read as a hypothesis rather than a result, and it reports how many items have been scored and how many pieces of human feedback exist, which at the moment is none.</p>

<p dir="auto">A score with no calibration behind it is a number with a confident typeface, and the difference between that and a judgement is thirty items somebody was willing to grade by hand. Printing the admission on the screen costs nothing and keeps the tool from quietly becoming the thing it was built to replace, which was an automatic filter nobody had checked.</p>]]></content:encoded>
    </item>
    <item>
      <title>One system, told four times</title>
      <link>https://www.rhomn.com/blog/one-system-told-four-times</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/one-system-told-four-times</guid>
      <pubDate>Sun, 30 Aug 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>A clinic and a garage do not want to read the same page, but they do want the same system. Four verticals, one product, one booking link.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>A patient ringing a clinic mid-procedure gets no answer and calls the next clinic. A salon client texting while the stylist has their hands full gets the same silence. Customers do not leave voicemails any more, and the business never finds out it lost them.</strong></p>

<p dir="auto">There was a second problem that had nothing to do with the product working. There was no way to show a prospective client, in the two minutes they will actually give you, what an AI answering their business looks and sounds like.</p>

<p dir="auto"><a href="/works/rhomn-systems" style="text-decoration:underline">Rhomn Systems</a> solves the second one with a live interactive builder on the page, so a visitor sees the thing running against their own kind of business rather than reading adjectives about it. The structure is the deliberate part. There are four vertical pages, for clinics, salons, trades and hotels, and they are the same system told once per audience rather than four separate products with four roadmaps. A clinic does not want to read about garages, but a clinic and a garage want the identical thing underneath, and pretending otherwise is how a small company ends up maintaining four things. Everything funnels to one booking link, and the content library is written once and adapted per trade rather than rewritten for each one menu bolted to the corner.</p>]]></content:encoded>
    </item>
    <item>
      <title>The run that was never resumed</title>
      <link>https://www.rhomn.com/blog/the-run-that-was-never-resumed</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/the-run-that-was-never-resumed</guid>
      <pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate>
      <category>Labs</category>
      <description>One hundred and seventy-five videos found, thirty-nine transcripts saved, three blocks, stopped mid-backoff. The number is the whole story, which is why it is still on the site.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Researching how a genre of build in public content talks about making and monetising software means watching hours of video, which is a bad way to spend a week. Transcripts turn that into something readable and searchable, so a script was written to list every video on a channel and pull the captions for each one into a local file.</strong></p>

<p dir="auto">It found one hundred and seventy-five videos. It saved thirty-nine transcripts. Rate limiting blocked it three times, the backoff got longer each time, and the run stopped partway through the fourth attempt and was never restarted, which means most of the catalogue was never collected at all.</p>

<p dir="auto">There is no clever recovery in this one. The blocking was ordinary, the fix would have been ordinary too, and the honest reason it stopped is that the thirty-nine transcripts answered the question that prompted the work, so the remaining hundred and thirty-six stopped being worth the argument with the rate limiter.</p>

<p dir="auto">It stays in <a href="/works/transcript-archive" style="text-decoration:underline">the archive</a> because the number is the interesting part. A tool that collected everything would say nothing except that collecting works. A tool that stopped at thirty-nine, and says so on its own page, is a more accurate picture of how this kind of work actually goes.</p>

<p dir="auto">Most portfolios quietly drop the projects that stalled, which leaves a body of work where everything shipped and everything succeeded, and that is not a record of how anything is built. The abandoned ones are evidence too, as long as the count is printed next to them.</p>]]></content:encoded>
    </item>
    <item>
      <title>verify_jwt is not authentication</title>
      <link>https://www.rhomn.com/blog/verify-jwt-is-not-authentication</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/verify-jwt-is-not-authentication</guid>
      <pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>A rule that trusted a Supabase setting found two of twelve real holes. The setting was never a security boundary, and the rewrite had to stop believing the config.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Supabase edge functions have a setting called verify_jwt, and switching it on feels like locking the door. The first version of <a href="/works/rhomn-scan" style="text-decoration:underline">Rhomn Scan</a>'s rule for unauthenticated functions believed that too, and went looking for the ones configured with the setting turned off. Run across two real codebases holding twelve genuine problems between them, it found two.</strong></p>

<p dir="auto">What the setting actually demands is a valid JWT signed by the project, and the anonymous key is exactly that. It ships inside the browser bundle, frequently hardcoded in the client source, so reading it takes about thirty seconds. Switching verify_jwt on narrows the set of people who can call a function from anyone who knows the URL to anyone who knows the URL and has opened developer tools once.</p>

<p dir="auto">The ten it missed were not subtle. One repository had no functions section in its configuration at all, so a rule keyed to that section scored zero against four functions that ran with the service role and never asked who was calling. Another held two nearly identical functions for connecting a bot, and the rule flagged one of them, for no better reason than a configuration entry existing for that one and not for its twin.</p>

<p dir="auto">The rewrite stopped treating configuration as evidence. Every function in the project is a candidate now, the check for authentication happens in the code itself and follows whatever wrapper it has been buried under, and the configuration is still read, only to word the finding rather than to decide it. A function with the setting off can be called with nothing at all, one with it on can be called with a key anybody can copy, and the report calls both of them anonymous callers, because that is what they are.</p>

<p dir="auto">Severity moved onto the finding for the same reason. An open mail relay and a function that only burns its own bandwidth were both landing as high, which left the word meaning very little. The rule now carries ninety fixture cases taken from real repositories, and forty-seven of them are there to prove it stays quiet on code that merely looks similar.</p>]]></content:encoded>
    </item>
    <item>
      <title>What a missed call actually costs a small business</title>
      <link>https://www.rhomn.com/blog/what-a-missed-call-actually-costs-a-small-business</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/what-a-missed-call-actually-costs-a-small-business</guid>
      <pubDate>Mon, 27 Jul 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>Nobody counts the calls they miss, so the number stays comfortable. The arithmetic uses two figures you already have.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Nobody counts the calls they miss, which is why the number stays comfortable. Customers do not leave voicemails any more, they call the next business on the list, and the loss arrives as an absence rather than as an event, so nothing about the day feels like it went wrong.</strong></p>

<p dir="auto">The arithmetic needs two figures that already exist. The phone keeps a log of unanswered calls, and any owner knows roughly what one job is worth, so the weekly cost is one multiplied by the other and then discounted by however many of those callers would have booked. Even at a conservative rate, a clinic or a garage that misses a handful of calls a week is usually looking at more than it expects.</p>

<p dir="auto">What that calculation leaves out is the part that compounds. A first job that never happened is also every repeat visit that would have followed it, the referral that person never made, and the review they never wrote, none of which appear in a call log and all of which were decided by a phone ringing out while somebody had their hands full.</p>

<p dir="auto">An <a href="/works/rhomn-systems" style="text-decoration:underline">AI system</a> that answers, books and follows up starts at two thousand euros, and the comparison worth making is against the weekly figure rather than against a feeling about whether automation is appropriate. For plenty of businesses the loss clears the cost inside a quarter, and for some it does not, which is a real answer rather than a sales obstacle.</p>

<p dir="auto">It also has to be built to refuse. A system that invents a price or promises a slot it cannot confirm costs far more than the missed call did, which is why the ones built here collect the details and hand a thread to a person instead of producing something plausible that a customer will hold the business to later.</p>]]></content:encoded>
    </item>
    <item>
      <title>Four inboxes and nowhere to reply</title>
      <link>https://www.rhomn.com/blog/four-inboxes-and-nowhere-to-reply</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/four-inboxes-and-nowhere-to-reply</guid>
      <pubDate>Sun, 19 Jul 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>Guest messages arrive on Booking.com, Airbnb, Expedia and direct email, with no shared surface and no usable API at this size. The mailbox turned out to be the integration.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Guest messages arrive across Booking.com, Airbnb, Expedia and direct email, each in its own format with no common place to answer, so a question about parking sits unread while staff toggle between extranets. None of those platforms offer a usable API to a property of this size, and their relays reject mail sent from any address other than the one tied to the account.</strong></p>

<p dir="auto">That constraint decides the architecture. There is no integration to build, so <a href="/works/hotel-ai" style="text-decoration:underline">the agent</a> works the mailbox the hotel already has: it watches for new guest mail and replies through the hotel's own address, which is the only way the platforms thread the response back into the right conversation.</p>

<p dir="auto">Each property is seeded with its own knowledge, tone and limits, kept separate from every other property, since a chain's phrasing and a twelve-room guesthouse's phrasing are not interchangeable and neither are their rules. The guardrails matter more than the answering does. The agent refuses to invent a price or a vacancy, and where it does not know it collects the dates and hands the thread to a person instead of producing something plausible that a guest will hold the hotel to later.</p>

<p dir="auto">There is also a dry-run mode where every reply is drafted and nothing is sent, so a property can watch it work for a week before trusting it with a real guest. Asking a hotel to let software answer its guests on day one is asking for a leap nobody sensible takes.</p>]]></content:encoded>
    </item>
    <item>
      <title>When two models watch the same tutorial</title>
      <link>https://www.rhomn.com/blog/when-two-models-watch-the-same-tutorial</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/when-two-models-watch-the-same-tutorial</guid>
      <pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate>
      <category>Labs</category>
      <description>One reading of a video is an opinion. Two independent readings, reconciled and labelled, turn disagreement into something you can measure before you watch a minute of it.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>A tutorial is one person's account of how something works, and it can be wrong, out of date, or quietly missing the step that matters. Handing it to a model does not fix that, because a single reading inherits whatever that model happened to notice. <a href="/works/brain" style="text-decoration:underline">Brain</a>, the pipeline behind Telecine, starts from the position that one reading is an opinion rather than a record.</strong></p>

<p dir="auto">Every video is therefore watched twice, by two different models working independently. One takes the video and its audio natively, the other reads sampled frames alongside the caption transcript, and neither sees the other's notes. What comes back is two accounts of the same forty minutes, and the useful part is wherever they fail to match.</p>

<p dir="auto">The two accounts are reconciled into a single specification in which every claim carries a label: confirmed by both readings, single source, conflict, or open question. One run turned thirty-eight claims into twenty-four confirmed, eight single-source, five conflicts and one open question, and the five conflicts are the only part that needs a person.</p>

<p dir="auto">The unexpected result is that the length of the reconciliation became the trust signal. A tutorial the two readings agreed on produced a thirty line document, while one they kept contradicting each other over ran to two hundred and eighty-one. Which videos to be careful with is visible from the file size before anyone watches a minute of them.</p>

<p dir="auto">What survives is a labelled specification rather than a summary, which is the difference between something to read and something to build from. A spec that comes through clean can be handed on and turned into a runnable skill, and any claim that never got a second vote stays marked as exactly that.</p>]]></content:encoded>
    </item>
    <item>
      <title>Your next customer might be an agent</title>
      <link>https://www.rhomn.com/blog/your-next-customer-might-be-an-agent</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/your-next-customer-might-be-an-agent</guid>
      <pubDate>Sun, 21 Jun 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>AI agents are starting to buy and book for people, and most sites cannot support them. Checking for metadata files misses the point, so send a real agent through instead.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>AI agents are starting to buy, book and sign up on behalf of people, and most sites cannot support it. Buttons go unlabelled, errors exist only as a red outline a model cannot read, and cart state changes in ways nothing on the page announces. The tools that claim to test for this check whether the right metadata files are present, which says nothing about whether an agent can finish the job.</strong></p>

<p dir="auto"><a href="/works/agentaudit" style="text-decoration:underline">AgentAudit</a> tests the only thing that matters, which is completion. A real agent is sent through the checkout, booking or signup flow, and what happens is scored out of a hundred. The run happens twice, once with the agent seeing nothing but the page, and once with the site's own tools exposed to it, so the gap between those two numbers is a measurement rather than an opinion about how agent friendly a site feels.</p>

<p dir="auto">Where the agent stalls, the report does not stop at naming the step. It writes the fix, checks that fix against the real page, and then runs the live journey again with the fix applied.</p>

<p dir="auto">Only a passing re-run gets stamped verified, which is the discipline most scanners skip. Anything can produce a list of suggestions, and a suggestion that has never been executed against the page it describes is a guess with formatting.</p>

<p dir="auto">The uncomfortable part for most sites is that nothing is broken in the human sense. Everything works for a person who can see, infer and guess, and the agent simply has none of those, so it exposes every place where meaning lived in a visual convention rather than in the page itself.</p>]]></content:encoded>
    </item>
    <item>
      <title>Why I wrote my taste down</title>
      <link>https://www.rhomn.com/blog/why-i-wrote-my-taste-down</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/why-i-wrote-my-taste-down</guid>
      <pubDate>Sun, 14 Jun 2026 00:00:00 GMT</pubDate>
      <category>Method</category>
      <description>Every studio has the same models now. Taste is the one thing that does not ship in an update, so I wrote mine into a file the machine reads before it starts.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Every studio I compete with uses the exact same models, weights and component libraries, and we all have the same afternoon to ship something that works. The only thing left that does not arrive in an update is taste, and taste is useless to a business if it stays trapped in one person's head. So I wrote mine down, as a document with clear rules that can actually be enforced or refused.</strong></p>

<h2 dir="auto">I came to this from painting jackets</h2>

<p dir="auto">Before any of this was software it was garments. I painted jackets and then built a clothing brand around them, and what decided whether a piece worked was never the idea, since everybody has ideas, but whether the execution earned the attention it was asking for. A jacket with a great concept and a bad hand looks like a costume, and you can feel that from across a room. A song works the same way: it is a structure you either respect or break on purpose, and breaking it only reads as intent when the rest of the record proves you knew the rule.</p>

<p dir="auto">None of that changed when the output became interfaces. What changed is that I now hand the work to a machine that has read everything and believes none of it. A model has no opinion about whether a card should be a glass slab or a flat rectangle with a one pixel border, and it will give you either for as long as you keep asking. If you do not bring the opinion yourself, you get the average of everything, which is exactly what most AI work looks like.</p>

<h2 dir="auto">What is actually in the file</h2>

<p dir="auto">The file is called DESIGN-DNA.md, and every rule in it has to serve its opening line: dark luxury glass, physical data, cinematic presentation. Under that sit eight principles marked non-negotiable. The first says beauty must carry information, so the oversized numeral is the metric and the orbit is the chart, and any ornament that cannot justify itself that way gets cut however good it looks on its own. Another asks for one hero per screen, a single saturated element on a neutral field, because when two things glow nothing glows. A third keeps real editorial photography behind the frosted layers with the technology in front of it, which is the jackets showing up inside a technical specification.</p>

<p dir="auto">The section that changes the output most is the list of what the aesthetic is not: flat cards with grey borders on white, more than one saturated gradient on a screen, pure black backgrounds, neon cyberpunk excess, sharp corners, default chart styling, emoji standing in for icons, and stock photos of people smiling at laptops. Each of those marks a specific place the average pulls you toward, which is why it has to be named. A rule like make it beautiful can never be broken, whereas never two glowing elements can, and catching yourself breaking it is the whole reason to write rules down in the first place.</p>

<h2 dir="auto">How anything new gets in</h2>

<p dir="auto">New reference material gets analysed shot by shot before anything is taken from it, and a pattern only becomes a principle once it has turned up in at least two independent sources, or when I simply love it and say so. I kept that second clause deliberately. Pretending taste is purely empirical would be its own kind of dishonesty, but writing the exception down means I can later tell a rule that earned its place from a mood I happened to be in that week.</p>

<h2 dir="auto">Why it has to be a file</h2>

<p dir="auto">The document is loadable, so an agent reads it before it writes a single line of code, which puts the constraint in front of the first decision rather than at review, when changes are expensive and I am already attached to whatever is on the screen. Most of the work is generated in the end; it simply had something to read before it started. That is the real shift: turning taste from a mood you apply when you are paying attention into a system that holds the line even on the days you are exhausted.</p>]]></content:encoded>
    </item>
    <item>
      <title>Advertising you can watch someone lose</title>
      <link>https://www.rhomn.com/blog/advertising-you-can-watch-someone-lose</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/advertising-you-can-watch-someone-lose</guid>
      <pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Being outbid is invisible, so nothing memorable comes out of it. Staging the transaction as a fight turns a database update into something people share.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Pay per click and pay per impression are invisible transactions. Nothing about being outbid is watchable, so no content comes out of it, and a business that just spent money has no visible proof that anything happened. Static featured listings are worse, because they never dramatise the moment somebody takes your place.</strong></p>

<p dir="auto"><a href="/works/bidchamp" style="text-decoration:underline">BidChamp</a> makes the transaction the show. Businesses pay to hold a ranked slot on a public board, and anyone paying more than the current holder knocks them off it in an animated bout. Nothing is random and there is no auction to lose on a technicality, since the higher payment always wins outright.</p>

<p dir="auto">What that buys is not the rank so much as the event. Losing a position becomes something worth screenshotting rather than a silent row changing in a database, and the business that took the slot has proof their money did something, which is the part every other advertising format fails to produce.</p>

<p dir="auto">Two structural decisions do most of the work. The board resets daily, so a single purchase becomes a recurring mechanic rather than a one-off, and fifteen categories mean fifteen number one slots to sell instead of one. The ladder is also measured in click counts rather than ego, so a holder can tell whether the position is actually worth what they paid.</p>

<p dir="auto">The theatre is real advertising underneath, with no chance element and no hidden reserve. It is paid placement wearing the costume of a fight night, which is the only part of the design anybody is asked to enjoy.</p>]]></content:encoded>
    </item>
    <item>
      <title>What a mobile app costs to build in Montenegro</title>
      <link>https://www.rhomn.com/blog/what-a-mobile-app-costs-to-build-in-montenegro</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/what-a-mobile-app-costs-to-build-in-montenegro</guid>
      <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
      <category>Method</category>
      <description>A product build starts at four thousand euros. The distance between the cheapest honest version and an expensive one comes down to a handful of decisions.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>A <a href="/works/kalo" style="text-decoration:underline">product build</a> starts at four thousand euros, which covers a full-stack application from the interface through to the database, a mobile-first design system, and the thing deployed, monitored and handed over. What the figure cannot tell you is which app you are buying, because the distance between the cheapest honest version and an expensive one comes down to a handful of decisions.</strong></p>

<p dir="auto">Roles are the first of them. An app where every user is identical costs a fraction of one where a customer, a contractor and an administrator each see different data under different permissions, since every role multiplies the surface that has to be designed, built and then tested against all the others. Body Heal carries three of them, and that is most of the difference between it and a single-audience app.</p>

<p dir="auto">Native or web is the second. FixMan shipped natively on Android and iOS because a home services app living on only one of them misses roughly half the people who need it, and Kalo is native iOS because a camera-first tracker succeeds or fails on the capture experience. Native means two builds, two review processes and two sets of release mechanics rather than one.</p>

<p dir="auto">Integrations are where estimates usually go wrong. Anything that has to talk to a system which already exists inherits that system's constraints, and those are never visible from the outside. Hotel AI could not use the booking platforms' APIs at all at that size, so the whole design had to move to the mailbox instead.</p>

<p dir="auto">Language is the last one, and it is underestimated most often. A second language is not a translation file bolted on at the end, it is a second set of decisions about length, tone and what a button is called, which is why Kalo carries no English fallback anywhere in its interface.</p>]]></content:encoded>
    </item>
    <item>
      <title>Thirteen agents and one human decision</title>
      <link>https://www.rhomn.com/blog/thirteen-agents-and-one-human-decision</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/thirteen-agents-and-one-human-decision</guid>
      <pubDate>Sun, 03 May 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>An outbound pipeline where the only person involved makes a single choice, placed in the middle on purpose rather than at the start or the end.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Taking a market gap through to something buildable means researching it, specifying it, designing a schema, deciding the hard parts and turning all of that into build instructions, which by hand is slow and happens one idea at a time. <a href="/works/rhomn-agency-os" style="text-decoration:underline">Rhomn Agency OS</a> compresses it into thirteen specialist agents arranged in two chains, and the only genuinely interesting decision in the whole design is where the person sits.</strong></p>

<p dir="auto">The first chain is research. One command sends six agents across real complaints people post in public, competitor feature sets, profitable clones, gaps in what already exists, and the technical reasons similar products tend to fail. Each reports into its own channel under its own name, so the output reads like a team's notes rather than one wall of text, and anything the guardrails reject lands in a channel of its own instead of quietly disappearing.</p>

<p dir="auto">What comes back is three concrete product ideas, and a person picks one. That is the entire human contribution, and it sits in the middle rather than at the beginning, where there is nothing to judge yet, or at the end, where the work is already done and the only remaining choices are shipping it or throwing it away.</p>

<p dir="auto">After the approval the second chain takes over: a product manager, an architect, a designer, an MVP builder, a prompt writer and two passes of quality checking, each handing to the next until what comes out is a set of instructions another machine can build from. Putting the approval where it is stops the thing being a machine for generating plausible products nobody asked for. Everything upstream of it is research a person can check, everything downstream is execution that is cheap to redo, and the one judgement that is expensive to get wrong is still made by someone who has to live with it.</p>]]></content:encoded>
    </item>
    <item>
      <title>Every factual sentence has to resolve to a quote</title>
      <link>https://www.rhomn.com/blog/every-factual-sentence-has-to-resolve-to-a-quote</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/every-factual-sentence-has-to-resolve-to-a-quote</guid>
      <pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate>
      <category>Systems</category>
      <description>The category leader scores niches on a rubric its own screen labels self-reported. An evidence gate is the difference between research and confident invention.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>The incumbent in this category charges three thousand dollars a year and scores niches against a rubric that its own screen labels self-reported. Nothing in it stops the tool producing a confident, uncited claim, which a paying customer then puts their name on and sells to somebody else.</strong></p>

<p dir="auto"><a href="/works/groundwork" style="text-decoration:underline">Groundwork</a> takes what a person knows and turns it into a finished digital product across nine stages, from scoring a niche through researching it across more than a hundred and fifty live sources, drafting the manuscript, and rendering it to PDF and EPUB. Its one hard rule is that every factual sentence must resolve to a verbatim quote from a cited source. Chapters carry claim identifiers that tie each factual sentence back to a ledger of source URLs, so any statement in the finished book can be traced to the thing it came from rather than to the model's confidence about it.</p>

<p dir="auto">Scoring is held to the same standard. Any dimension without real supporting evidence is forced to zero rather than filled in with something plausible, and candidates are ranked against each other so a score carries meaning instead of floating free.</p>

<p dir="auto">Forcing a zero is the part that makes the rest work, because the natural behaviour of a language model handed an empty cell is to produce a reasonable-looking number. A pipeline that cannot say it does not know will always sound better and be worth less.</p>]]></content:encoded>
    </item>
    <item>
      <title>The hotel app nobody was ever going to download</title>
      <link>https://www.rhomn.com/blog/the-hotel-app-nobody-was-ever-going-to-download</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/the-hotel-app-nobody-was-ever-going-to-download</guid>
      <pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>A twelve room property cannot ask guests to install anything. Taking the app out of the problem is what made the rest of it solvable.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Independent hotels run guest requests through a phone call to a desk that is not always manned, and a host with three apartments has no desk to call at all. Menus are laminated cards that go stale the moment a price changes, and requests get lost between shifts because nothing writes them down. The software built to fix this is priced and scoped for five star chains rather than for a twelve room property.</strong></p>

<p dir="auto">The obvious product is an app, and it is the wrong one. A guest staying four nights will not install software for it, which means every feature behind that install is theoretical, and an app store submission puts weeks between a hotel deciding to try something and the thing existing.</p>

<p dir="auto"><a href="/works/ibutler" style="text-decoration:underline">iButler</a> removes the install entirely. A QR code in the room opens the hotel's own branded ordering portal in whatever browser the guest already has, with no account to create and no download, and the menu appears in the language their phone is set to rather than the one the hotel happens to print in.</p>

<p dir="auto">Taking the app out changes what the rest of the system has to be. Going live is a matter of writing the menu once and printing the codes, which a property can do in about ten minutes without an integration project or a support call. Every request is logged and timestamped as it arrives, pushed to staff on their phones, and worked through to done, so the thing that used to get lost between two shifts now has a record.</p>

<p dir="auto">The owner ends up with something they never had, which is a live view of what guests actually ask for and when. A laminated card cannot tell anyone that the spa questions all arrive after nine at night, and a portal that logs every order can.</p>]]></content:encoded>
    </item>
    <item>
      <title>Ringing round and hoping the price holds</title>
      <link>https://www.rhomn.com/blog/ringing-round-and-hoping-the-price-holds</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/ringing-round-and-hoping-the-price-holds</guid>
      <pubDate>Sun, 22 Mar 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Booking a tradesperson means calling several, describing the job twice, and hoping the quote survives their arrival. Nothing confirms price, time and person together.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Booking a tradesperson normally means calling several, describing the same job down the phone each time, and hoping both the quote and the arrival window survive contact with reality. At no point does anything confirm the price, the time and the person together in one place, which is why the whole process runs on optimism.</strong></p>

<p dir="auto"><a href="/works/fixman" style="text-decoration:underline">FixMan</a> collapses it into one flow. A customer picks a category, drops a pin on the address instead of dictating it, chooses a slot, and ends up with a scheduled, mapped, priced booking without making a call at all.</p>

<p dir="auto">Dropping a pin is a small decision that removes a specific failure. Addresses given over the phone are how tradespeople end up on the wrong street, and in a country where a written address and where a building actually is do not always agree, a coordinate is simply better evidence than a sentence.</p>

<p dir="auto">After booking, the status is a notification rather than a wondering, and support or the contractor is reachable in the app instead of through voicemail, which is where the old version of this process quietly failed. It covers plumbing, electrical, carpentry and cleaning, and it shipped natively on both Android and iOS, because a home services app that only exists on one of them is missing roughly half of the people who need it.</p>]]></content:encoded>
    </item>
    <item>
      <title>A town of four thousand is not a small Berlin</title>
      <link>https://www.rhomn.com/blog/a-town-of-four-thousand-is-not-a-small-berlin</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/a-town-of-four-thousand-is-not-a-small-berlin</guid>
      <pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Google Maps gives a coastal town the same generic categories it gives a capital city, and answers none of the questions a visitor actually has.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Google Maps and TripAdvisor hand a town of a few thousand people the same categories they hand Berlin. There is no sense of what is genuinely open right now, no local colour, and no way to tell a konoba locals actually use from a place that exists for one season of tourists.</strong></p>

<p dir="auto">The businesses are not filling that gap either. Most have no digital presence beyond a listing nobody has edited in years, which is how a visitor ends up standing outside somewhere the internet swore was open.</p>

<p dir="auto"><a href="/works/ilokal" style="text-decoration:underline">iLokal</a> answers the question people are actually asking, which is whether somewhere is open now. Live open or closed status replaces guessing from stale hours, and curated collections such as Hidden Gems and Late Night Eats replace an undifferentiated dump of pins across a map.</p>

<p dir="auto">Ranking needed its own decision. A straight average rewards a new place with six enthusiastic reviews over somewhere with hundreds of ordinary ones, which inverts exactly the recommendation a visitor wants, so the weighting exists to stop a genuine local favourite being pushed under by arithmetic.</p>

<p dir="auto">Owners claim and edit their own listing through a merchant portal, which is the only way a directory stays true for more than a season. Anything maintained centrally rots at the speed the town changes, and a coastal town changes every May.</p>]]></content:encoded>
    </item>
    <item>
      <title>A calorie tracker that has heard of burek</title>
      <link>https://www.rhomn.com/blog/a-calorie-tracker-that-has-heard-of-burek</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/a-calorie-tracker-that-has-heard-of-burek</guid>
      <pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Every good tracker is built in English and localised later, if ever. Manual logging also dies on the first bowl of grah nobody wants to weigh.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Cal AI, MyFitnessPal and the rest are built in English and localised afterwards, if anyone gets to it. Nobody had made a tracker native to Serbian, Croatian, Bosnian or Montenegrin, even though people were searching for exactly that.</strong></p>

<p dir="auto">The second problem kills more accounts than language does. Manual logging does not survive a real meal, because nobody is going to look up gram weights for a bowl of grah, so the habit collapses within days and the app gets deleted with the blame landing on the user.</p>

<p dir="auto"><a href="/works/kalo" style="text-decoration:underline">Kalo</a> replaces the database with a photograph. The plate gets read into calories and macros, comes back as a structured breakdown in the user's own language within seconds, and stays editable before it logs, so a wrong estimate is corrected rather than argued with.</p>

<p dir="auto">The model prompt is tuned for the food people here actually eat, which an American food database has never heard of. A tracker that cannot recognise ćevapi is not slightly worse for this market, it is useless, and the interface carries no English fallback anywhere, because a single untranslated string is the moment an app stops feeling like it was made for you. The model key never touches the phone, which matters more than it sounds: shipping a key inside a mobile binary is handing it to anyone willing to unzip the app.</p>]]></content:encoded>
    </item>
    <item>
      <title>Nobody should have to hand over the skin first</title>
      <link>https://www.rhomn.com/blog/nobody-should-have-to-hand-over-the-skin-first</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/nobody-should-have-to-hand-over-the-skin-first</guid>
      <pubDate>Mon, 09 Feb 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Every existing way to trade CS2 skins costs you a fee, an escrow bot, or the ability to search by the thing that sets the price.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Every existing way to trade a CS2 skin takes something from you. The Steam market handles fixed listings only, with no negotiation and no bundles. The large third-party sites run bot escrow, so the item leaves your account before anything arrives back, and they take a cut for holding it. Reddit is a wall of manual posts with no search and no way to judge who is on the other end.</strong></p>

<p dir="auto"><a href="/works/cs2offer" style="text-decoration:underline">CS2Offer</a> matches buyers and sellers directly and never holds an item at any point. The trade itself completes inside Steam's own native window, which means neither side deposits anything with a third party, and known scammers are flagged before a conversation starts.</p>

<p dir="auto">The other half of the problem is search. Skins are priced on float, sticker wear and paint seed, and no marketplace lets people search on those, so buyers scroll hundreds of listings looking for a combination they could have filtered for in one query.</p>

<p dir="auto">Searching the exact float range and sticker combination changes what a listing is for. A seller can put up a bundle asking for one desired return instead of maintaining a dozen separate listings and doing the arithmetic themselves, and a buyer finds the specific item rather than the closest thing on the first page.</p>

<p dir="auto">Removing custody was the harder decision, because holding items is how the incumbents justify their fee. A platform that never touches the goods has to earn its place on matching and trust signals alone.</p>]]></content:encoded>
    </item>
    <item>
      <title>The people who know how you work are never asked</title>
      <link>https://www.rhomn.com/blog/the-people-who-know-how-you-work-are-never-asked</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/the-people-who-know-how-you-work-are-never-asked</guid>
      <pubDate>Sun, 18 Jan 2026 00:00:00 GMT</pubDate>
      <category>Product</category>
      <description>Performance reviews are written by managers who were not in the room. Turning the team into the evaluator produces a number a company can actually pay against.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Performance reviews are top-down, annual, and thin on signal. A manager rates people they rarely sit beside, and what comes out is a document nobody can pay a bonus against. The colleagues who actually know how somebody works are the ones next to them all year, and they are the one group never asked.</strong></p>

<p dir="auto"><a href="/works/team-feel" style="text-decoration:underline">Team Feel</a> inverts that. Organisations run structured mutual-rating sessions across departments, so the evaluation comes from the people with first-hand evidence rather than from one person's recollection of the last quarter.</p>

<p dir="auto">The output is deliberately a figure rather than a paragraph. Scores are computed on the server and turn into engagement numbers, talent signals and calculated bonuses, which moves the conversation from arguing about wording to checking a calculation. A relationship graph sits next to it so the outliers are visible instead of buried in averages.</p>

<p dir="auto">It was built multi-tenant from the first commit, with billing and referrals designed in rather than bolted on later, because retrofitting tenancy into something that assumed one company is close to a rewrite. Version two was a rebuild in five weeks that carried the same schema forward, and the honest measure of what changed is the access control surface: forty-seven policies became seventy-seven. Mutual rating means people can see things about each other, and every one of those thirty extra policies is a question about who is allowed to see what.</p>]]></content:encoded>
    </item>
    <item>
      <title>What the work costs, and what moves the number</title>
      <link>https://www.rhomn.com/blog/what-the-work-costs-and-what-moves-the-number</link>
      <guid isPermaLink="true">https://www.rhomn.com/blog/what-the-work-costs-and-what-moves-the-number</guid>
      <pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
      <category>Method</category>
      <description>Four published starting prices, a fixed price per stage, and the ability to stop after any of them. The figures matter less than the structure under them.</description>
      <content:encoded><![CDATA[<p dir="auto"><strong>Most agency pricing is a conversation designed to work out what a client can pay. The four practices here carry published starting figures instead: a brand and identity system from one thousand five hundred euros, a product build from four thousand, an AI system from two thousand, and growth and marketing at one thousand a month.</strong></p>

<p dir="auto">Those are starting points rather than quotes, and what moves them is scope rather than mood. A brand system for one founder is a different object from one that has to hold four sub-brands, packaging and a print run, and a product talking to one payment provider is not the product that has to reconcile with a back office somebody installed in 2011.</p>

<p dir="auto">The structure underneath matters more than any of the figures. Every project runs in stages, define, design, build and run, and each stage is priced before it starts rather than estimated and quietly revised halfway through. A client can stop after any of them.</p>

<p dir="auto">That last part is commercially inconvenient on purpose. Somebody who can walk away after the design stage owning everything they paid for has to be given a reason to continue, which is a healthier arrangement than one held together by a contract neither side wants to reread.</p>

<p dir="auto">You own the output at the end, files and repositories and accounts included. The four practices are priced separately but built together for the reason <a href="/services" style="text-decoration:underline">the practices page</a> states plainly: hire four specialists and you get four disconnected things, each one correct on its own terms and none of them agreeing with the others.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
