<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Sanderson</title>
    <description>The latest articles on DEV Community by James Sanderson (@jam-techcirkle).</description>
    <link>https://dev.to/jam-techcirkle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3924233%2Fda0f94b8-9b3b-46d6-8e8d-385565e5705a.webp</url>
      <title>DEV Community: James Sanderson</title>
      <link>https://dev.to/jam-techcirkle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jam-techcirkle"/>
    <language>en</language>
    <item>
      <title>Implementing CCPA Deletion Is a Distributed Systems Problem</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Tue, 04 Aug 2026 19:13:08 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/implementing-ccpa-deletion-is-a-distributed-systems-problem-2d4d</link>
      <guid>https://dev.to/jam-techcirkle/implementing-ccpa-deletion-is-a-distributed-systems-problem-2d4d</guid>
      <description>&lt;p&gt;The first time a team implements a data deletion request, the ticket usually says something like "add account deletion." Someone adds a button, writes a &lt;code&gt;DELETE FROM users WHERE id = ?&lt;/code&gt;, cascades a few foreign keys, and closes it.&lt;/p&gt;

&lt;p&gt;Then legal asks whether the data is gone from the analytics warehouse. And the answer is no. And the ticket reopens as an architecture project.&lt;/p&gt;

&lt;p&gt;If you build for California residents, CCPA and CPRA make this obligation real rather than theoretical, and the interesting part is that it is not a legal problem at all once the requirement is understood. It is a distributed systems problem about every place data has been copied to, and it is far easier to design for than to retrofit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual requirement
&lt;/h2&gt;

&lt;p&gt;Stripped of legal language, the system must be able to do three things for a given individual:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Locate&lt;/strong&gt; every piece of personal information about them, everywhere it is stored&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produce&lt;/strong&gt; it in a portable format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete&lt;/strong&gt; it, with limited and specific exceptions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Point one is the hard one. Points two and three are mostly mechanical once you can do point one reliably.&lt;/p&gt;

&lt;p&gt;The reason point one is hard is that "everywhere" is a much larger set than most teams' mental model of their system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the data actually is
&lt;/h2&gt;

&lt;p&gt;Write this list out for your own system. It is longer than you expect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary database.&lt;/strong&gt; The obvious one. Usually the only one anyone thinks of initially.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read replicas and caches.&lt;/strong&gt; Redis keyed by user id, materialised views, denormalised lookup tables, search indices. An Elasticsearch document containing a user's name and email survives the primary-database delete quite happily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The analytics warehouse.&lt;/strong&gt; Your BigQuery or Snowflake instance has been receiving event streams for years. Those events contain user identifiers, and often much more than identifiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event streams and message queues.&lt;/strong&gt; Kafka topics with a retention window still contain the data during that window. So do dead-letter queues, which frequently have no retention policy at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application logs.&lt;/strong&gt; This is the one that catches people. If you have ever logged a request body during debugging, personal data is sitting in your log aggregator, and log aggregators are typically retained for months and indexed for search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backups.&lt;/strong&gt; The genuinely hard one, discussed below.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party processors.&lt;/strong&gt; Your email provider, payment processor, error tracker, session recorder, support desk, CRM, feature flag service, and marketing automation platform each hold a copy. Each has its own deletion API, its own latency, and its own quirks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Derived artifacts.&lt;/strong&gt; Exported CSVs sitting in an S3 bucket, generated PDFs, a data-science team's working copy in a notebook environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A deletion implementation that does not have an answer for every line on that list is not a deletion implementation. It is a button.&lt;/p&gt;

&lt;h2&gt;
  
  
  The backup problem
&lt;/h2&gt;

&lt;p&gt;Backups are where most implementations quietly compromise, and it is worth understanding the honest options rather than pretending the problem does not exist.&lt;/p&gt;

&lt;p&gt;Deleting a single record from a backup is generally not feasible. Backups are immutable snapshots by design; that immutability is the entire point of having them.&lt;/p&gt;

&lt;p&gt;The three approaches that actually get used:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retention-window expiry.&lt;/strong&gt; Document that backups age out on a defined schedule — 30, 60, 90 days — and that deletion propagates as backups expire. Track the pending deletion so that if a restore happens within the window, the deletion is reapplied immediately afterwards. This is the most common approach and it is defensible when the window is documented and the reapplication step actually exists rather than being assumed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crypto-shredding.&lt;/strong&gt; Encrypt each user's personal data with a per-user key held outside the backup scope. Deleting the key renders the backed-up ciphertext unrecoverable. This is elegant, genuinely solves the problem, and has to be designed in from the start — retrofitting per-user encryption into an existing schema is a large project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokenisation.&lt;/strong&gt; Keep personal data in a separate vault referenced by token, so the bulk of the system holds only tokens. Delete the vault entry and every backup elsewhere contains only meaningless identifiers. Also a design-time decision.&lt;/p&gt;

&lt;p&gt;The point is not that one approach is correct. It is that a team who has done this before will raise backups within the first two minutes of the conversation, because it is the constraint that shapes the design. A team who has not will describe a settings page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design implications worth adopting early
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A user-data inventory as a maintained artifact.&lt;/strong&gt; A document, ideally generated or at least validated by tests, listing every store containing personal data and the deletion mechanism for each. Without it, the next new datastore silently breaks compliance and nobody notices for a year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A deletion orchestrator, not a deletion function.&lt;/strong&gt; Deletion spans systems with different latencies and failure modes, and third-party APIs fail. This is a durable workflow with retries, idempotency, per-target status tracking, and an audit record — not a synchronous call chain. Treat it with the same seriousness as a payment flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log hygiene as a build-time concern.&lt;/strong&gt; Structured logging with an explicit allowlist for fields, plus a linter or CI check that fails when a request body is logged whole. Cleaning personal data out of a year of log history is enormously more expensive than never putting it there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistent identifiers across systems.&lt;/strong&gt; If your warehouse keys on a different user identifier than your primary database, and your support desk keys on email address, locating one individual across all three becomes a join nobody wants to maintain under time pressure. Decide the correlation strategy early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it in CI.&lt;/strong&gt; Create a user, exercise the system so data spreads to every store on the inventory, issue a deletion, then assert emptiness across all of them. This is one of the highest-value integration tests a product can have, and almost nobody writes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this belongs in a vendor conversation
&lt;/h2&gt;

&lt;p&gt;If you are evaluating an engineering partner and you serve California residents, this is a precise, checkable question with a wide range of possible answers: &lt;em&gt;describe a data subject deletion you implemented end to end.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Teams who have done it start with backups and third-party processors, because that is where the difficulty lives. Teams who have not describe a settings page and a database cascade.&lt;/p&gt;

&lt;p&gt;It is worth noting that the obligation attaches to serving California residents, not to where your engineering team is located. A firm in San Francisco has no inherent advantage here over a distributed team — what matters is whether they have implemented it before.&lt;/p&gt;




&lt;p&gt;The full guide to evaluating California engineering partners — market segments, regional differences, current rate bands, contract specifics under California law, and twelve-month cost ranges — is here: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/software-companies-in-california-usa" rel="noopener noreferrer"&gt;Software Companies in California, USA&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does CCPA require deleting data from backups?
&lt;/h3&gt;

&lt;p&gt;The obligation is to delete personal information, and regulators have generally accepted documented retention-window expiry as reasonable for backups, provided deletion is reapplied if a restore occurs within the window. Crypto-shredding and tokenisation solve it more completely but must be designed in from the start.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is crypto-shredding?
&lt;/h3&gt;

&lt;p&gt;Encrypting each user's personal data with a per-user key stored outside backup scope. Deleting the key makes the backed-up ciphertext unrecoverable without touching the backup itself. It works well and is difficult to retrofit into an existing schema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why are application logs such a common problem?
&lt;/h3&gt;

&lt;p&gt;Because request bodies get logged during debugging and the practice persists. Log aggregators are typically retained for months and are fully indexed, so personal data there is both durable and searchable. A CI check that fails on whole-body logging is far cheaper than remediating a year of history.&lt;/p&gt;

&lt;h3&gt;
  
  
  How should deletion across third-party services be implemented?
&lt;/h3&gt;

&lt;p&gt;As a durable, idempotent workflow with retries and per-target status tracking, not a synchronous call chain. Third-party deletion APIs have varied latencies and failure modes, and you need an audit record showing which targets completed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a California-based team for CCPA compliance?
&lt;/h3&gt;

&lt;p&gt;No. The obligation attaches to serving California residents regardless of where your engineers are. What matters is demonstrated experience implementing deletion end to end — ask for a specific prior implementation rather than a claim of familiarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  What single test proves the implementation works?
&lt;/h3&gt;

&lt;p&gt;An integration test that creates a user, exercises the system so data propagates to every store in your inventory, issues a deletion, then asserts emptiness across all of them. Very few teams have this, and it is one of the highest-value tests a product can carry.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>architecture</category>
      <category>database</category>
      <category>devops</category>
    </item>
    <item>
      <title>Technically Vetting an Engineering Vendor — Ask for Artifacts, Not Answers</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Tue, 04 Aug 2026 19:11:40 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/technically-vetting-an-engineering-vendor-ask-for-artifacts-not-answers-191l</link>
      <guid>https://dev.to/jam-techcirkle/technically-vetting-an-engineering-vendor-ask-for-artifacts-not-answers-191l</guid>
      <description>&lt;p&gt;At some point a senior engineer gets pulled into a vendor selection. Usually late, usually as "can you sit in on the technical call," and usually with the commercial decision already 80% made. If that is you, here is the useful framing: you are not there to evaluate the pitch. You are there to convert unverifiable claims into checkable artifacts.&lt;/p&gt;

&lt;p&gt;Every question you ask in a sales conversation has a free answer. "Do you write tests?" Yes. "Do you do code review?" Of course. "Is your team senior?" Very. None of that is information — it is the only possible response, so it carries no signal.&lt;/p&gt;

&lt;p&gt;Artifacts carry signal. Here is the list I actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The CI pipeline config from a recent project
&lt;/h2&gt;

&lt;p&gt;Ask for the actual file. A &lt;code&gt;.github/workflows/*.yml&lt;/code&gt;, a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;, a Jenkinsfile — redacted for secrets and client names, fine.&lt;/p&gt;

&lt;p&gt;What you are reading for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are tests a &lt;strong&gt;merge gate&lt;/strong&gt;, or a job that runs and is allowed to fail? A red-but-mergeable pipeline is the single most common form of theatre in this category.&lt;/li&gt;
&lt;li&gt;Is there a lint and type-check stage, and does it block?&lt;/li&gt;
&lt;li&gt;Is there any security scanning — dependency audit, SAST, secret detection?&lt;/li&gt;
&lt;li&gt;Are migrations run and rolled back somewhere before production?&lt;/li&gt;
&lt;li&gt;How long does the pipeline take? A 45-minute pipeline shapes team behaviour whether anyone admits it or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A team that cannot produce this file in a day either does not have one or does not have access to their own past work. Both are informative.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. An architecture decision record
&lt;/h2&gt;

&lt;p&gt;One ADR from a real project. What you want to see is a decision where the team chose the &lt;em&gt;less&lt;/em&gt; obvious option and wrote down why, including what they gave up.&lt;/p&gt;

&lt;p&gt;The failure mode is a document that reads like a justification written after the fact, listing only advantages. Real ADRs have a "consequences" section that contains something the author is not happy about. If every ADR they have is uniformly positive, they are producing documentation as an artifact of process compliance rather than as a thinking tool, which tells you what the thinking is like.&lt;/p&gt;

&lt;p&gt;If they cannot produce one at all, your future internal team inherits a system whose decisions exist only in the heads of people who will not be there.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A production incident timeline
&lt;/h2&gt;

&lt;p&gt;Ask: what broke in production on your last engagement, how was it detected, how long did it take to resolve, and what changed afterwards?&lt;/p&gt;

&lt;p&gt;The wrong answer is "nothing significant." Everything breaks. That answer means either the systems have no users or nobody is watching.&lt;/p&gt;

&lt;p&gt;The right answer has a detection mechanism in it (an alert, not a customer email), a timeline with real numbers, and a follow-up change that was made to the system or the process. Bonus signal if they mention something they got wrong during the response.&lt;/p&gt;

&lt;p&gt;This one question tells you more about engineering culture than the entire case study section of a proposal.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Their review policy for AI-generated code
&lt;/h2&gt;

&lt;p&gt;This is now the highest-signal technical question available, because the industry has not converged on an answer yet and so the responses are genuinely differentiated.&lt;/p&gt;

&lt;p&gt;Ask: what proportion of your production code is AI-assisted, and what is your review gate for it?&lt;/p&gt;

&lt;p&gt;Teams who have engineered around this describe specific mechanisms — diff size limits so a reviewer can actually reason about a change, mandatory human review for anything touching authentication, payments, or personal data, coverage requirements before merge, and often a rule that generated code must be accompanied by tests the human wrote rather than tests the model wrote alongside it.&lt;/p&gt;

&lt;p&gt;Teams who have not thought about it are enthusiastic and unspecific. That is the answer you are listening for, and it takes about thirty seconds to get.&lt;/p&gt;

&lt;p&gt;The reason this matters technically: the volume of code arriving for review went up sharply while review capacity did not. Any team that has not adjusted its process for that is accumulating a review-quality deficit whether or not they can feel it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Evidence of production AI, if you need AI features
&lt;/h2&gt;

&lt;p&gt;Distinct from the above. Using a coding assistant well and shipping a system with a model in the request path are unrelated competencies.&lt;/p&gt;

&lt;p&gt;If your roadmap includes AI features, ask for a live production system with usage numbers, then ask three follow-ups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does your evaluation harness look like, and what regression did it catch?&lt;/li&gt;
&lt;li&gt;What is your cost per user session, and how did you get it there?&lt;/li&gt;
&lt;li&gt;What happens when the provider degrades — not goes down, degrades?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Teams with real production experience answer all three immediately because they have been hurt by all three. Teams without it pivot to describing a proof of concept. Serious &lt;a href="https://techcirkle.com/llm-integration" rel="noopener noreferrer"&gt;LLM integration&lt;/a&gt; work is identifiable within about two minutes of questioning, and the same holds for &lt;a href="https://techcirkle.com/agentic-workflow-development" rel="noopener noreferrer"&gt;agentic systems&lt;/a&gt; where you should additionally ask about action-level permissions, idempotency, and the rollback path.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Where the repos and cloud accounts will live
&lt;/h2&gt;

&lt;p&gt;Not a technical question in the usual sense, but you are the person in the room who understands the consequences.&lt;/p&gt;

&lt;p&gt;Repositories in your GitHub organisation from the first commit. Cloud accounts owned by your company with vendor engineers holding scoped IAM roles, not the reverse. CI configuration, monitoring dashboards, and third-party service accounts the same.&lt;/p&gt;

&lt;p&gt;The version where the vendor "manages it for now and hands over at the end" is how handovers become renegotiations. Raise it early, because it is trivial to arrange at kickoff and genuinely painful to unwind eighteen months in.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. The named team, in writing
&lt;/h2&gt;

&lt;p&gt;Ask which specific engineers will be assigned and what they shipped most recently. Then ask for that to appear in the statement of work, with a clause requiring written approval to change it and a minimum commitment period for the technical lead.&lt;/p&gt;

&lt;p&gt;Team substitution after signature is the most frequent complaint in this market. It is also entirely contractually preventable, and the fix costs nothing except the willingness to ask before signing rather than after.&lt;/p&gt;




&lt;p&gt;None of this requires you to be the decision maker. It requires you to convert seven claims into seven artifacts, hand the folder back to whoever is deciding, and let the gaps speak.&lt;/p&gt;

&lt;p&gt;The full buyer-side version — delivery models, current US rate bands, pricing structures, compliance expectations, and realistic twelve-month cost ranges — is here: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/product-engineering-services-companies-usa" rel="noopener noreferrer"&gt;Product Engineering Services Companies in USA: A 2026 Buyer's Guide&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What if a vendor refuses to share a CI config?
&lt;/h3&gt;

&lt;p&gt;A redacted pipeline file from any past project contains no client-identifying information, so refusal usually means it does not exist or is embarrassing. Offer to accept it with all names, secrets, and URLs stripped. If that is still refused, note it and move on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a slow CI pipeline actually a problem?
&lt;/h3&gt;

&lt;p&gt;Yes, indirectly. Pipelines over about fifteen minutes change behaviour — engineers batch changes into larger commits, skip local verification, and merge on optimism. You are reading the number as a proxy for how the team works day to day.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I evaluate AI code review policy if we do not use AI ourselves?
&lt;/h3&gt;

&lt;p&gt;You are not evaluating the policy against your own practice; you are checking that one exists and is specific. Diff size limits, mandatory human review on sensitive paths, and coverage gates are the concrete markers. Absence of any policy means unreviewed volume is entering the codebase you will inherit.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between using AI and building AI features?
&lt;/h3&gt;

&lt;p&gt;Using AI is a development practice — code generation, refactoring, test scaffolding. Building AI features means owning retrieval quality, evaluation datasets, latency budgets, cost per session, and failure behaviour when a model provider degrades. Vendors deliberately blur the two; ask for a production system with users to separate them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should repositories really live in our org from day one?
&lt;/h3&gt;

&lt;p&gt;Yes. It costs nothing at kickoff and it removes an entire category of leverage from any future dispute. The same applies to cloud accounts, CI configuration, monitoring, and third-party service accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  How many artifacts should I ask for before it looks adversarial?
&lt;/h3&gt;

&lt;p&gt;All of them. Every serious firm has been asked before and can produce them within a few days. A vendor that treats routine technical due diligence as an insult has told you something useful about how they will respond to scrutiny during delivery.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>testing</category>
      <category>architecture</category>
      <category>career</category>
    </item>
    <item>
      <title>An RTL Checklist That Catches What Frameworks Miss</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sun, 02 Aug 2026 16:51:52 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/an-rtl-checklist-that-catches-what-frameworks-miss-jcd</link>
      <guid>https://dev.to/jam-techcirkle/an-rtl-checklist-that-catches-what-frameworks-miss-jcd</guid>
      <description>&lt;p&gt;Turn on RTL support in React Native, Flutter, SwiftUI or Compose and roughly 80% of your layout mirrors correctly on the first try. That number is the problem. It is high enough to feel finished and low enough that the remaining 20% will be found by your users.&lt;/p&gt;

&lt;p&gt;This is the checklist for the 20%.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Mirror by meaning, not by geometry
&lt;/h2&gt;

&lt;p&gt;The framework mirrors the view hierarchy. It does not know which elements carry directional meaning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mirror:&lt;/strong&gt; navigation and back affordances, the back gesture edge, progress indicators, sliders, carousels and their swipe direction, list disclosure chevrons, drawer position, alignment of body text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not mirror:&lt;/strong&gt; logos and wordmarks, media playback controls (a mirrored play button reads as rewind), clock and timer faces, phone numbers, most physical-world icons, and time-series charts where the reader's expectation of time flowing one way outweighs layout direction.&lt;/p&gt;

&lt;p&gt;Ambiguous by product: back/forward media controls, undo and redo, and any icon whose arrow is metaphorical rather than navigational. Decide these deliberately and write the decision down, because otherwise a future contributor will "fix" it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use logical properties everywhere
&lt;/h2&gt;

&lt;p&gt;Anywhere your codebase says &lt;code&gt;left&lt;/code&gt; or &lt;code&gt;right&lt;/code&gt;, it is a latent RTL bug.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; semantics: &lt;code&gt;marginStart&lt;/code&gt;, &lt;code&gt;paddingEnd&lt;/code&gt;, &lt;code&gt;textAlign: start&lt;/code&gt;, &lt;code&gt;flexDirection: row&lt;/code&gt; with logical alignment rather than manual reversal. Add a lint rule banning physical directional properties in UI code. Without the lint rule, the pattern degrades within two quarters, because writing &lt;code&gt;marginLeft&lt;/code&gt; is muscle memory.&lt;/p&gt;

&lt;p&gt;Padding asymmetries are the sneakiest case: a 16/8 left/right padding pair that reads as deliberate design in LTR reads as a misalignment in RTL, and nobody will file it as a bug — they will just find the screen slightly wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Isolate mixed-content runs explicitly
&lt;/h2&gt;

&lt;p&gt;This is where the real bugs live. Arabic apps constantly mix Latin content: brand names, URLs, product SKUs, email addresses, phone numbers, prices.&lt;/p&gt;

&lt;p&gt;The Unicode bidirectional algorithm resolves runs by character class, and neutral characters (spaces, punctuation, digits) take direction from their surroundings. Concatenate a Latin string into an Arabic sentence without isolation and you get reordered phone digits, URLs split across the sentence, or a price rendered on the wrong side of its symbol.&lt;/p&gt;

&lt;p&gt;Fixes, in order of preference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the platform's localized formatters for numbers, currency and dates rather than string concatenation. This solves the majority of cases for free.&lt;/li&gt;
&lt;li&gt;Wrap embedded foreign-direction runs in isolate marks (&lt;code&gt;U+2068&lt;/code&gt; / &lt;code&gt;U+2069&lt;/code&gt;) or the platform's equivalent bidi-isolation API.&lt;/li&gt;
&lt;li&gt;Never build a user-visible string by concatenating a localized fragment with a raw data value. Use parameterized format strings so the formatter can reason about the whole sentence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Critically: &lt;strong&gt;these bugs will pass your tests.&lt;/strong&gt; A snapshot test comparing strings passes because the characters are all present and in logical order — it is the &lt;em&gt;visual&lt;/em&gt; order that is wrong. Only rendered-screenshot review, by someone who reads Arabic, catches them.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Typography needs its own pass
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use a typeface with a real Arabic cut, not system fallback. Fallback renders glyphs correctly in isolation and fails at contextual joining.&lt;/li&gt;
&lt;li&gt;Increase line height relative to your Latin setting. Arabic sits differently on the baseline and carries marks above and below; Latin-tuned leading feels cramped.&lt;/li&gt;
&lt;li&gt;Do not use Latin font weights as a proxy for Arabic emphasis. Many Arabic typefaces have fewer weights, and synthetic bolding looks broken.&lt;/li&gt;
&lt;li&gt;Verify text rendering on older Android hardware, which remains common in the market — font fallback behaviour differs from what you see on a current device.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Numerals and calendars are product decisions
&lt;/h2&gt;

&lt;p&gt;Eastern Arabic (٠١٢٣) versus Western Arabic (0123) numerals is not a technical choice; it is an audience choice with no universally correct answer. What matters is consistency across UI, notifications, receipts and exported documents.&lt;/p&gt;

&lt;p&gt;Where dates carry religious, governmental or contractual meaning, Hijri calendar support is required — and it needs to work in scheduling and reminders, not only in a display formatter. Converting for display while scheduling against Gregorian internally is a defensible architecture; getting them out of sync is a support ticket you will not enjoy.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Test the things that only break at runtime
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Language switch mid-session. On some platforms an RTL toggle requires a restart; if yours does, handle it deliberately rather than leaving the app in a half-mirrored state.&lt;/li&gt;
&lt;li&gt;Deep links and push notifications opening into a screen in the other direction.&lt;/li&gt;
&lt;li&gt;Text input with mixed direction — typing a Latin email address into an Arabic form is where cursor behaviour, selection and backspace get strange.&lt;/li&gt;
&lt;li&gt;Screenshots for store listings in both directions, at every required device size.&lt;/li&gt;
&lt;li&gt;Accessibility: verify screen reader reading order in RTL, which does not automatically follow visual order.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Put a native reader in the release process
&lt;/h2&gt;

&lt;p&gt;Everything above is mechanical and can be enforced with tooling. This last item cannot.&lt;/p&gt;

&lt;p&gt;A native Arabic speaker with product judgment needs to look at real screens before every release. Not a translator checking strings in a spreadsheet — someone using the app. They will catch the register of the copy, the mixed-content rendering, and the small wrongnesses that no test asserts on and every user perceives.&lt;/p&gt;

&lt;p&gt;The broader guide — SAR cost benchmarks, PDPL and residency, mada and Nafath integration, and how to vet a partner — is here: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/mobile-app-development-company-saudi-arabia" rel="noopener noreferrer"&gt;Mobile App Development Company in Saudi Arabia: The 2026 Buyer's Guide&lt;/a&gt;&lt;/strong&gt;. How we run delivery is on our &lt;a href="https://techcirkle.com/development/mobile-app-development" rel="noopener noreferrer"&gt;mobile app development&lt;/a&gt; page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does enabling RTL in my framework handle Arabic support?
&lt;/h3&gt;

&lt;p&gt;It handles most layout mirroring and none of the judgment. Framework RTL does not know which elements carry directional meaning, does not fix bidirectional text isolation, and does not address typography, numerals or copy quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should never be mirrored in an RTL layout?
&lt;/h3&gt;

&lt;p&gt;Logos and wordmarks, media playback controls, clock and timer faces, phone numbers, most physical-world icons, and time-series charts. Mirroring these produces interfaces that look intentional and read as wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do bidirectional text bugs pass automated tests?
&lt;/h3&gt;

&lt;p&gt;Because the characters are present and in correct logical order — the failure is in visual order after the bidirectional algorithm resolves runs. Only rendered-screenshot review by an Arabic reader reliably catches them.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I prevent RTL regressions over time?
&lt;/h3&gt;

&lt;p&gt;Add a lint rule banning physical directional properties (&lt;code&gt;left&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, &lt;code&gt;marginLeft&lt;/code&gt;) in UI code, and run screenshot tests in both directions on critical screens. Without enforcement, the pattern degrades within a couple of quarters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need Hijri calendar support?
&lt;/h3&gt;

&lt;p&gt;Wherever dates carry religious, governmental or contractual meaning. It needs to work in scheduling and reminders rather than only in display formatting, and the conversion boundary between Hijri display and internal storage must be explicit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is screen reader order automatic in RTL?
&lt;/h3&gt;

&lt;p&gt;No. Accessibility reading order does not automatically follow visual order in mirrored layouts, so verify it explicitly on both platforms as part of RTL QA.&lt;/p&gt;

</description>
      <category>i18n</category>
      <category>mobile</category>
      <category>rtl</category>
      <category>a11y</category>
    </item>
    <item>
      <title>French Localization Broke Our Layout, and It Was Entirely Our Fault</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sun, 02 Aug 2026 16:51:47 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/french-localization-broke-our-layout-and-it-was-entirely-our-fault-51p0</link>
      <guid>https://dev.to/jam-techcirkle/french-localization-broke-our-layout-and-it-was-entirely-our-fault-51p0</guid>
      <description>&lt;p&gt;Every Canadian product team eventually ships an English-first app and files French as a ticket for later. Later arrives, a translator returns a spreadsheet, and suddenly seventeen screens have text overflowing their containers, a settings toggle whose label wraps to three lines, and a push notification that arrives in the wrong language because someone read the device locale instead of the user's preference.&lt;/p&gt;

&lt;p&gt;None of that is a translation problem. All of it is an engineering problem that was deferred, and deferral is what made it expensive.&lt;/p&gt;

&lt;p&gt;Here is what treating bilingual support as engineering actually looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30% rule
&lt;/h2&gt;

&lt;p&gt;French strings run roughly 15–30% longer than their English equivalents. "Settings" becomes "Paramètres". "Save" becomes "Enregistrer". "Sign out" becomes "Se déconnecter". Individually trivial; collectively fatal to any layout designed against English copy with tight horizontal constraints.&lt;/p&gt;

&lt;p&gt;The fix is not to design for French. It is to stop designing against a single fixed string length:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No fixed-width containers around localized text. Ever.&lt;/li&gt;
&lt;li&gt;Buttons size to content with a defined minimum, not a defined width.&lt;/li&gt;
&lt;li&gt;Multi-line labels get an explicit line limit and a truncation strategy chosen deliberately, not inherited from the framework default.&lt;/li&gt;
&lt;li&gt;Review every screen at the longest supported string, not the shortest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cheapest way to enforce this is &lt;strong&gt;pseudo-localization&lt;/strong&gt;. Before any real translation exists, render the app with English strings artificially expanded by ~35% and wrapped in delimiters — &lt;code&gt;[Ŝéttíñgŝ————]&lt;/code&gt;. Two things fall out immediately: every layout that cannot survive French, and every string that was hardcoded and therefore did not expand. Run it as a build variant, put it in CI, and screenshot-diff the critical screens.&lt;/p&gt;

&lt;p&gt;That single technique catches most of what would otherwise be found by a translator's QA pass three weeks before launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bidirectional and mixed-content edge cases
&lt;/h2&gt;

&lt;p&gt;Even in a purely LTR pair like English and French, mixed content bites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number and currency formatting differ. &lt;code&gt;1 234,56 $&lt;/code&gt; is not &lt;code&gt;$1,234.56&lt;/code&gt;, and hardcoded format strings will produce nonsense in one locale or the other. Use the platform formatters.&lt;/li&gt;
&lt;li&gt;Date formats differ, and so do abbreviated month names. Never build a date string by concatenation.&lt;/li&gt;
&lt;li&gt;Sorting and search behave differently with accented characters. &lt;code&gt;é&lt;/code&gt; must collate with &lt;code&gt;e&lt;/code&gt; for user-facing sort and search, which means locale-aware comparison, not byte comparison. &lt;code&gt;String.localeCompare&lt;/code&gt; with the right locale, or the platform collator — not &lt;code&gt;&amp;lt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Search input needs accent-insensitive matching, or Quebec users will conclude your search is broken when "cafe" fails to find "café".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Locale is a user property, not a device property
&lt;/h2&gt;

&lt;p&gt;This is the bug that reaches production most often, because it works perfectly in development.&lt;/p&gt;

&lt;p&gt;The device locale tells you how to render the UI on that device right now. It does not tell you what language to use for a &lt;strong&gt;push notification generated on your server&lt;/strong&gt;, an email, an SMS, or a PDF receipt. Those are produced server-side, potentially hours later, possibly for a user who has since switched devices.&lt;/p&gt;

&lt;p&gt;Store the user's language preference on the user record. Send it up when it changes. Have every server-generated message read from that record. And test the case where a user changes language while a scheduled notification is already queued — the answer should be that they get the new language, and the only way to be sure is to write that test.&lt;/p&gt;

&lt;h2&gt;
  
  
  String management that survives a second locale
&lt;/h2&gt;

&lt;p&gt;If your localization workflow is "export a spreadsheet, email it, paste it back," you have built a process that fails silently. Missing keys become blank UI. Stale keys accumulate forever. Nobody can tell which strings changed since the last release.&lt;/p&gt;

&lt;p&gt;A workable minimum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strings live in the repository, in a structured format, as the single source of truth.&lt;/li&gt;
&lt;li&gt;Keys are semantic (&lt;code&gt;checkout.button.confirm&lt;/code&gt;), never the English text — otherwise every copy edit orphans a translation.&lt;/li&gt;
&lt;li&gt;A CI check fails the build on any key present in one locale and missing in another.&lt;/li&gt;
&lt;li&gt;Every string carries a comment giving the translator context. &lt;code&gt;"Save"&lt;/code&gt; is a verb on a button and a noun in a settings header, and a translator without context will guess wrong roughly half the time.&lt;/li&gt;
&lt;li&gt;Machine translation is a first draft that a native French reviewer edits. Shipping raw MT into a Quebec-facing product is immediately recognizable and quietly expensive in trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to test in CI
&lt;/h2&gt;

&lt;p&gt;Concretely, the pipeline additions that pay for themselves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pseudo-locale build variant, screenshot-diffed on critical screens.&lt;/li&gt;
&lt;li&gt;Missing-key and orphan-key checks across all locales.&lt;/li&gt;
&lt;li&gt;Snapshot tests for both locales on any screen with dynamic content.&lt;/li&gt;
&lt;li&gt;A lint rule banning string literals in UI components — this is the check that keeps the other four honest.&lt;/li&gt;
&lt;li&gt;One end-to-end test that switches language mid-session and asserts the app does not restart into a broken state.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why this matters more in Canada than most markets
&lt;/h2&gt;

&lt;p&gt;Two reasons beyond user experience. Quebec's language rules apply to commercial communications and consumer software in ways that can require French to be available on terms at least as favourable as English — this is not a nice-to-have for a product with national reach. And App Store and Play Store listings, screenshots and support content need French versions to rank properly in Quebec, which means localization is an acquisition channel, not just a UI concern.&lt;/p&gt;

&lt;p&gt;Treated from sprint one, all of this costs a few percent of build effort. Treated as a pre-launch ticket, it is a redesign wearing a smaller name.&lt;/p&gt;

&lt;p&gt;The wider version — Canadian cost bands, PIPEDA and Law 25 architecture, SR&amp;amp;ED eligibility, and how to vet a development partner — is here: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/mobile-app-development-company-canada" rel="noopener noreferrer"&gt;Mobile App Development Company Canada: The 2026 Buyer's Guide&lt;/a&gt;&lt;/strong&gt;. Our &lt;a href="https://techcirkle.com/development/mobile-app-development" rel="noopener noreferrer"&gt;mobile app development&lt;/a&gt; page covers how we structure delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much longer are French strings than English?
&lt;/h3&gt;

&lt;p&gt;Typically 15–30% for UI-length text, with short labels expanding the most in relative terms. Design and review screens at the longest supported string rather than the English original, and use pseudo-localization to surface the failures before a translator ever sees the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is pseudo-localization and why use it?
&lt;/h3&gt;

&lt;p&gt;It is a build variant that renders English strings artificially expanded and wrapped in markers. It exposes both layouts that cannot accommodate longer text and strings that were hardcoded and therefore did not expand — before any translation exists and at effectively zero cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use device locale or a stored user preference?
&lt;/h3&gt;

&lt;p&gt;Device locale for rendering the UI on that device; a stored user preference for anything generated server-side, including push notifications, emails and receipts. Relying on device locale for server-generated messages is the most common localization bug that reaches production.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I handle accented characters in search and sort?
&lt;/h3&gt;

&lt;p&gt;Use locale-aware collation rather than byte comparison, and make user-facing search accent-insensitive so "cafe" matches "café". Getting this wrong reads to users as a broken search feature rather than a localization gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use machine translation for app UI copy?
&lt;/h3&gt;

&lt;p&gt;As a first draft, reviewed and edited by a native speaker before release. Raw machine translation in a Quebec-facing product is recognizable to users immediately and erodes trust in the product generally, not just in the copy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does French support affect App Store ranking in Canada?
&lt;/h3&gt;

&lt;p&gt;Yes. Localized store listings, screenshots and keywords materially affect discoverability in Quebec, which makes localization an acquisition investment rather than purely a UI cost.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>i18n</category>
      <category>reactnative</category>
      <category>testing</category>
    </item>
    <item>
      <title>Review Is the New Bottleneck - Engineering Process After Generated Code</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Wed, 29 Jul 2026 16:41:12 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/review-is-the-new-bottleneck-engineering-process-after-generated-code-okn</link>
      <guid>https://dev.to/jam-techcirkle/review-is-the-new-bottleneck-engineering-process-after-generated-code-okn</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvwb2wdsgo9ju0zwvogyo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvwb2wdsgo9ju0zwvogyo.jpg" alt="Software engineer writing code while colleagues collaborate at a shared desk" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a failure mode I have now seen enough times to describe it as a pattern rather than an anecdote. It goes like this.&lt;/p&gt;

&lt;p&gt;A team adopts AI assistance seriously. Velocity climbs — visibly, on the chart, for about two quarters. Everyone is pleased. Then the incident rate starts rising, and the relationship between the two takes an embarrassingly long time to establish, because the incidents are diffuse. A null check that was never there. An authorization check applied at the wrong layer. A query without an index that was fine at ten thousand rows.&lt;/p&gt;

&lt;p&gt;The root cause is not the tooling. It is that &lt;strong&gt;generation throughput increased and comprehension throughput did not&lt;/strong&gt;, and nobody adjusted the process for the new constraint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why review capacity is the binding constraint
&lt;/h2&gt;

&lt;p&gt;The pre-2023 workflow had a useful property that nobody designed and everybody relied on: the person writing the code understood it, because writing it was how they came to understand it. Review was a second opinion on top of an existing first opinion.&lt;/p&gt;

&lt;p&gt;That property is gone for generated code. Review is now frequently the &lt;em&gt;first&lt;/em&gt; time anyone forms a mental model of what the code does. That is a categorically different task, and it takes longer per line — not less.&lt;/p&gt;

&lt;p&gt;Meanwhile the volume arriving at review went up. Two curves moving in opposite directions.&lt;/p&gt;

&lt;p&gt;The observable symptoms are consistent: pull requests get larger, review latency grows, approval quality degrades under queue pressure, and — the important one — reviewers start pattern-matching on plausibility rather than verifying behaviour. Generated code is &lt;em&gt;unusually&lt;/em&gt; good at looking right. It has correct naming, sensible structure, and plausible error handling. It fails on things that require knowing your system: the invariant that lives in a different service, the reason that table has no index, the auth check that has to happen before the fetch rather than after.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually helps
&lt;/h2&gt;

&lt;p&gt;Six changes, roughly in order of return on effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cap PR size, and enforce it
&lt;/h3&gt;

&lt;p&gt;The single highest-leverage change. Generated code makes large PRs effortless to produce and no easier to review. A hard cap — 400 changed lines is a reasonable starting point, excluding lockfiles and generated schemas — forces decomposition at the point where decomposition is cheap.&lt;/p&gt;

&lt;p&gt;Enforce it in CI rather than in culture. Cultural norms lose to deadline pressure every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Require a provenance note
&lt;/h3&gt;

&lt;p&gt;A one-line PR field: was this predominantly generated, predominantly hand-written, or mixed?&lt;/p&gt;

&lt;p&gt;This sounds bureaucratic and is not. It changes what the reviewer does. Hand-written code from a colleague who understands the system carries a prior that generated code does not, and reviewers calibrate correctly when they know which they are looking at. Without the signal they apply the same prior to both, which is wrong in one direction or the other.&lt;/p&gt;

&lt;p&gt;It also produces data. After six months you can correlate provenance against defect rate in your own codebase rather than arguing from other people's blog posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Write down what may not be generated
&lt;/h3&gt;

&lt;p&gt;An explicit, short list. The specifics vary by system, but the shape is consistent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication and authorization logic&lt;/li&gt;
&lt;li&gt;Cryptographic operations and key handling&lt;/li&gt;
&lt;li&gt;Anything touching money, billing, or ledger state&lt;/li&gt;
&lt;li&gt;Schema migrations on tables with production traffic&lt;/li&gt;
&lt;li&gt;Access control policy&lt;/li&gt;
&lt;li&gt;Data deletion and retention cascades&lt;/li&gt;
&lt;li&gt;Concurrency primitives and locking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not because generation is incapable here, but because these are the areas where plausible-looking wrongness is most expensive and least likely to be caught by tests. The rule is really about forcing a human to hold the mental model where the blast radius is largest.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Shift verification toward properties and integration
&lt;/h3&gt;

&lt;p&gt;Generated unit tests have a systematic weakness: they tend to test the implementation that was just written, including its mistakes. A generated function with an off-by-one and a generated test asserting the off-by-one behaviour is a perfectly self-consistent pair, and it passes.&lt;/p&gt;

&lt;p&gt;What survives this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Property-based tests&lt;/strong&gt; — invariants stated independently of implementation. "Serializing then deserializing returns an equal value." "The ledger balances after any sequence of operations."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration tests against real dependencies&lt;/strong&gt; — a real database, a real queue, in a container. Mocks encode assumptions, and generated mocks encode generated assumptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contract tests at service boundaries&lt;/strong&gt; — where the expensive failures actually live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutation testing on critical paths&lt;/strong&gt; — the only reliable way to distinguish tests that verify behaviour from tests that merely execute lines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Coverage percentage was always a weak signal. With generated tests it is close to meaningless, because coverage is now trivial to manufacture.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Automate what humans read badly
&lt;/h3&gt;

&lt;p&gt;Reviewer attention is now the scarcest resource in the pipeline, so spend it deliberately. Push to tooling everything a machine does better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static analysis and type checking at maximum strictness&lt;/li&gt;
&lt;li&gt;Dependency and supply chain scanning, including anything the assistant suggested — hallucinated package names that later get registered by someone else is a real attack pattern&lt;/li&gt;
&lt;li&gt;Secret scanning in the pre-commit hook, not just in CI&lt;/li&gt;
&lt;li&gt;Performance regression checks on hot paths&lt;/li&gt;
&lt;li&gt;Automated detection of common generated-code smells: swallowed exceptions, unbounded retries, N+1 queries, missing pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every item automated is attention returned to the things only a human can check — whether this code is correct &lt;em&gt;for this system&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Review architecture separately from implementation
&lt;/h3&gt;

&lt;p&gt;Generated code is usually locally sensible and globally questionable. It does not know your service boundaries, your existing utilities, or the abstraction you deliberately avoided two years ago for good reasons.&lt;/p&gt;

&lt;p&gt;Separating architectural review from line-level review helps, because the two questions require different context and different reviewers. "Does this belong here at all?" is a different question from "is this loop correct?" and asking them simultaneously means one of them gets less attention than it needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The economics, stated honestly
&lt;/h2&gt;

&lt;p&gt;Because this connects directly to how work gets priced.&lt;/p&gt;

&lt;p&gt;Genuinely compressed by current tooling: boilerplate, CRUD, API clients, test scaffolding, migrations, first-draft interfaces, documentation, and orientation in unfamiliar code. Real, measurable, a meaningful minority of total effort on an enterprise build.&lt;/p&gt;

&lt;p&gt;Not compressed at all: understanding an undocumented business process, integrating a legacy system whose author has left, resolving a data model dispute between departments, security architecture, load behaviour, regulatory interpretation, stakeholder alignment. These dominate.&lt;/p&gt;

&lt;p&gt;Newly added: inference as an operating cost that scales with usage, evaluation infrastructure, drift monitoring — and the review burden described above.&lt;/p&gt;

&lt;p&gt;Which is why a vendor promising fifty percent off "because AI" is describing a fantasy. The honest number is meaningfully smaller, and it arrives only for teams that adapted their process. Teams that did not adapt are not saving money; they are deferring it into a maintenance budget nobody has forecast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test I would apply
&lt;/h2&gt;

&lt;p&gt;If you are evaluating a team — internal or external — ask two things.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is your standard for what may not be generated?&lt;/em&gt; A written answer means they have thought about blast radius. No answer means every part of the system is being treated as equally safe to automate, which is not true of any system I have worked on.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How did your review process change?&lt;/em&gt; "It didn't" is a complete and worrying answer. Generation throughput went up by a lot. If nothing downstream adjusted, the queue is absorbing it, and queues absorb pressure by lowering quality rather than by complaining.&lt;/p&gt;

&lt;p&gt;Full guide to US delivery models, rate reality, compliance costs, contract structures, and budgeting: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/custom-software-development-services-in-usa" rel="noopener noreferrer"&gt;Custom Software Development Services in USA: The 2026 Cost and Vendor Guide&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgmxl4wu15wi22t34dqk1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgmxl4wu15wi22t34dqk1.jpg" alt="Business partners shaking hands after signing a software development agreement" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why is reviewing generated code slower than reviewing hand-written code?
&lt;/h3&gt;

&lt;p&gt;Because review is often the first time anyone forms a mental model of what the code does. Previously the author built that understanding while writing, and review was a second opinion on an existing one. Forming the model from scratch takes longer per line.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should never be AI-generated?
&lt;/h3&gt;

&lt;p&gt;Authentication and authorization, cryptographic operations, anything touching money or ledger state, migrations on production tables, access control policy, deletion and retention cascades, and concurrency primitives. These are where plausible-looking wrongness is most expensive and least likely to be caught by tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are generated tests useful?
&lt;/h3&gt;

&lt;p&gt;Partially. They tend to test the implementation that was just written, including its bugs, producing a self-consistent pair that passes. Property-based tests, integration tests against real dependencies, contract tests, and mutation testing on critical paths are far more reliable signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does code coverage still mean anything?
&lt;/h3&gt;

&lt;p&gt;Less than it ever did. Coverage is now trivial to manufacture, so a high percentage indicates that lines executed, not that behaviour was verified. Mutation testing on critical paths is the practical replacement.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the highest-return process change?
&lt;/h3&gt;

&lt;p&gt;A hard, CI-enforced cap on pull request size. Generated code makes large PRs effortless to produce and no easier to review, and review quality degrades sharply with size. Cultural norms about PR size lose to deadline pressure; CI does not.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>productivity</category>
      <category>engineering</category>
    </item>
    <item>
      <title>RTL, Residency, and Collation - Three UAE Constraints You Cannot Retrofit</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Wed, 29 Jul 2026 16:39:40 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/rtl-residency-and-collation-three-uae-constraints-you-cannot-retrofit-bd8</link>
      <guid>https://dev.to/jam-techcirkle/rtl-residency-and-collation-three-uae-constraints-you-cannot-retrofit-bd8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl5xpqhzdk6b9kgkq3lyq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl5xpqhzdk6b9kgkq3lyq.jpg" alt="Dubai downtown skyline meeting the desert, representing the UAE technology market" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most internationalization advice treats locale support as a layer: build the app, extract the strings, add the translations, ship. That model works reasonably well for adding French to an English product.&lt;/p&gt;

&lt;p&gt;It fails for the UAE, and it fails in a specific way worth understanding, because two of the three constraints below are not string problems at all. They are schema and infrastructure problems wearing i18n clothing, and both get dramatically more expensive after your data model settles.&lt;/p&gt;

&lt;p&gt;Here is what actually breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. RTL is a layout engine concern, not a stylesheet toggle
&lt;/h2&gt;

&lt;p&gt;The naive mental model is &lt;code&gt;direction: rtl&lt;/code&gt; and you are done. Modern CSS gets you further than it used to — logical properties (&lt;code&gt;margin-inline-start&lt;/code&gt;, &lt;code&gt;padding-inline-end&lt;/code&gt;, &lt;code&gt;inset-inline&lt;/code&gt;) handle a great deal automatically if you used them from the start.&lt;/p&gt;

&lt;p&gt;That conditional is the whole problem. Most codebases did not use them from the start. They used &lt;code&gt;margin-left&lt;/code&gt;, &lt;code&gt;padding-right&lt;/code&gt;, and &lt;code&gt;left: 0&lt;/code&gt;, thousands of times, across a component library and every one-off override that accumulated on top of it.&lt;/p&gt;

&lt;p&gt;What breaks beyond the obvious mirroring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Directional iconography.&lt;/strong&gt; Back arrows, next chevrons, progress indicators, and send icons all need mirroring. Logos, media playback controls, and clock icons must &lt;em&gt;not&lt;/em&gt; mirror. There is no automatic rule; it requires a per-icon decision, which means an audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixed-direction strings.&lt;/strong&gt; An Arabic sentence containing a Latin brand name and a numeral is handled by the Unicode bidirectional algorithm, and the result is frequently not what you intended. Punctuation at boundaries lands in visually wrong positions. You need isolation marks (&lt;code&gt;U+2068&lt;/code&gt; / &lt;code&gt;U+2069&lt;/code&gt;) or &lt;code&gt;&amp;lt;bdi&amp;gt;&lt;/code&gt; around embedded runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text expansion.&lt;/strong&gt; Arabic strings can be meaningfully shorter or longer than their English equivalents. Components sized against English copy overflow or collapse. Fixed-width buttons are the usual first casualty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party components.&lt;/strong&gt; Your date picker, charting library, rich text editor, and map controls each have their own RTL story. Some are excellent. Some do nothing. You find out one at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animations and gestures.&lt;/strong&gt; Slide-in directions, swipe-to-dismiss, and carousel transitions all carry directional assumptions written when someone was thinking left-to-right.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is intellectually hard. All of it is a sweep across the entire surface area of the product, which is why doing it at the end costs multiples of doing it from the beginning — and why retrofitted RTL interfaces tend to &lt;em&gt;look&lt;/em&gt; retrofitted to people who read Arabic natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Collation and normalization break search silently
&lt;/h2&gt;

&lt;p&gt;This is the one that gets shipped broken, because it produces no errors. Search simply returns fewer results than it should, and nobody files a bug because nobody knows what should have matched.&lt;/p&gt;

&lt;p&gt;Arabic text has several sources of variance that users do not perceive as variance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alef variants.&lt;/strong&gt; &lt;code&gt;أ&lt;/code&gt;, &lt;code&gt;إ&lt;/code&gt;, &lt;code&gt;آ&lt;/code&gt;, and &lt;code&gt;ا&lt;/code&gt; are frequently typed interchangeably. A user searching for a name spelled with one will not match a record stored with another under naive equality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ta marbuta and ha.&lt;/strong&gt; &lt;code&gt;ة&lt;/code&gt; and &lt;code&gt;ه&lt;/code&gt; are commonly substituted at word endings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alef maqsura and ya.&lt;/strong&gt; &lt;code&gt;ى&lt;/code&gt; and &lt;code&gt;ي&lt;/code&gt; likewise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diacritics (tashkeel).&lt;/strong&gt; Usually absent, sometimes present. &lt;code&gt;U+064B&lt;/code&gt;–&lt;code&gt;U+0652&lt;/code&gt; need stripping before comparison.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tatweel.&lt;/strong&gt; The kashida &lt;code&gt;ـ&lt;/code&gt; is a decorative elongation carrying no semantic meaning and must be removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentation forms.&lt;/strong&gt; Text pasted from PDFs or legacy systems often arrives as Unicode presentation forms rather than standard letters. NFKC normalization handles this; nothing else does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix is a normalized search column populated at write time — strip diacritics and tatweel, unify alef and ya and ta marbuta variants, apply NFKC — with queries normalized identically before comparison. Add an appropriate index on it.&lt;/p&gt;

&lt;p&gt;Note the shape of that fix: &lt;strong&gt;a new column, written at insert time, backfilled across existing rows.&lt;/strong&gt; That is a migration on your hottest table, plus a rewrite of every query that touches it. Cheap in week two. Genuinely disruptive in month eight with production traffic on it.&lt;/p&gt;

&lt;p&gt;Two related traps in the same family. Person names in Arabic do not decompose reliably into first and last — a schema with &lt;code&gt;first_name&lt;/code&gt; and &lt;code&gt;last_name&lt;/code&gt; &lt;code&gt;NOT NULL&lt;/code&gt; will corrupt real user data from the first week of production. And sorting requires a locale-aware collation, not byte ordering, or your alphabetical lists are arbitrary to the people reading them.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Data residency is decided in week one whether you decide it or not
&lt;/h2&gt;

&lt;p&gt;The third constraint is the most expensive and the least visible, because it is settled by default before anyone frames it as a decision. Someone stands up infrastructure, picks the region they always pick, and the choice is made.&lt;/p&gt;

&lt;p&gt;The regulatory picture here has four interacting layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;federal data protection law&lt;/strong&gt;, broadly GDPR-shaped — lawful basis, subject rights, breach notification, controls on cross-border transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free zone regimes.&lt;/strong&gt; DIFC and ADGM operate their own data protection frameworks with their own commissioners. If your entity sits in one of these, the federal law is not the complete picture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sector regulators.&lt;/strong&gt; Health data under DHA or DoH oversight and financial data under Central Bank supervision carry residency expectations stricter than the federal baseline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own entity structure.&lt;/strong&gt; Mainland versus free zone determines which of the above applies, plus payment gateway eligibility and national digital identity integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineering consequences that follow directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Region selection is a week-one decision.&lt;/strong&gt; Both major hyperscalers run UAE regions. They cost more than European ones. That delta belongs in the budget from the start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data classification belongs in the schema.&lt;/strong&gt; You need to know which tables hold personal data, which hold health or financial data, and which hold neither — because that determines what may leave the country for analytics or support tooling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party services are the usual leak.&lt;/strong&gt; Analytics, crash reporting, session replay, support widgets, and model APIs all move data across borders by default. Each needs an explicit decision and usually a data processing agreement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletion must be engineered.&lt;/strong&gt; A privacy policy promising deletion in thirty days is fiction if nobody built the cascade. Foreign keys, soft deletes, backups, and downstream analytics copies all need a defined story.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model calls are transfers.&lt;/strong&gt; Routing personal data to an inference endpoint outside a permitted jurisdiction is a cross-border transfer, whatever the integration is called in your architecture diagram.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Relocating residency after schema and integrations have settled means re-architecture plus a live migration, on a team that has already spent its contingency. Compare that to twenty minutes of conversation in week one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI helps here, specifically
&lt;/h2&gt;

&lt;p&gt;Worth being concrete rather than promotional, since this is the part most vendor decks overstate.&lt;/p&gt;

&lt;p&gt;Genuinely useful: generating the normalization function and its test matrix across variant spellings; sweeping a codebase for physical CSS properties and proposing logical replacements; drafting the data classification map from an existing schema; producing migration scripts for the normalized column.&lt;/p&gt;

&lt;p&gt;Not useful: deciding which regulator applies to you, whether a given third-party processor is acceptable, or what your data model should be when departments disagree. Those remain human, and on regulated UAE projects they are the majority of the effort — which is why a proposal offering fifty percent off "because AI" has mispriced the work rather than optimized it.&lt;/p&gt;

&lt;p&gt;The larger shift is what became newly buildable. Reliable Arabic language handling in production moved from research problem to procurement decision in roughly two years. Bilingual document processing, mixed-language semantic search, and Arabic-and-English support triage were six-figure custom projects and are now weeks of integration work. For a bilingual market that matters more than any hourly discount.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical ordering
&lt;/h2&gt;

&lt;p&gt;If you are starting a UAE build this quarter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Establish which regulatory regimes apply — federal, free zone, sector — before infrastructure exists.&lt;/li&gt;
&lt;li&gt;Pick the region accordingly, and put the cost delta in the budget.&lt;/li&gt;
&lt;li&gt;Use CSS logical properties from the first component.&lt;/li&gt;
&lt;li&gt;Add the normalized search column in the initial schema, not later.&lt;/li&gt;
&lt;li&gt;Model names as a single field with optional structured parts.&lt;/li&gt;
&lt;li&gt;Inventory every third-party processor with its data location before integrating it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Six items. Cheap now, expensive later, and in two cases effectively irreversible.&lt;/p&gt;

&lt;p&gt;Full country-level guide, including emirate-by-emirate landscape, AED budget bands, the vendor question set, and contract terms: &lt;strong&gt;&lt;a href="https://techcirkle.com/blog/app-development-companies-in-uae" rel="noopener noreferrer"&gt;App Development Companies in UAE: The 2026 Buyer's Guide&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu41eq53j7u4s9p2rbtny.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu41eq53j7u4s9p2rbtny.jpg" alt="Product designers working through mobile app interface wireframes" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do CSS logical properties fully solve RTL?
&lt;/h3&gt;

&lt;p&gt;They solve layout mirroring if used consistently from the start. They do not handle directional iconography decisions, bidirectional string isolation, text expansion in fixed-size components, third-party component behaviour, or directional animations. Budget an audit regardless.&lt;/p&gt;

&lt;h3&gt;
  
  
  What exactly should Arabic search normalization do?
&lt;/h3&gt;

&lt;p&gt;Strip diacritics (U+064B–U+0652) and tatweel, unify alef variants to a single form, normalize ta marbuta to ha and alef maqsura to ya, and apply NFKC to collapse presentation forms. Store the result in an indexed column written at insert time, and normalize queries identically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I store UAE user data outside the UAE?
&lt;/h3&gt;

&lt;p&gt;Sometimes — it depends on your sector and entity type rather than a blanket rule. Health data under DHA or DoH oversight and financial data under Central Bank supervision carry the strictest expectations. DIFC and ADGM entities answer to their own regimes. Resolve this before choosing a region.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are AI API calls a cross-border data transfer?
&lt;/h3&gt;

&lt;p&gt;Yes, if personal data is included in the request and the endpoint sits outside a permitted jurisdiction. Treat model providers exactly like any other subprocessor: document the transfer, execute a data processing agreement, and consider a regional deployment where residency is strict.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not just add RTL support later?
&lt;/h3&gt;

&lt;p&gt;Because RTL touches every component, every directional asset, every animation, and every third-party integration. Late RTL is a full-surface sweep rather than a feature, and the results are visibly compromised to native readers. Logical properties from day one cost nothing extra.&lt;/p&gt;

</description>
      <category>i18n</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>database</category>
    </item>
    <item>
      <title>Offline Sync Is the Question That Sorts Mobile Teams</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Mon, 27 Jul 2026 14:15:41 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/offline-sync-is-the-question-that-sorts-mobile-teams-48cn</link>
      <guid>https://dev.to/jam-techcirkle/offline-sync-is-the-question-that-sorts-mobile-teams-48cn</guid>
      <description>&lt;p&gt;If I get one technical question when evaluating a mobile team, I ask how they handle offline state and conflict resolution.&lt;/p&gt;

&lt;p&gt;Not because every app needs offline support. Most do not, at least not fully. I ask because the answer is almost impossible to fake, and because it maps directly onto whether a team has operated apps in the real world or only built them in an office with good wifi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this question works
&lt;/h2&gt;

&lt;p&gt;Offline is where mobile stops being a thin client and becomes a distributed system.&lt;/p&gt;

&lt;p&gt;The moment a device can accept a write it cannot immediately send, you have two copies of the truth and a merge problem. Everything unpleasant about distributed systems arrives at once — ordering, idempotency, partial failure, clock skew, and a user interface that has to represent uncertainty without confusing anyone.&lt;/p&gt;

&lt;p&gt;You cannot reason your way through this from first principles in an interview. Either a team has been through it or they have not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the answers sound like
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"Our app requires connectivity."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes legitimate. Frequently it means the question has not been considered, and the app will behave badly on the Underground, in a lift, in a hospital basement, or on a train through the Cotswolds.&lt;/p&gt;

&lt;p&gt;Follow up: what happens if the network drops mid-submit? If the answer is a spinner that never resolves, or a duplicate record when the user retries, you have your answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"We use last-write-wins."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An actual strategy, and defensible for genuinely single-user data — settings, drafts, personal preferences. Silent data loss for anything collaborative.&lt;/p&gt;

&lt;p&gt;Follow up: what if two devices belonging to the same user edit the same record? A team that has shipped will immediately know whether that case exists in their app and what happens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"We queue mutations and replay them."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we are somewhere. The follow-ups that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are the mutations idempotent, and how is that enforced? Client-generated IDs is the usual answer.&lt;/li&gt;
&lt;li&gt;What happens when a replayed mutation fails validation because the server state moved? Is it dropped, retried forever, or surfaced to the user?&lt;/li&gt;
&lt;li&gt;Is ordering preserved across dependent operations — create-then-update on the same entity?&lt;/li&gt;
&lt;li&gt;How large can the queue get, and what happens when it exceeds that?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A team that has run this in production answers these quickly and mentions at least one thing they got wrong first time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"We use CRDTs."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes exactly right, particularly for collaborative text or list structures. Sometimes an impressive-sounding answer to a problem that a mutation queue would have solved in a fifth of the time.&lt;/p&gt;

&lt;p&gt;Follow up: which CRDT, for which data, and what is the memory profile on a low-end Android device after a year of history? The last part is where the real answers live.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts everyone underestimates
&lt;/h2&gt;

&lt;p&gt;Three specifics that separate a working implementation from one that mostly works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clock skew.&lt;/strong&gt; Device clocks are wrong, sometimes by a lot, and users change them. Any conflict strategy that relies on device timestamps for ordering is broken in a way that will not show up until it does. Server-assigned sequence numbers or logical clocks are the workable answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schema migration with a queue in flight.&lt;/strong&gt; You ship an update. Some users have pending mutations queued in the old shape. Those mutations still have to apply. This is genuinely hard and it is the source of some of the nastiest data bugs I have seen — teams that have hit it once never forget it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Representing uncertainty in the UI.&lt;/strong&gt; The state is not "saved" or "unsaved" — it is "accepted locally, not yet confirmed, possibly about to be rejected." Most apps flatten this into a checkmark and then confuse the user later when something silently changes. Teams with production experience have opinions about this, usually strong ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI wrinkle
&lt;/h2&gt;

&lt;p&gt;Newer and increasingly common: if the app has AI features, the offline story gets a second dimension.&lt;/p&gt;

&lt;p&gt;Inference typically requires connectivity, which means an AI feature is an online feature unless you have shipped an on-device model. That has consequences for how you present availability — a feature that silently degrades is worse than one that clearly states it needs a connection.&lt;/p&gt;

&lt;p&gt;There is also a queuing question. If a user triggers an AI action offline, do you queue the request? If the underlying data has changed by the time it executes, is the result still meaningful? Usually not, which argues for failing fast rather than queuing — but it is a decision, and it should be a conscious one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this generalises
&lt;/h2&gt;

&lt;p&gt;The reason I lean on this question so heavily is that it is a proxy. A team with a considered answer on offline sync almost always has considered answers on the other things that matter — background processing, push reliability, migration strategy, crash triage, what happens when the store rejects a submission.&lt;/p&gt;

&lt;p&gt;Production experience is a single trait that shows up everywhere. Offline sync is just the cheapest place to test for it.&lt;/p&gt;

&lt;p&gt;The wider guide to evaluating UK app companies — 2026 cost ranges, agency archetypes, compliance requirements and contract terms — is &lt;a href="https://techcirkle.com/blog/mobile-app-development-company-uk" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and our &lt;a href="https://techcirkle.com/development/mobile-app-development" rel="noopener noreferrer"&gt;mobile app development&lt;/a&gt; work covers the architecture side in more depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does every mobile app need offline support?
&lt;/h3&gt;

&lt;p&gt;No, and building full offline capability into an app that does not need it is a common and expensive mistake. But every app needs a considered answer for what happens when the network drops mid-operation — even if that answer is a clear error state and a safe retry rather than a sync engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is last-write-wins ever acceptable?
&lt;/h3&gt;

&lt;p&gt;For genuinely single-user, single-device data such as settings, drafts and preferences, yes. For anything collaborative, or anything a user might touch from two devices, it produces silent data loss. The test is whether the same record can be edited from two places; if it can, last-write-wins will eventually destroy something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is clock skew such a problem for sync?
&lt;/h3&gt;

&lt;p&gt;Because device clocks are frequently wrong and users can change them. Any conflict resolution strategy that orders operations by device timestamp will produce incorrect merges in ways that are extremely hard to reproduce. Server-assigned sequence numbers or logical clocks avoid the whole class of bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens to queued mutations when I ship a schema change?
&lt;/h3&gt;

&lt;p&gt;They still have to apply, in their old shape, after the update. This is one of the hardest problems in offline sync and a common source of serious data corruption. Handling it usually means versioning queued mutations and maintaining migration paths for in-flight items — teams that have hit this once design for it thereafter.&lt;/p&gt;

&lt;h3&gt;
  
  
  How should AI features behave offline?
&lt;/h3&gt;

&lt;p&gt;Usually by failing fast and saying so, rather than queuing. Inference generally needs connectivity, and a queued AI request may produce a meaningless result if the underlying data changed before it executed. A feature that clearly states it needs a connection is better than one that silently degrades.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>architecture</category>
      <category>offline</category>
      <category>sync</category>
    </item>
    <item>
      <title>Data Residency in Canada — What ca-central-1 Actually Costs You</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Mon, 27 Jul 2026 14:15:20 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/data-residency-in-canada-what-ca-central-1-actually-costs-you-3aop</link>
      <guid>https://dev.to/jam-techcirkle/data-residency-in-canada-what-ca-central-1-actually-costs-you-3aop</guid>
      <description>&lt;p&gt;Data residency shows up as a checkbox in a procurement document and lands in your architecture as a permanent constraint. The compliance framing is well covered. The engineering consequences are not, and they are the part that bites.&lt;/p&gt;

&lt;p&gt;If you are building for Canadian public sector, healthcare, or a chunk of financial services, you will be asked to keep personal data inside Canada. Here is what that actually means once you are past the checkbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  The regions you have
&lt;/h2&gt;

&lt;p&gt;Three realistic options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt; — &lt;code&gt;ca-central-1&lt;/code&gt; (Montreal) and &lt;code&gt;ca-west-1&lt;/code&gt; (Calgary, added later and thinner on services).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure&lt;/strong&gt; — Canada Central (Toronto) and Canada East (Quebec City).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Cloud&lt;/strong&gt; — &lt;code&gt;northamerica-northeast1&lt;/code&gt; (Montreal) and &lt;code&gt;northamerica-northeast2&lt;/code&gt; (Toronto).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three are genuine regions, not edge locations. That is the good news and roughly where the good news ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost one: service availability lag
&lt;/h2&gt;

&lt;p&gt;Canadian regions are not first-tier launch regions for any of the three providers. New managed services, new instance families, and new model endpoints land in &lt;code&gt;us-east-1&lt;/code&gt; and its equivalents first, and reach Canada anywhere from a few months to never.&lt;/p&gt;

&lt;p&gt;This matters most for anything AI-adjacent right now, because that is where the release cadence is fastest. If your architecture assumes a specific managed inference endpoint and your compliance requirement pins you to a Canadian region, verify availability &lt;em&gt;before&lt;/em&gt; you design around it. This is a recurring and entirely avoidable source of late-stage rework.&lt;/p&gt;

&lt;p&gt;A practical mitigation: keep the inference layer behind an interface from day one, so the decision of where a model runs stays swappable. You will likely need to change it at least once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost two: multi-AZ but effectively single-region
&lt;/h2&gt;

&lt;p&gt;Canadian regions have multiple availability zones, so zone-level redundancy is fine. Region-level redundancy is where it gets awkward.&lt;/p&gt;

&lt;p&gt;The usual disaster-recovery pattern is a second region. If your residency requirement is "data must remain in Canada," your second region has to be the other Canadian one — and the pairs are asymmetric. &lt;code&gt;ca-west-1&lt;/code&gt; supports meaningfully fewer services than &lt;code&gt;ca-central-1&lt;/code&gt;. Azure's Canada East is thinner than Canada Central. You cannot assume a symmetric failover target.&lt;/p&gt;

&lt;p&gt;Design consequence: verify service parity across both Canadian regions before you promise anyone an RPO or RTO. A DR plan that depends on a service unavailable in the failover region is not a DR plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost three: latency, mostly fine, occasionally not
&lt;/h2&gt;

&lt;p&gt;Montreal to New York is around 15ms. Toronto to Chicago is similar. For most applications this is invisible.&lt;/p&gt;

&lt;p&gt;Where it stops being invisible is chatty architectures. If a request fans out to eight services with a cross-region hop each, small latencies compound into something users notice. And if your users are in Europe or Asia while your data must sit in Canada, you are looking at a fundamentally different problem — read replicas and edge caching for non-personal data, with the personal data staying put.&lt;/p&gt;

&lt;p&gt;Worth stating plainly: residency constrains &lt;em&gt;where personal data lives&lt;/em&gt;, not where every byte of your application lives. Separating those two things early gives you room to move later. Teams that treat "the whole system must be in Canada" as the requirement build themselves a much tighter box than the regulation actually requires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost four: Quebec's Law 25 is stricter than PIPEDA
&lt;/h2&gt;

&lt;p&gt;PIPEDA is the federal baseline. Quebec's Law 25 goes considerably further, and this catches teams out because Montreal is where a lot of Canadian engineering happens.&lt;/p&gt;

&lt;p&gt;Provisions with direct engineering consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy impact assessments&lt;/strong&gt; before transferring personal information outside Quebec. If your team is in Montreal and your database is in Virginia, that is a transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data portability&lt;/strong&gt; — users can demand their data in a structured, commonly used technical format. Retrofitting a clean export path onto a mature schema is genuinely unpleasant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit consent standards&lt;/strong&gt; that are harder to satisfy with a single blanket toggle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mandatory breach reporting&lt;/strong&gt; with defined timelines, which implies you have the logging and detection to know a breach occurred.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are hard if you design for them. All of them are expensive to add later, particularly portability and erasure, because they touch the data model rather than a service boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one that always hurts: erasure
&lt;/h2&gt;

&lt;p&gt;Right-to-erasure is where I have seen the most retrofit pain, and it is worth thinking about before you have a schema.&lt;/p&gt;

&lt;p&gt;The naive approach is a &lt;code&gt;deleted_at&lt;/code&gt; column. That satisfies nobody once you actually read the requirement, because the data is still there. Real erasure has to reach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary tables and every denormalised copy.&lt;/li&gt;
&lt;li&gt;Analytics warehouses and event streams.&lt;/li&gt;
&lt;li&gt;Search indices.&lt;/li&gt;
&lt;li&gt;Backups — where the usual accepted approach is documented rotation rather than surgical deletion, but you need that documented position.&lt;/li&gt;
&lt;li&gt;Logs, which routinely contain personal data nobody intended to put there.&lt;/li&gt;
&lt;li&gt;Any third-party processor, including AI providers you sent context to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is newer and increasingly relevant. If you pass user content to a model provider, that provider is a sub-processor and belongs in your DPA, your privacy notice, and your erasure story. "We send it to an API" is not an exemption.&lt;/p&gt;

&lt;p&gt;The design that makes this tractable is centralising personal data behind a small number of owning services with clear identifiers, so erasure is a bounded operation rather than a search across the estate. Costs a little upfront, saves an enormous amount later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Confirm every managed service you depend on exists in your target Canadian region — and in the failover region.&lt;/li&gt;
&lt;li&gt;Keep inference and other fast-moving dependencies behind a swappable interface.&lt;/li&gt;
&lt;li&gt;Separate "personal data must be in Canada" from "everything must be in Canada." They are different requirements.&lt;/li&gt;
&lt;li&gt;Build export and erasure paths into the schema, not on top of it.&lt;/li&gt;
&lt;li&gt;Enumerate sub-processors, AI providers included, and get them into the DPA.&lt;/li&gt;
&lt;li&gt;Verify service parity before committing to an RPO or RTO.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full guide to evaluating Canadian development partners — including 2026 rates, vendor archetypes and a contract checklist — is &lt;a href="https://techcirkle.com/blog/software-development-companies-in-canada" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does PIPEDA require my data to be stored in Canada?
&lt;/h3&gt;

&lt;p&gt;No. PIPEDA does not mandate data localisation — it requires comparable protection wherever data goes and transparency about cross-border transfers. Residency requirements usually come from your customers or sector regulators rather than from PIPEDA itself, which is why the requirement often appears in a procurement questionnaire rather than a statute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is ca-central-1 more expensive than us-east-1?
&lt;/h3&gt;

&lt;p&gt;Modestly, typically single-digit to low-double-digit percentage differences depending on service. The larger practical cost is not the line item but service availability lag — newer managed services reach Canadian regions later, which occasionally forces architectural changes you did not budget for.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Quebec's Law 25 differ from PIPEDA in practice?
&lt;/h3&gt;

&lt;p&gt;Law 25 adds mandatory privacy impact assessments before transferring personal information outside Quebec, explicit data portability rights, stricter consent standards, and defined breach reporting timelines. If your engineering team sits in Montreal and handles personal data, it applies to your build regardless of where your company is incorporated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use a US-based AI provider if I have Canadian residency requirements?
&lt;/h3&gt;

&lt;p&gt;Only if your residency obligation permits it, and you must treat the provider as a sub-processor — named in your DPA, disclosed in your privacy notice, and included in your erasure process. Some Canadian public sector and healthcare contracts prohibit this outright, so check the specific obligation rather than assuming.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the most expensive thing to retrofit?
&lt;/h3&gt;

&lt;p&gt;Erasure, followed by data portability. Both touch the data model rather than a single service boundary, which means they reach denormalised copies, analytics warehouses, search indices, logs and third-party processors. Designing personal data behind a small number of owning services from the start makes both bounded operations instead of estate-wide searches.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>compliance</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Vetting a Dev Agency in One Hour: Read Their Pull Requests</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sun, 26 Jul 2026 13:02:59 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/vetting-a-dev-agency-in-one-hour-read-their-pull-requests-7hl</link>
      <guid>https://dev.to/jam-techcirkle/vetting-a-dev-agency-in-one-hour-read-their-pull-requests-7hl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxqk39v6tfkecush2udgj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxqk39v6tfkecush2udgj.jpg" alt="Development team reviewing code together on desktop monitors" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agency evaluations are almost always run backwards. Three hours of pitch deck, case studies, and methodology slides, then twenty minutes at the end with someone technical who asks about the stack.&lt;/p&gt;

&lt;p&gt;Invert it. You can assess engineering capability in about an hour if you ask for artefacts rather than claims, and the artefacts are far harder to fake than a case study written in the passive voice.&lt;/p&gt;

&lt;p&gt;Here is the sequence I would run.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Ask for a real pull request and read the review comments
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fifteen minutes, and it is the highest-signal thing available.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ask them to bring a genuine PR from a recent project — sanitised as needed — and walk you through it, including the review discussion.&lt;/p&gt;

&lt;p&gt;What you learn, none of which appears in a proposal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What their actual standard is&lt;/strong&gt;, versus their stated standard. Everyone claims code review. Not everyone leaves substantive comments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whether reviews are engineering or ceremony.&lt;/strong&gt; "LGTM 👍" on a 600-line diff tells you review is a process gate rather than a quality mechanism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How disagreement is handled.&lt;/strong&gt; A junior pushing back on a senior, and the discussion resolving on technical grounds, is one of the strongest positive signals you can observe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whether they understand code they did not type.&lt;/strong&gt; This is the one that matters most in 2026. There is a substantial difference between an engineer using AI assistance to move faster within a design they hold in their head, and one accepting generated code they cannot fully explain. The second produces a codebase that looks fine at handover and becomes unmaintainable within a year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ask about a specific block: &lt;em&gt;why this approach here?&lt;/em&gt; Confident, specific reasoning is what you want. Vagueness about their own recent code is disqualifying, and it is a much better test of AI-tooling discipline than asking whether they use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Test strategy, with numbers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ten minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"What is your test strategy, and what was coverage on your last three projects?"&lt;/p&gt;

&lt;p&gt;Good answer: specific figures, plus an &lt;em&gt;opinion about what not to test&lt;/em&gt;. Maturity shows up as deliberate omission — "we don't unit-test thin controllers, we cover those at integration level" is the answer of someone who has thought about cost versus value.&lt;/p&gt;

&lt;p&gt;Bad answer: a promise of comprehensive testing with no numbers. That is a sales response, and it usually means coverage is whatever it happened to be.&lt;/p&gt;

&lt;p&gt;Follow-up worth asking: what breaks most often in the first month after a launch, and what did you change in your process because of it? A real answer describes a specific class of bug and a specific process change.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Architecture ownership, by name
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Five minutes, and it settles a question that causes real damage later.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Who makes architecture decisions on my project, and will they still be on it in month six?"&lt;/p&gt;

&lt;p&gt;You want a name, and you want that name in the statement of work with a committed percentage. Senior people in the pitch and different people on the project is the single most common reason agency engagements disappoint, and it is a contracting failure rather than a market condition.&lt;/p&gt;

&lt;p&gt;If they are proposing distributed delivery, the sharper version: &lt;em&gt;where does the person making architecture calls physically sit, and how many hours of overlap will my team have with the engineers writing code?&lt;/em&gt; Four or more hours of overlap with genuine local technical authority works well. An account manager fronting a remote team with no technical decision-maker in your time zone is the arrangement most likely to disappoint, because nobody available to you can actually decide anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The failure question
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ten minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Describe a project that went badly and what you changed afterwards."&lt;/p&gt;

&lt;p&gt;An agency with no bad project has either not done many or is not being straight with you. The useful answers are specific and slightly uncomfortable, and they end in a process change rather than a personnel change.&lt;/p&gt;

&lt;p&gt;Listen for whether the lesson was institutionalised. "We now require X before starting Y" indicates an organisation that learns. "We were unlucky with that client" indicates one that does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Handover, asked early
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Five minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"What does handover look like if we bring this in-house next year?"&lt;/p&gt;

&lt;p&gt;Ask this in the first technical conversation, not during contract negotiation. A good answer covers documentation, runbooks, a transition period, and does not get defensive. Discomfort here is informative — it suggests a commercial model that depends on you not being able to leave.&lt;/p&gt;

&lt;p&gt;Related: who owns the code, the frameworks, and anything embedded in your repository. A licence-back to their internal framework is a dependency wearing the costume of efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Ask what is wrong with your brief
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ten minutes, and the best predictor in the whole process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"What in my brief do you think is wrong?"&lt;/p&gt;

&lt;p&gt;The strongest agencies push back before contract, not after. Total agreement in a first conversation means either nobody is being honest or nobody has read it carefully, and in both cases the disagreement is merely deferred to a point where it costs money.&lt;/p&gt;

&lt;p&gt;I have never regretted hiring the team that challenged the brief. I have regretted the pleasant meetings.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. AI tooling boundaries
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Five minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"How do you use AI tooling in delivery, and what do you not use it for?"&lt;/p&gt;

&lt;p&gt;You want a considered boundary. Not enthusiasm — "we use it for everything" describes a team that has not yet been burned. Not prohibition — that is a team declining a real productivity improvement and charging you for the difference.&lt;/p&gt;

&lt;p&gt;Good answers distinguish implementation from judgement: fast on scaffolding, integration code, test fixtures, migrations; deliberate and human on data model design, security boundaries, and anything where the failure mode is silent.&lt;/p&gt;

&lt;h2&gt;
  
  
  References: two questions only
&lt;/h2&gt;

&lt;p&gt;When you take references, most of the value is in two questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Did the estimates hold?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Did the team in month six match the team in the pitch?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second one surfaces more than any amount of case-study reading, because it tests the failure mode that no amount of technical assessment can detect in advance.&lt;/p&gt;

&lt;p&gt;Full guide with 2026 UK rate tables, IR35 context, compliance requirements, and a six-week selection process: &lt;a href="https://techcirkle.com/blog/software-development-agency-uk" rel="noopener noreferrer"&gt;Software Development Agency UK: How to Choose the Right One in 2026&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are on the other side of these conversations regularly at TechCirkle — &lt;a href="https://techcirkle.com/development/custom-software-development" rel="noopener noreferrer"&gt;custom software development&lt;/a&gt; and &lt;a href="https://techcirkle.com/app-development-uk" rel="noopener noreferrer"&gt;app development in the UK&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feegz3em61ozzvlynnxx4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feegz3em61ozzvlynnxx4.jpg" alt="Two business teams shaking hands after successfully negotiating a software development contract" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the single most useful thing to ask an agency for?
&lt;/h3&gt;

&lt;p&gt;A real pull request from a recent project, walked through including the review comments. It reveals their actual code review standard, whether review is engineering or ceremony, how technical disagreement is handled, and — most importantly now — whether engineers genuinely understand code they did not type themselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can I tell if an agency uses AI tooling responsibly?
&lt;/h3&gt;

&lt;p&gt;Ask them to explain a specific block in their own recent pull request. Confident, specific reasoning about why that approach was chosen indicates a team using assistance within a design they hold; vagueness about their own recent code indicates accepted output they cannot explain, which produces codebases that look fine at handover and degrade within a year.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does a good answer about test strategy sound like?
&lt;/h3&gt;

&lt;p&gt;Specific coverage figures for recent projects plus an opinion about what deliberately is not tested — for example covering thin controllers at integration level rather than with unit tests. A promise of comprehensive testing with no numbers is a sales answer and usually means coverage is whatever it happened to be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why insist on named architecture ownership?
&lt;/h3&gt;

&lt;p&gt;Because senior staff in the pitch and different staff on the project is the most common reason these engagements disappoint, and it is a contracting failure rather than a market condition. Get the name in the statement of work with a committed percentage and a right to reject substitutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I evaluate a distributed or offshore delivery model?
&lt;/h3&gt;

&lt;p&gt;Ask where the person making architecture decisions physically sits and how many hours of overlap your team will have with the engineers writing code. Four or more hours with genuine local technical authority works well. An account manager fronting a remote team with no local decision-maker means nobody available to you can actually decide anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I be concerned if an agency agrees with everything in my brief?
&lt;/h3&gt;

&lt;p&gt;Yes. It means either nobody is being candid or nobody has read it closely, and the disagreement resurfaces later when it costs money. Asking what they think is wrong with your brief is the best single predictor in the process — the teams that challenge it are consistently the better hires.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I ask about handover and IP?
&lt;/h3&gt;

&lt;p&gt;In the first technical conversation, not during contract negotiation. Good answers cover documentation, runbooks, and a transition period without defensiveness. Watch specifically for a licence-back to their internal framework rather than full assignment, which creates a dependency presented as efficiency.&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>hiring</category>
      <category>codereview</category>
      <category>management</category>
    </item>
    <item>
      <title>Building the Escalation Gate — The Hard Part of Agentic Workflows</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sun, 26 Jul 2026 12:57:55 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/building-the-escalation-gate-the-hard-part-of-agentic-workflows-5a3h</link>
      <guid>https://dev.to/jam-techcirkle/building-the-escalation-gate-the-hard-part-of-agentic-workflows-5a3h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9awh4dp9xpbxjnd3m300.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9awh4dp9xpbxjnd3m300.jpg" alt="Engineering view of automated business process flows and data routing" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have built one of these for production, you already know the ratio. Getting a model to draft a plausible response to a support ticket, code an invoice, or classify a document takes an afternoon. Getting it to production takes months, and almost none of that time goes into the part that looked like the product.&lt;/p&gt;

&lt;p&gt;It goes into two components that never appear in a demo: the gate that decides whether output ships or escalates, and the audit trail that lets you explain the decision six months later.&lt;/p&gt;

&lt;p&gt;This is a note on building the first one properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the gate actually is
&lt;/h2&gt;

&lt;p&gt;A useful agentic workflow has four properties: a defined input trigger, a bounded set of permitted actions against real systems, a &lt;strong&gt;validation gate&lt;/strong&gt; deciding whether output ships or escalates, and a complete record of every decision and tool call.&lt;/p&gt;

&lt;p&gt;The gate is not a confidence threshold on a model score. That is the naive version, and it fails for a specific reason: token-level probabilities are not calibrated to task correctness. A model can be extremely confident and wrong, particularly on inputs that resemble its training distribution but differ in a business-critical detail — the deviation in clause 14, the account flagged as enterprise, the code combination that is valid but unusual.&lt;/p&gt;

&lt;p&gt;A gate that works is a composition of cheap independent checks, most of which are not model calls at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;verdict = ship
  if structural_valid(output)          # schema, required fields, referential integrity
  and within_policy_bounds(output)     # amount ceilings, permitted action set, blast radius
  and consistent_with_source(output)   # every claimed fact traceable to retrieved input
  and not matches_escalation_rule(input)  # explicit carve-outs: VIP, legal hold, dispute
  and self_check_passed(output)        # a second model call, adversarially prompted
  else escalate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ordering matters for cost. Put the deterministic checks first — they are free and they catch the majority of genuine failures. The model-based self-check goes last, on the minority of cases that survive, because it roughly doubles your per-transaction inference cost when it runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicit carve-outs beat clever thresholds
&lt;/h2&gt;

&lt;p&gt;The single highest-value component is the boring one: &lt;code&gt;matches_escalation_rule&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A hand-maintained list of conditions that always route to a human regardless of how confident everything else is. Disputed accounts. Anything with a legal hold. Amounts above a ceiling. Customers flagged as sensitive. Any input where a prior attempt was overturned.&lt;/p&gt;

&lt;p&gt;This list is where domain expertise actually enters the system, and it is the thing your business owner should own directly and be able to edit without a deployment. Every incident post-mortem adds a line to it. It grows for the first six months and then stabilises, and its growth curve is a decent proxy for how well you understood the process at the start.&lt;/p&gt;

&lt;p&gt;The temptation is to replace it with a smarter model. Resist that. A rule you can read, test, and explain in an audit is worth more than a marginal accuracy gain you cannot account for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tune the threshold with evidence, not judgement
&lt;/h2&gt;

&lt;p&gt;Ship with the gate deliberately too conservative. Escalate most cases in week one. This feels like failure and is not — it is how you collect the labelled data that lets you tune honestly.&lt;/p&gt;

&lt;p&gt;Every escalation produces a human decision. Log the pair: what the system would have done, what the human actually did. After a few thousand pairs you can compute, for any candidate threshold, the agreement rate and the cost of the disagreements. Now the tuning decision is empirical rather than a product manager's intuition.&lt;/p&gt;

&lt;p&gt;Two things to watch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The two error types are not symmetrically expensive.&lt;/strong&gt; A false escalation costs you a few minutes of human time. A false ship can cost a customer relationship or a regulatory finding. Tune for the asymmetry explicitly rather than optimising a single accuracy number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Week one and month three differ substantially.&lt;/strong&gt; Resolution rate rises as you fix the failure modes the escalations reveal. Anyone quoting a single accuracy figure for a production system without specifying when it was measured has not watched one mature.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The audit trail is a product requirement, not logging
&lt;/h2&gt;

&lt;p&gt;For each transaction, persist: the input, everything retrieved, the full prompt, the raw output, every gate check with its result, the final verdict, and — for escalations — the human decision. Keyed to the business record, queryable, retained per your policy.&lt;/p&gt;

&lt;p&gt;Two reasons this cannot be deferred. First, when a workflow misbehaves at 2am, an engineer needs to reconstruct exactly what the system saw and why it decided as it did. Application logs will not do it. Second, in any regulated context you will eventually be asked to explain a specific decision about a specific person, possibly a year later, and the answer needs to be evidence rather than a description of your architecture.&lt;/p&gt;

&lt;p&gt;Retrofitting this after go-live is one of the more expensive mistakes available, because the interesting transactions are already gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evals, or every change is an uncontrolled experiment
&lt;/h2&gt;

&lt;p&gt;You need a regression suite of real cases with expected outcomes, run on every prompt change, model change, and retrieval change.&lt;/p&gt;

&lt;p&gt;Not synthetic cases. Real transactions with known correct outcomes, including every case that has ever failed in production — each incident should add a permanent test. Fifty well-chosen cases beat five hundred generated ones, because the value is in covering the failure modes you have actually encountered.&lt;/p&gt;

&lt;p&gt;Without this, a provider deprecating a model version becomes a production emergency instead of a Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflows worth building first
&lt;/h2&gt;

&lt;p&gt;Not every process is a good candidate, and the profile is fairly specific:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High volume, moderate complexity&lt;/strong&gt; — thousands per month, each currently five to forty minutes of human time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verifiable ground truth&lt;/strong&gt; — you can tell afterwards whether it was right, which is what makes measurement and improvement possible at all&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An existing escalation path&lt;/strong&gt; — someone already handles exceptions; you are not inventing that capability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured or semi-structured input&lt;/strong&gt; — documents, tickets, forms against a known schema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A measurable current cost per unit&lt;/strong&gt;, so the savings claim is arithmetic rather than narrative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything failing this profile should be later in the roadmap, however strategically important it feels. You cannot tune a gate without a safe failure mode, and you cannot measure improvement without volume.&lt;/p&gt;

&lt;p&gt;Full writeup, including 2026 US cost benchmarks and the compliance constraints that shape all of this: &lt;a href="https://techcirkle.com/blog/digital-transformation-company-usa" rel="noopener noreferrer"&gt;Digital Transformation Company in USA: How to Choose the Right Partner in 2026&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We build these systems at TechCirkle — &lt;a href="https://techcirkle.com/agentic-workflow-development" rel="noopener noreferrer"&gt;agentic workflow development&lt;/a&gt; and &lt;a href="https://techcirkle.com/llm-integration" rel="noopener noreferrer"&gt;LLM integration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42avxtboii827cfyrqh4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42avxtboii827cfyrqh4.jpg" alt="Workflow automation flowchart showing process hierarchy and decision routing" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is an escalation gate in an agentic workflow?
&lt;/h3&gt;

&lt;p&gt;It is the component deciding whether the system acts on its own output or routes the case to a human. Practically it is a composition of cheap deterministic checks — schema validity, policy bounds, source consistency, explicit carve-out rules — with an optional model-based self-check last. It is not simply a confidence threshold, because token probabilities are not calibrated to task correctness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why shouldn't I use model confidence scores as the gate?
&lt;/h3&gt;

&lt;p&gt;Because a model can be highly confident and wrong, especially on inputs that closely resemble its training distribution but differ in a business-critical detail. Confidence measures fluency, not correctness. Deterministic checks against schema, policy limits, and traceability to retrieved source catch a far higher share of real failures at zero inference cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I choose the right confidence threshold?
&lt;/h3&gt;

&lt;p&gt;Ship deliberately conservative so most cases escalate, then log every pair of what the system would have done and what the human actually did. After a few thousand pairs you can compute agreement rate and disagreement cost for any candidate threshold. Tune for the asymmetry between error types — a false escalation costs minutes, a false ship can cost a customer or a regulatory finding.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should an audit trail for an LLM workflow contain?
&lt;/h3&gt;

&lt;p&gt;The input, everything retrieved, the full prompt, raw output, every gate check with its result, the final verdict, and the human decision for escalated cases — all keyed to the business record and queryable. This is a product requirement rather than logging, because debugging a 2am failure and explaining a specific decision a year later both need evidence rather than an architecture description.&lt;/p&gt;

&lt;h3&gt;
  
  
  How many eval cases do I need?
&lt;/h3&gt;

&lt;p&gt;Fifty well-chosen real cases beat five hundred synthetic ones. Use actual transactions with known correct outcomes, and make every production incident add a permanent test case. The purpose is covering failure modes you have genuinely encountered, so that a model deprecation or prompt change becomes a routine regression run rather than an emergency.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does the self-check step add to cost?
&lt;/h3&gt;

&lt;p&gt;Roughly double the per-transaction inference cost on the cases where it runs, which is why it belongs last in the chain — after the free deterministic checks have already filtered most of the traffic. Ordering the gate by cost rather than by conceptual tidiness is one of the easier optimisations available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which processes make good first candidates for agentic automation?
&lt;/h3&gt;

&lt;p&gt;High volume with moderate complexity, verifiable ground truth after the fact, an escalation path that already exists, structured or semi-structured inputs, and a current cost per unit you can already measure. Support triage, invoice coding, and document classification usually qualify. Low-volume, high-stakes processes with no existing exception path should come much later.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>architecture</category>
      <category>observability</category>
    </item>
    <item>
      <title>HIPAA + AI: A Developer's Guide to Compliant US Healthcare Software</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sat, 25 Jul 2026 07:58:58 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/hipaa-ai-a-developers-guide-to-compliant-us-healthcare-software-4h0n</link>
      <guid>https://dev.to/jam-techcirkle/hipaa-ai-a-developers-guide-to-compliant-us-healthcare-software-4h0n</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu49j9o1l5mob660144z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feu49j9o1l5mob660144z.jpg" alt="Clinician using healthcare software" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are an engineer shipping features into a US healthcare product in 2026, the interesting problem is no longer "can we call an LLM." You can. The interesting problem is that the moment a prompt contains protected health information, you have created a HIPAA disclosure event, and most of the mistakes I see are made by good developers who did not realize the compliance boundary moved into their request payload.&lt;/p&gt;

&lt;p&gt;This is a practical guide to building AI features that survive a compliance review, written for the people who actually write the code. The regulatory language is real, but the takeaways are concrete: what to put in your architecture, what to keep out of your prompts, and where the audit trail has to exist before anyone asks for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The compliance stack, from a developer's seat
&lt;/h2&gt;

&lt;p&gt;Before the AI part, get the substrate right. HIPAA is the floor and it is architectural, not a checkbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BAA&lt;/strong&gt; — a Business Associate Agreement is required with anyone who touches PHI on your behalf, including your cloud and, critically, your model provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption&lt;/strong&gt; at rest and in transit, non-negotiable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access controls&lt;/strong&gt; — least privilege, real RBAC, no shared service accounts reading full patient records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit logging&lt;/strong&gt; — who accessed what, when, and why, in a form you can hand to an auditor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documented risk analysis&lt;/strong&gt; under the Privacy, Security, and Breach Notification Rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Layered on top: HITECH raises breach and enforcement stakes, PCI DSS applies if you process payments, and 42 CFR Part 2 governs substance-use records with stricter consent rules than standard PHI. Know which of these your feature touches before you design it, not after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why your LLM call is a disclosure
&lt;/h2&gt;

&lt;p&gt;Here is the mental model that prevents the most expensive mistake. When your service sends a chart snippet to a third-party model API, you are disclosing PHI to a business associate. That is not a metaphor — it is the legal characterization, and it has three direct engineering consequences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model provider needs a signed BAA with you. No BAA, no PHI in the prompt, full stop.&lt;/li&gt;
&lt;li&gt;Your architecture should minimize what leaves your environment — send the least data that makes the feature work, and de-identify or tokenize where the use case allows.&lt;/li&gt;
&lt;li&gt;For the most sensitive workloads, keep the model inside your boundary: a private endpoint, a VPC-scoped deployment, or an on-premise model rather than a public API.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A useful rule of thumb: treat every field in a prompt as if it will appear in a breach-notification letter, because if the disclosure was unlawful, functionally it will.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozrambn0yzb34vuscmmi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozrambn0yzb34vuscmmi.jpg" alt="Healthcare data on a tablet" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  De-identification and the drafts-vs-decides line
&lt;/h2&gt;

&lt;p&gt;Two techniques do most of the safety work. The first is de-identification before inference — strip or tokenize identifiers so the model reasons over the clinically relevant content without receiving a re-identifiable record. Reversible tokenization lets you re-attach identity inside your trusted boundary after the model returns. It is not always possible (some tasks need the identifiers), but when it is, it shrinks your disclosure surface dramatically.&lt;/p&gt;

&lt;p&gt;The second is a hard architectural distinction between &lt;strong&gt;AI that drafts&lt;/strong&gt; and &lt;strong&gt;AI that decides&lt;/strong&gt;. Drafting — ambient documentation composing a note from the visit transcript, a coding assistant proposing ICD codes, a denial-appeal generator writing a first draft — is safe &lt;em&gt;when a human reviews before anything is committed&lt;/em&gt;. Deciding — an autonomous action that alters care or submits a claim with no human in the loop — is a different risk class and must be tightly bounded or avoided. Encode this in the system, not the docs: drafts land in a review queue with an explicit human approval step, and nothing an AI produced touches a care or billing workflow without that gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three AI use cases that are actually in production
&lt;/h2&gt;

&lt;p&gt;To be concrete about what "healthcare AI in 2026" means in shipped systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ambient documentation&lt;/strong&gt; — a model drafts the clinical note from the visit conversation, measurably cutting the documentation burden that drives clinician burnout. Human review before sign-off is the safety mechanism.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated coding and prior authorization&lt;/strong&gt; — language models read charts against payer rules to accelerate administrative cycles that used to take days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Denial management&lt;/strong&gt; — models predict, prevent, and draft appeals for claim denials at a scale human teams can't match, which is where a lot of current RCM ROI lives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of these works because it is a drafting task with a human gate, not an autonomous decision. That pattern is the template.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit trails, FHIR, and drift
&lt;/h2&gt;

&lt;p&gt;Three things you will regret not building early. First, &lt;strong&gt;AI audit trails&lt;/strong&gt;: log the input (or a de-identified reference to it), the model and version, the output, and the human decision on it. When a regulator or a clinician asks "why did the system produce this," "the model said so" is not an answer — the trail is.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;FHIR integration&lt;/strong&gt;. Interoperability is now a compliance concern, not just a technical nicety; ONC rules and information-blocking provisions expect standardized API exchange, and FHIR (alongside legacy HL7 v2) is the lingua franca. Budget for it as real work — EHR integrations carry authentication quirks, uneven endpoint quality, and partner-program approval cycles that add calendar time.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;model monitoring for drift&lt;/strong&gt;. A model accurate on launch-day data degrades as the real-world distribution shifts — denial patterns move, guidelines change, payer rules update quarterly. Production healthcare AI needs monitoring for accuracy, bias, and hallucination, plus revalidation and a human-review loop that stays funded after launch excitement fades.&lt;/p&gt;

&lt;h2&gt;
  
  
  The build-team takeaway
&lt;/h2&gt;

&lt;p&gt;Compliant AI in US healthcare is not a heroic effort; it is a set of defaults you set once and enforce everywhere: BAA before any PHI leaves your boundary, minimize and de-identify in the prompt, a mandatory human gate between AI output and any care or billing action, and an audit trail plus drift monitoring that outlives go-live. Teams that internalize these ship fast and pass review. Teams that bolt AI on afterward fund the education plus the risk.&lt;/p&gt;

&lt;p&gt;If you are scoping this for a real product, TechCirkle's guide to choosing a &lt;a href="https://techcirkle.com/blog/custom-healthcare-software-development-company-usa" rel="noopener noreferrer"&gt;custom healthcare software development company in the USA&lt;/a&gt; covers vendor-level governance, our &lt;a href="https://techcirkle.com/ai-development-services" rel="noopener noreferrer"&gt;AI development services&lt;/a&gt; page goes deeper on regulated model deployment, and you can always &lt;a href="https://techcirkle.com/contact-us" rel="noopener noreferrer"&gt;talk to our engineers&lt;/a&gt; about a specific architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can I send PHI to a commercial LLM API?
&lt;/h3&gt;

&lt;p&gt;Only if that provider has signed a BAA with you and the API is configured for HIPAA-eligible use — and even then, minimize what you send. Many teams de-identify or tokenize identifiers before inference and re-attach identity inside their trusted boundary afterward. Without a BAA, PHI must never appear in a prompt to that provider; treat it the way you would treat writing the data to an unencrypted public log.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between de-identification and tokenization here?
&lt;/h3&gt;

&lt;p&gt;De-identification removes or generalizes identifiers so the record can't reasonably be tied back to a person. Tokenization replaces identifiers with reversible tokens you can resolve only inside your trusted environment, so the model reasons over clinical content while identity stays behind your boundary. Tokenization is useful when you need to re-attach identity after inference; full de-identification is stronger when the task never needs the identifiers at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does the "drafts vs decides" distinction matter so much?
&lt;/h3&gt;

&lt;p&gt;Because it maps directly to risk class. AI that drafts — notes, codes, appeal letters — is safe when a human reviews before anything is committed, so you build a mandatory approval gate into the workflow. AI that autonomously decides or acts on care or billing without a human is a far higher-risk class that must be tightly bounded or avoided. Encoding the gate in the system, not just the documentation, is what makes the feature defensible.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much of an audit trail do AI features actually need?
&lt;/h3&gt;

&lt;p&gt;Enough to answer "why did the system produce this output" after the fact. In practice that means logging the model and version, the input (or a de-identified reference), the generated output, and the human decision applied to it. Regulators and clinicians will eventually ask, and a complete trail is the difference between a routine explanation and an incident. Build it from day one — retrofitting logging onto a live PHI system is painful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is FHIR really a compliance issue or just a technical one?
&lt;/h3&gt;

&lt;p&gt;Both. Technically it's how modern healthcare systems exchange data; legally, ONC rules and information-blocking provisions expect standardized API exchange, so software that can't interoperate can create regulatory exposure on top of being a stranded island. Budget FHIR and EHR integration as substantial work — authentication, data mapping, uneven endpoints, and EHR partner-program approval cycles routinely dominate a healthcare project's timeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  What breaks after go-live that I should plan for?
&lt;/h3&gt;

&lt;p&gt;Model drift and validation drift. A model accurate at launch degrades as denial patterns, clinical guidelines, and payer rules shift, and EHR upgrades can silently break integrations. Plan for continuous monitoring of accuracy, bias, and hallucination, scheduled revalidation, and a human-review loop that stays funded. In healthcare, the maintenance and oversight work isn't optional polish — it's what keeps the system safe and compliant over its life.&lt;/p&gt;

</description>
      <category>healthcaresoftware</category>
      <category>hipaa</category>
      <category>customsoftware</category>
      <category>usa</category>
    </item>
    <item>
      <title>A Technical Due-Diligence Checklist for a Dubai App Development Company</title>
      <dc:creator>James Sanderson</dc:creator>
      <pubDate>Sat, 25 Jul 2026 07:54:48 +0000</pubDate>
      <link>https://dev.to/jam-techcirkle/a-technical-due-diligence-checklist-for-a-dubai-app-development-company-4g62</link>
      <guid>https://dev.to/jam-techcirkle/a-technical-due-diligence-checklist-for-a-dubai-app-development-company-4g62</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u8nw8sbjikgzs448a4u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u8nw8sbjikgzs448a4u.jpg" alt="Dubai skyline" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are the engineer in the room when your company shortlists an &lt;strong&gt;app development company in Dubai&lt;/strong&gt;, your job is not to be impressed by the portfolio. Your job is to find the failure modes before they cost six figures in AED. Sales decks are optimized to survive exactly the questions non-technical buyers ask, which is why the useful due diligence starts where the deck ends. This is the checklist I'd run — grouped by what it actually protects.&lt;/p&gt;

&lt;p&gt;One framing note before the list. The biggest shift in this evaluation since 2023 is AI. A large share of what a modern app does — in-app assistants, natural-language search, document understanding, personalization — now ships by integrating a foundation model rather than being hand-built. That collapses the cost of some features and moves engineering effort into data pipelines, evaluation, and guardrails. So half of due diligence in 2026 is checking whether a Dubai firm understands that shift, and half is the timeless stuff: QA, IP, security, and who actually writes your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Verify the code, not the case study
&lt;/h2&gt;

&lt;p&gt;Portfolios are curated; shipped software is not. Make the firm prove delivery you can independently inspect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get live App Store and Google Play links to apps they built, then check ratings, recent review sentiment, and update cadence yourself. An app last updated in 2022 is telling you something.&lt;/li&gt;
&lt;li&gt;Ask for a reference call with a client whose project matches yours in size and domain — and ask that client specifically what went wrong and how the firm handled it.&lt;/li&gt;
&lt;li&gt;Request a redacted architecture diagram from a past build. Fluency here is hard to fake; hand-waving is easy to spot.&lt;/li&gt;
&lt;li&gt;Confirm which legal entity signs the contract and where the engineers physically sit. "Dubai firm" can mean a local studio, a blended UAE-plus-offshore team, or a phone number in front of pure offshore delivery — all valid, but you must know which.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Interrogate the QA and release pipeline
&lt;/h2&gt;

&lt;p&gt;This is where cut corners hide, because testing is invisible until it isn't.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have them walk you through automated testing, device-matrix coverage, TestFlight and staged rollouts, and crash and performance monitoring. Vague answers here predict buggy launches.&lt;/li&gt;
&lt;li&gt;Ask how they handle phased rollouts and rollback when a release regresses in production.&lt;/li&gt;
&lt;li&gt;Ask what their crash-free-session target is and how they measure it. A real number signals a real process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwu13oa621i7ajaxg95x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwu13oa621i7ajaxg95x.jpg" alt="App development team" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Pressure-test AI capability with a scenario
&lt;/h2&gt;

&lt;p&gt;Do not accept "we use AI" as an answer. Give them a concrete problem and listen to the shape of the response.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pose a specific scenario: "How would you add an Arabic-and-English in-app support assistant?" A capable team talks about retrieval, evaluation harnesses, hallucination and latency measurement, fallbacks for when the model is wrong, and cost control. A weak one says "we'll use ChatGPT."&lt;/li&gt;
&lt;li&gt;Ask which features they'd deliver with a model versus build traditionally, and why. The reasoning matters more than the answer.&lt;/li&gt;
&lt;li&gt;Ask to install a live app they shipped with AI inside it. Working software beats a slide titled "AI Capabilities" every time.&lt;/li&gt;
&lt;li&gt;Confirm they treat prompts and retrieval as versioned, tested assets — not strings pasted into a config once and forgotten.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Nail down data protection and cross-border flow
&lt;/h2&gt;

&lt;p&gt;The UAE is not a compliance-light market, and this is where offshore-only teams most often stumble.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm they understand the UAE Personal Data Protection Law (PDPL): consent, purpose limitation, and cross-border transfer obligations.&lt;/li&gt;
&lt;li&gt;Ask specifically how AI features stay compliant. The instant user content goes to a third-party model provider, you have a cross-border data flow and a processor relationship the PDPL cares about. The right answer includes data minimization before anything leaves your environment, regional model endpoints where available, and records of what is processed where.&lt;/li&gt;
&lt;li&gt;For fintech or health apps, confirm awareness of the additional Central Bank, DFSA/ADGM, or health-data obligations layered on top.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Lock ownership and continuity in writing
&lt;/h2&gt;

&lt;p&gt;Two contract terms protect you more than any SLA.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm unconditional source-code and IP ownership, with handover written in so you can leave with the full repository at any time. Resistance here is a walk-away signal.&lt;/li&gt;
&lt;li&gt;Meet the actual engineers and product manager assigned to your account — not just the sales lead — and get commitment that they won't be reassigned to a bigger client mid-build. Team continuity is the strongest predictor of a smooth delivery.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Sanity-check the AED budget
&lt;/h2&gt;

&lt;p&gt;Use market ranges to spot both padding and dangerous discounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A polished single-platform MVP typically runs AED 90,000 to AED 250,000; a full cross-platform consumer app AED 250,000 to AED 600,000; enterprise or regulated builds beyond AED 600,000, usually as an ongoing engagement.&lt;/li&gt;
&lt;li&gt;If a quote sits ~60% under the others, find what was removed — it is almost always QA, security review, or senior oversight.&lt;/li&gt;
&lt;li&gt;If intelligent features are still priced like bespoke research projects, the firm hasn't updated its cost model for AI. That's padding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Insist on a paid discovery sprint before the main build. A short, well-run discovery produces a clickable prototype, a technical architecture, and a realistic estimate — the cheapest insurance against a six-figure misunderstanding. For the full buyer-side framework, TechCirkle's guide to choosing an &lt;a href="https://techcirkle.com/blog/app-development-company-dubai" rel="noopener noreferrer"&gt;app development company in Dubai&lt;/a&gt; is a solid reference, alongside their &lt;a href="https://techcirkle.com/development/mobile-app-development" rel="noopener noreferrer"&gt;mobile app development&lt;/a&gt; and &lt;a href="https://techcirkle.com/ai-development-services" rel="noopener noreferrer"&gt;AI development services&lt;/a&gt; pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's the single most revealing due-diligence question?
&lt;/h3&gt;

&lt;p&gt;"Show me a live app you built with AI inside it, and walk me through how you made it reliable." It forces the firm off marketing language and onto engineering specifics — retrieval, evaluation, guardrails, fallbacks, cost. Teams that can answer have shipped real AI; teams performing AI theater can't produce the installable proof.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I check QA capability without seeing their code?
&lt;/h3&gt;

&lt;p&gt;Ask process questions with numeric answers: crash-free-session target, device-matrix coverage, staged-rollout and rollback strategy, and how they monitor performance in production. Firms with mature pipelines give concrete figures and named tools; firms without one deflect to reassurances. The specificity of the answer is the signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the PDPL really affect AI features?
&lt;/h3&gt;

&lt;p&gt;Yes, directly. Sending user content to a third-party model provider creates a cross-border data flow and a processor relationship the UAE Personal Data Protection Law governs. A capable Dubai team designs for it: minimize data before it leaves your environment, prefer regional model endpoints, and keep records of what is processed where. Treat "we hadn't considered that" as a red flag.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why insist on source-code ownership in the contract?
&lt;/h3&gt;

&lt;p&gt;Because it's your leverage. Unconditional ownership of the repository and IP, with handover written in, lets you change vendors, pass technical due diligence for funding, or exit a bad engagement without rebuilding from scratch. A firm that resists or obscures this is prioritizing lock-in over your interests, regardless of price.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I use AED ranges during vetting?
&lt;/h3&gt;

&lt;p&gt;As a two-sided filter. A quote far above the AED 90k–600k+ bands may be padding — especially if intelligent features are priced as bespoke research rather than model integrations. A quote far below usually means QA, security review, or senior oversight was quietly cut. Normalize scope across bids before comparing totals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a paid discovery sprint worth it?
&lt;/h3&gt;

&lt;p&gt;Almost always. A short, well-run discovery yields a clickable prototype, a real architecture, and a defensible estimate before you commit the main budget. It surfaces misunderstandings while they're cheap to fix. Vendors who push for a fixed all-in quote with no discovery are optimizing to sign you, not to ship you.&lt;/p&gt;

</description>
      <category>appdevelopment</category>
      <category>dubai</category>
      <category>uae</category>
      <category>mobileapps</category>
    </item>
  </channel>
</rss>
