<?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: Dmytro Nasyrov</title>
    <description>The latest articles on DEV Community by Dmytro Nasyrov (@dmytronasyrov).</description>
    <link>https://dev.to/dmytronasyrov</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%2F140475%2F9927d920-3e1f-416a-bede-35b832d27c5c.png</url>
      <title>DEV Community: Dmytro Nasyrov</title>
      <link>https://dev.to/dmytronasyrov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmytronasyrov"/>
    <language>en</language>
    <item>
      <title>Top 5 LLM Evaluation Frameworks for Release Engineering in 2026</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Thu, 27 Aug 2026 16:32:58 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/top-5-llm-evaluation-frameworks-for-release-engineering-in-2026-4mfh</link>
      <guid>https://dev.to/dmytronasyrov/top-5-llm-evaluation-frameworks-for-release-engineering-in-2026-4mfh</guid>
      <description>&lt;p&gt;Choosing an LLM evaluation framework for release engineering is not a contest for the longest metrics catalog. The practical question is whether a tool can bind results to an exact model, prompt, dataset and application revision, then turn a failed requirement into a blocked release.&lt;/p&gt;

&lt;p&gt;Under that test, Promptfoo is the strongest CI-native option, DeepEval fits Python test suites, LangSmith leads when managed traces and experiment history matter, OpenAI Evals is useful for reusable eval specifications, and Ragas is the specialist for RAG quality. None replaces deployment controls. The ranking below uses official documentation verified on August 27, 2026.&lt;/p&gt;

&lt;p&gt;The rubric comes from the release criteria we use in &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;production AI engineering at Pharos Production&lt;/a&gt;, so Pharos is the evaluator here, not a sixth framework in the ranking.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the five frameworks were ranked
&lt;/h2&gt;

&lt;p&gt;Every alternative had to support repeatable evaluation against a versioned dataset and some form of custom evaluator. I then compared the five on the same release-engineering questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What does a regression run compare?&lt;/li&gt;
&lt;li&gt;Can a team encode deterministic checks and LLM-as-a-judge criteria?&lt;/li&gt;
&lt;li&gt;How does a failure reach CI/CD?&lt;/li&gt;
&lt;li&gt;Can the result be traced to a pull request or candidate build?&lt;/li&gt;
&lt;li&gt;What operating constraint makes the tool a poor fit?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Release-gate readiness has three meanings in this article. &lt;strong&gt;Native&lt;/strong&gt; means the official workflow documents a failing test or build path. &lt;strong&gt;Composable&lt;/strong&gt; means test hooks exist but the team writes the blocking policy. &lt;strong&gt;External&lt;/strong&gt; means the framework creates evidence while another system must own the block.&lt;/p&gt;

&lt;p&gt;This is a release-engineering ranking, not a popularity ranking. A team optimizing a research benchmark, a RAG pipeline or a Python library can rationally choose a different order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;th&gt;Regression unit&lt;/th&gt;
&lt;th&gt;Custom evaluators&lt;/th&gt;
&lt;th&gt;CI/blocking path&lt;/th&gt;
&lt;th&gt;Traceability evidence&lt;/th&gt;
&lt;th&gt;Main constraint&lt;/th&gt;
&lt;th&gt;Disqualifier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. Promptfoo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CI-native prompt, model and security regression&lt;/td&gt;
&lt;td&gt;baseline versus candidate configuration and test cases&lt;/td&gt;
&lt;td&gt;deterministic assertions, JavaScript/Python hooks, semantic and model-graded checks&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Native:&lt;/strong&gt; failed tests or pass-rate threshold can return a failing process status&lt;/td&gt;
&lt;td&gt;tags for Git SHA or CI run; JSON, HTML and JUnit output&lt;/td&gt;
&lt;td&gt;Node-based CLI and provider credentials&lt;/td&gt;
&lt;td&gt;reject when the team will not maintain declarative eval configuration in CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. DeepEval&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python and pytest-based LLM regression testing&lt;/td&gt;
&lt;td&gt;test case plus metric threshold, run as a pytest-style suite&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;BaseMetric&lt;/code&gt;, GEval and built-in task metrics&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Native:&lt;/strong&gt; &lt;code&gt;assert_test&lt;/code&gt; and &lt;code&gt;deepeval test run&lt;/code&gt; can fail a build&lt;/td&gt;
&lt;td&gt;local test output; shared reports and official baselines through Confident AI&lt;/td&gt;
&lt;td&gt;judge credentials; hosted history needs an additional service account&lt;/td&gt;
&lt;td&gt;reject when the release stack is not Python-oriented and cannot host pytest-style tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. LangSmith&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;managed experiments tied to traces and application components&lt;/td&gt;
&lt;td&gt;dataset experiment, including intermediate trace steps&lt;/td&gt;
&lt;td&gt;custom code evaluators and LLM evaluators&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Composable:&lt;/strong&gt; pytest/Jest hooks exist; the team owns the release policy&lt;/td&gt;
&lt;td&gt;datasets, experiment metadata, traces, comparisons and exports&lt;/td&gt;
&lt;td&gt;managed platform dependency and explicit policy glue&lt;/td&gt;
&lt;td&gt;reject when evaluation data or traces cannot be sent to the managed service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4. OpenAI Evals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;reusable eval specifications and benchmark-registry workflows&lt;/td&gt;
&lt;td&gt;JSONL samples plus an eval definition and completion function&lt;/td&gt;
&lt;td&gt;templates and custom eval classes&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;External:&lt;/strong&gt; run the eval in CI, then add your own threshold and evidence binding&lt;/td&gt;
&lt;td&gt;run artifacts depend on the wrapper and logging setup&lt;/td&gt;
&lt;td&gt;OpenAI API cost/key; some solver interfaces are beta&lt;/td&gt;
&lt;td&gt;reject when a turnkey pull-request gate and release ledger are required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5. Ragas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RAG evaluation metrics and experiment comparison&lt;/td&gt;
&lt;td&gt;RAG or agent dataset run, optionally compared with a baseline experiment&lt;/td&gt;
&lt;td&gt;discrete and numerical metrics plus specialized RAG metrics&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;External:&lt;/strong&gt; CLI and experiment comparison provide results; CI must interpret them&lt;/td&gt;
&lt;td&gt;timestamped experiment results and CSV-backed comparisons&lt;/td&gt;
&lt;td&gt;strongest vocabulary is RAG-specific; gate policy is team-owned&lt;/td&gt;
&lt;td&gt;reject when tool-use safety, permissions and broad system regression dominate the release&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  1. Promptfoo: strongest CI-native release gate
&lt;/h2&gt;

&lt;p&gt;Promptfoo puts the shortest distance between an evaluation failure and a blocked build. Its &lt;a href="https://www.promptfoo.dev/docs/integrations/ci-cd/" rel="noopener noreferrer"&gt;CI/CD integration&lt;/a&gt; shows evaluations running in standard pipelines, while the CLI can fail on errors or enforce a pass-rate threshold. That makes it practical for pull request evaluation: compare a candidate prompt or model with a baseline, test protected scenarios, then stop the merge when the policy fails.&lt;/p&gt;

&lt;p&gt;The custom assertion surface is broad enough to mix exact checks, JavaScript or Python logic, semantic similarity and model-graded rubrics. Its &lt;a href="https://www.promptfoo.dev/docs/configuration/expected-outputs/" rel="noopener noreferrer"&gt;expected-output configuration&lt;/a&gt; can express assertions beside test cases instead of hiding the release rule in a dashboard.&lt;/p&gt;

&lt;p&gt;For traceability, tags can carry a Git SHA or CI run ID, and the &lt;a href="https://www.promptfoo.dev/docs/usage/command-line/" rel="noopener noreferrer"&gt;command-line interface&lt;/a&gt; can emit JSON, HTML or JUnit evidence. The trade-off is operational: the team must maintain Node-compatible tooling, provider credentials and a disciplined configuration repository. Promptfoo is the best choice here when evaluation is expected to behave like a software quality gate rather than an analyst workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. DeepEval: best fit for Python test suites
&lt;/h2&gt;

&lt;p&gt;DeepEval treats LLM regression testing as unit testing. A developer creates an LLM test case, attaches metrics and thresholds and calls &lt;code&gt;assert_test&lt;/code&gt; inside pytest. Its &lt;a href="https://deepeval.com/docs/evaluation-unit-testing-in-ci-cd" rel="noopener noreferrer"&gt;CI/CD guide&lt;/a&gt; documents &lt;code&gt;deepeval test run&lt;/code&gt; as a build step where failed metrics fail the job.&lt;/p&gt;

&lt;p&gt;That model works well for Python services because an eval suite can live beside application tests. Teams can extend &lt;code&gt;BaseMetric&lt;/code&gt; for deterministic logic or use GEval when a rubric needs an LLM judge. Local execution does not require a Confident AI account, although the judge provider still needs credentials. Shared reports, trends and an official baseline add the Confident AI service.&lt;/p&gt;

&lt;p&gt;The disqualifier is not evaluation quality; it is stack fit. A TypeScript-first release system may not want Python and pytest as the control plane. If the application is already Python-based, however, DeepEval offers a clear test-to-build failure path without forcing all result review into a separate UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. LangSmith: best managed traceability
&lt;/h2&gt;

&lt;p&gt;LangSmith is strongest when an evaluation result must be inspected with the execution that produced it. Its &lt;a href="https://docs.langchain.com/langsmith/evaluate-llm-application" rel="noopener noreferrer"&gt;evaluation workflow&lt;/a&gt; covers datasets, offline experiments, code evaluators and LLM evaluators. Teams can attach experiment metadata for model, prompt and tool versions, compare runs and export results.&lt;/p&gt;

&lt;p&gt;The differentiator is component-level evidence. LangSmith can &lt;a href="https://docs.langchain.com/langsmith/evaluate-on-intermediate-steps" rel="noopener noreferrer"&gt;evaluate intermediate trace steps&lt;/a&gt;, which helps diagnose whether retrieval, tool selection or another stage caused the regression. Pytest and Jest integrations make the results available during testing, but release authority is still composable: the team must define which metric, slice or critical case blocks the candidate.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://pharosproduction.com/services/mlops/" rel="noopener noreferrer"&gt;MLOps release and monitoring work&lt;/a&gt;, that boundary matters because offline evaluation still has to hand evidence to canary deployment, observability, rollback and an accountable release owner.&lt;/p&gt;

&lt;p&gt;Choose LangSmith when managed experiment history and traces justify the platform dependency. Reject it when policies prohibit sending evaluation data or traces to the service, or when the team wants a completely local gate with no managed control plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. OpenAI Evals: best for reusable eval specifications
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/openai/evals" rel="noopener noreferrer"&gt;OpenAI Evals&lt;/a&gt; is an open-source framework and registry for evaluating language models and model-powered systems. Its useful release-engineering contribution is the specification: private JSONL samples, reusable templates, completion functions and &lt;a href="https://github.com/openai/evals/blob/main/docs/custom-eval.md" rel="noopener noreferrer"&gt;custom eval classes&lt;/a&gt; can turn an evaluation method into versioned code.&lt;/p&gt;

&lt;p&gt;That flexibility is also why the framework ranks below the first three for release gating. The official repository explains how to build and run evals, but it does not provide the same documented pull-request policy, candidate binding and build-fail workflow as Promptfoo or DeepEval. Teams need a wrapper that translates scores and critical failures into process status, stores artifacts and binds the run to the candidate commit.&lt;/p&gt;

&lt;p&gt;The framework also requires an OpenAI API key for relevant runs and incurs model-call cost. Its newer solver interface is documented as beta, which matters if a release process depends on a stable extension boundary. Choose it when the eval definition and benchmark corpus are the primary assets. Do not choose it expecting a turnkey release ledger.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Ragas: best for RAG-specific evaluation
&lt;/h2&gt;

&lt;p&gt;Ragas earns the fifth place because retrieval-augmented generation has failure modes that generic answer scoring often misses. Its &lt;a href="https://docs.ragas.io/en/stable/howtos/cli/rag_eval/" rel="noopener noreferrer"&gt;RAG evaluation workflow&lt;/a&gt; starts from a dataset and applies metrics suited to retrieved context and generated answers. The framework also supports custom discrete and numerical metrics.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.ragas.io/en/stable/concepts/experimentation/" rel="noopener noreferrer"&gt;experimentation layer&lt;/a&gt; stores runs and supports comparison with a baseline experiment. That is useful for testing a new embedding model, chunking strategy, reranker or prompt against a known RAG configuration.&lt;/p&gt;

&lt;p&gt;Ragas becomes weaker when the release target is a broad agentic system. RAG metrics do not prove that tool permissions, side effects, schema contracts or rollback controls are correct. Its CLI can produce evaluation results, but the official workflow leaves the hard CI policy to the team. Use Ragas as the evaluation specialist inside a wider release contract; reject it as the sole gate when non-RAG system behavior carries most of the risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The framework is only one part of the release gate
&lt;/h2&gt;

&lt;p&gt;Whichever tool you select, bind every run to an immutable candidate fingerprint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"provider/model@version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt_sha256"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dataset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"golden-set-v12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evaluator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"release-rubric-v4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"app_commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f4c2d..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store per-slice results, not only an average. A critical safety case, an unauthorized tool call or a broken schema can be a hard failure even when the aggregate score improves. Save the failing examples, evaluator version, CI run ID and threshold policy with the verdict.&lt;/p&gt;

&lt;p&gt;Finally, keep the controls that evaluation frameworks do not own: canary exposure, production monitoring, side-effect receipts, rollback and the person authorized to accept residual risk. The evidence bundle should answer three questions without reopening the dashboard: what exact candidate was tested, which rule passed or failed, and who owns the release decision.&lt;/p&gt;

&lt;p&gt;Choose Promptfoo for a CI-native gate, DeepEval for Python-native regression tests, LangSmith for managed trace evidence, OpenAI Evals for reusable eval specifications, or Ragas for RAG-specific measurement. Then make the blocking rule explicit. A framework can calculate evidence; release engineering decides whether that evidence is sufficient to ship.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>testing</category>
      <category>mlops</category>
      <category>ai</category>
    </item>
    <item>
      <title>Smart Contract Release Audit: 8 Repository Artifacts</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Thu, 27 Aug 2026 10:45:19 +0000</pubDate>
      <link>https://dev.to/pharos_production/how-to-choose-a-smart-contract-development-company-8-repository-checks-9m</link>
      <guid>https://dev.to/pharos_production/how-to-choose-a-smart-contract-development-company-8-repository-checks-9m</guid>
      <description>&lt;p&gt;An auditable smart contract release is a chain of evidence, not a green CI badge. The repository should bind the build, threat model, invariant tests, privileged roles, deployment rehearsal, audit scope and handover runbook to one commit.&lt;/p&gt;

&lt;p&gt;This guide turns that chain into eight repository checks and a 60-minute technical review. Use it to determine whether a delivery process can reproduce and explain one EVM release. A failed build, unmapped privileged authority or audit report without a scope commit blocks the review.&lt;/p&gt;

&lt;p&gt;This is a release-audit framework, not a security certification.&lt;/p&gt;

&lt;h2&gt;
  
  
  A release claim needs a repository artifact
&lt;/h2&gt;

&lt;p&gt;"Security-first" is not evidence. A threat model and a failing test are evidence. So are a CI result and a deployment manifest.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.soliditylang.org/en/latest/security-considerations.html" rel="noopener noreferrer"&gt;Solidity security guidance&lt;/a&gt; recommends code review and testing. It also discusses audits, small modular contracts and fail-safe design. A release review should therefore inspect how those practices appear in the repository, not merely ask whether the team uses them.&lt;/p&gt;

&lt;p&gt;A neutral rule matters here: &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;Pharos Production's company profile&lt;/a&gt; should receive no credit for a claim that cannot be mapped to an inspectable artifact either. Apply the same test to any team presenting the release.&lt;/p&gt;

&lt;p&gt;Confidential client work does not invalidate this approach. The delivery team can provide a sanitized repository, a public project, an internal reference implementation or a live screen-share with sensitive names removed. You do not need customer source code. You need proof that the release process exists and can be reproduced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze one release as the review boundary
&lt;/h2&gt;

&lt;p&gt;Select one recent project close to the target chain and risk model. The review package should identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the exact commit being demonstrated.&lt;/li&gt;
&lt;li&gt;compiler and framework versions, plus the dependency lock.&lt;/li&gt;
&lt;li&gt;reproducible build commands and CI entry points.&lt;/li&gt;
&lt;li&gt;the threat model with declared system invariants.&lt;/li&gt;
&lt;li&gt;every role that can upgrade, pause, mint or administer the system.&lt;/li&gt;
&lt;li&gt;deployment scripts plus a non-production rehearsal record.&lt;/li&gt;
&lt;li&gt;audit scope, remediation changes and unresolved risks.&lt;/li&gt;
&lt;li&gt;the handover runbook with named owners.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not request seed phrases, private keys, customer data or proprietary business logic. A good evidence room proves the process without exposing secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  An eight-check repository scorecard
&lt;/h2&gt;

&lt;p&gt;Score each check from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;2&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt;: absent, verbal only or not reproducible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt;: an artifact exists but is incomplete, stale or not bound to the demonstrated release.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt;: a reviewer can reproduce it and trace it to the same commit, configuration and release scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Evidence to inspect&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;0&lt;/code&gt; looks like&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;2&lt;/code&gt; looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Build provenance&lt;/td&gt;
&lt;td&gt;pinned compiler, lockfile, documented commands and CI workflow&lt;/td&gt;
&lt;td&gt;"It builds on our lead developer's laptop"&lt;/td&gt;
&lt;td&gt;a clean checkout builds with the documented toolchain and no hidden local step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Threat model&lt;/td&gt;
&lt;td&gt;assets, actors, trust boundaries, external dependencies, abuse cases and invariants&lt;/td&gt;
&lt;td&gt;a generic security checklist&lt;/td&gt;
&lt;td&gt;named failure scenarios are mapped to controls and tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Test design&lt;/td&gt;
&lt;td&gt;unit, fuzz, invariant, integration or fork tests selected for the system's risks&lt;/td&gt;
&lt;td&gt;a coverage percentage with no risk mapping&lt;/td&gt;
&lt;td&gt;the team can reintroduce a bounded defect and show the relevant test fail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Static analysis and review debt&lt;/td&gt;
&lt;td&gt;tool configuration, CI output, suppressions, manual-review notes and finding owners&lt;/td&gt;
&lt;td&gt;a green badge or tool logo&lt;/td&gt;
&lt;td&gt;every material finding is fixed, accepted with rationale or assigned for action&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. Upgrade and admin authority&lt;/td&gt;
&lt;td&gt;immutable or proxy decision, role map, current controllers, emergency powers and storage-layout checks&lt;/td&gt;
&lt;td&gt;"We use a multisig" with no address or authority map&lt;/td&gt;
&lt;td&gt;every privileged action has a controller, change path and observable event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6. Deployment rehearsal&lt;/td&gt;
&lt;td&gt;versioned scripts, network parameters, address manifest, verification steps and dry-run receipt&lt;/td&gt;
&lt;td&gt;manual console commands reconstructed from memory&lt;/td&gt;
&lt;td&gt;the team can replay a non-production deployment from the reviewed commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7. Audit handoff&lt;/td&gt;
&lt;td&gt;scope commit, exclusions, report, remediation pull requests, retest and accepted residual risk&lt;/td&gt;
&lt;td&gt;an audit PDF with no repository reference&lt;/td&gt;
&lt;td&gt;each finding traces from the reviewed commit to a change and final disposition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8. Operational handover&lt;/td&gt;
&lt;td&gt;monitoring, incident roles, pause or containment procedure, key rotation and upgrade runbook&lt;/td&gt;
&lt;td&gt;support described only in the proposal&lt;/td&gt;
&lt;td&gt;the operator can run the system without an undocumented team-only action&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Across the 8 checks, the maximum is 16, but the total is not the decision. A hard stop overrides the score. Adjust the depth of each check to value at risk. Privilege concentration and external dependencies also matter.&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%2Fjerlgkfdwg6d7nq0pont.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjerlgkfdwg6d7nq0pont.png" alt="Repository release-audit flow from a claim through a commit-bound artifact, reproducibility and ownership checks to a score, with failed gates routed to zero or block" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A claim earns points only after it is bound to one release, reproduced and assigned a disposition. Any failed hard gate routes to &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;BLOCK&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Broader procurement questions such as team scope, regulatory fit, multi-chain experience and engagement evidence belong in a separate &lt;a href="https://pharosproduction.com/insights/comparisons/blockchain-development-companies/" rel="noopener noreferrer"&gt;blockchain development company evaluation framework&lt;/a&gt;. This repository review begins after one delivery system and one release boundary have been selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the test model, not the test count
&lt;/h2&gt;

&lt;p&gt;Line coverage says which lines executed. It does not say that the important property was asserted.&lt;/p&gt;

&lt;p&gt;Ask the team to name the properties that must survive arbitrary user actions. Examples include conservation of assets, bounded issuance, withdrawal availability and authorization of privileged state changes. Then locate those properties in the test suite.&lt;/p&gt;

&lt;p&gt;Foundry's &lt;a href="https://getfoundry.sh/forge/invariant-testing" rel="noopener noreferrer"&gt;invariant-testing documentation&lt;/a&gt; explains that invariant campaigns run randomized sequences of calls and assert the declared invariants after each call. The repository should also expose what the fuzzer actually explored. Inspect its targets and run depth, then examine reverts and handler behavior. A passing campaign that never reaches a meaningful state is weak evidence.&lt;/p&gt;

&lt;p&gt;One demonstration is especially useful: ask the team to make a reversible local change that violates a declared invariant, then run the relevant test. The point is not theater. It verifies that the test can detect the failure it claims to control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read static-analysis suppressions as engineering debt
&lt;/h2&gt;

&lt;p&gt;Static analysis is a gate only when its configuration and output are reviewable. Slither can analyze Solidity and Vyper projects, integrate with CI and emit machine-readable results, as described in the &lt;a href="https://github.com/crytic/slither" rel="noopener noreferrer"&gt;project documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Do not award points for running &lt;code&gt;slither .&lt;/code&gt; alone. Inspect excluded detectors and path filters. Then review inline suppressions and the treatment of each material finding. A suppression needs a technical reason and a defined scope. It also needs an owner. Otherwise the tool may be green because the repository taught it not to look.&lt;/p&gt;

&lt;p&gt;Required status checks can prevent a protected GitHub branch from accepting changes until configured checks pass. That mechanism is documented in &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches" rel="noopener noreferrer"&gt;GitHub's protected-branch guidance&lt;/a&gt;. During due diligence, confirm that the security job is actually required on the release branch and that its expected source cannot be replaced casually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make upgrade authority explicit
&lt;/h2&gt;

&lt;p&gt;"Upgradeable" is not a feature checkbox. It changes the trust model.&lt;/p&gt;

&lt;p&gt;For proxy-based systems, request the proxy pattern, initializer logic, storage-layout comparison and the current authority that can change implementation code. OpenZeppelin's &lt;a href="https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable" rel="noopener noreferrer"&gt;upgradeable-contract guidance&lt;/a&gt; documents initializer and storage-layout constraints. &lt;a href="https://eips.ethereum.org/EIPS/eip-1967" rel="noopener noreferrer"&gt;ERC-1967&lt;/a&gt; defines standard implementation, beacon and optional admin storage slots for common proxy designs.&lt;/p&gt;

&lt;p&gt;The evidence room should answer four questions without a sales call:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which address can upgrade, pause, mint, seize, recover or change critical parameters?&lt;/li&gt;
&lt;li&gt;What contract, multisig, timelock or governance path controls that address?&lt;/li&gt;
&lt;li&gt;Which event or monitor reveals a change?&lt;/li&gt;
&lt;li&gt;What happens if the controller is compromised or unavailable?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An immutable contract still needs an authority review. The answer may be "no upgrade path," but ownership, external dependencies and emergency behavior must remain visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind the audit to the release
&lt;/h2&gt;

&lt;p&gt;An audit report describes a scope at a point in time. Record the repository URL and commit hash beside it. Preserve the compiler settings, excluded components and deployed addresses in the same record. Then trace every finding to a remediation pull request, retest result or explicit risk acceptance.&lt;/p&gt;

&lt;p&gt;This avoids a common evidence break: the audit covers one commit while the deployment comes from a later branch with unreviewed changes. The team does not need to claim that an audit guarantees safety. It needs to show which code was reviewed and what changed afterward.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://scs.owasp.org/SCSVS/" rel="noopener noreferrer"&gt;OWASP Smart Contract Security Verification Standard&lt;/a&gt; can help structure the threat model and review scope. Its control groups cover architecture and code as well as governance, authorization and external interactions. Treat it as a control reference, not proof that the repository satisfies those controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run a 60-minute technical review
&lt;/h2&gt;

&lt;p&gt;A bounded live session is more discriminating than another capability deck:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Reviewer asks the delivery team to do&lt;/th&gt;
&lt;th&gt;Evidence produced&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0-10 minutes&lt;/td&gt;
&lt;td&gt;check out the named commit and build it with documented commands&lt;/td&gt;
&lt;td&gt;reproducible build or a concrete blocker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10-25 minutes&lt;/td&gt;
&lt;td&gt;run one unit path and one risk-based fuzz or invariant test&lt;/td&gt;
&lt;td&gt;test output plus an explanation of the property being checked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25-40 minutes&lt;/td&gt;
&lt;td&gt;walk through roles, upgrade paths and one compromised-admin scenario&lt;/td&gt;
&lt;td&gt;privilege map and containment decision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40-50 minutes&lt;/td&gt;
&lt;td&gt;trace one audit finding from scope commit to remediation&lt;/td&gt;
&lt;td&gt;commit-bound audit trail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50-60 minutes&lt;/td&gt;
&lt;td&gt;replay a non-production deployment and inspect the handover package&lt;/td&gt;
&lt;td&gt;deployment receipt, address manifest and runbook&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The session is not a coding contest. It tests whether the release evidence remains coherent under inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hard stops that override the score
&lt;/h2&gt;

&lt;p&gt;Block or pause the release review when any of these remains unresolved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clean checkout cannot build without an undocumented machine or manual step.&lt;/li&gt;
&lt;li&gt;the audit report cannot be tied to a commit and declared scope.&lt;/li&gt;
&lt;li&gt;upgrade, pause, mint or deployment authority cannot be mapped to current controllers.&lt;/li&gt;
&lt;li&gt;a material static-analysis or audit finding is suppressed without rationale and ownership.&lt;/li&gt;
&lt;li&gt;production deployment depends on unrecorded console actions.&lt;/li&gt;
&lt;li&gt;a critical invariant has no test or explicit compensating control.&lt;/li&gt;
&lt;li&gt;the operator cannot monitor or contain the system without undocumented team-only knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A release can score well on six checks and still fail on unknown upgrade authority. Do not let arithmetic hide a control that can replace the code after review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adapt the evidence request to the engagement
&lt;/h2&gt;

&lt;p&gt;During early discovery, finished code may not exist. Review the team's repository template and threat-model method instead. Inspect its CI gates and sample handover package separately. Mark future evidence as a delivery requirement.&lt;/p&gt;

&lt;p&gt;For non-EVM work, replace Solidity and Foundry with the target ecosystem's compiler and test framework. Substitute its analyzer and authority model for Slither and ERC-1967. The evidence jobs stay the same.&lt;/p&gt;

&lt;p&gt;A small immutable utility contract needs less ceremony than a protocol controlling treasury assets. It does not get a free pass on reproducible builds, authority mapping or release provenance. Scale the depth, not the existence, of the controls.&lt;/p&gt;

&lt;p&gt;Send this request before the sales call:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please prepare a 60-minute technical review tied to one recent, representative release. First, show a sanitized repository or screen-share with a clean build, risk-mapped tests and static-analysis disposition. Then show the privileged-role map, non-production deployment rehearsal, commit-bound audit handoff and operational runbook. Do not share private keys or customer data. Omit confidential business logic as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The response shows whether another operator can reproduce the release without undocumented help.&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>web3</category>
      <category>security</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>LLM Evaluation Scores Are Not Release Gates</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Thu, 27 Aug 2026 07:35:49 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/llm-evaluation-scores-are-not-release-gates-1m6p</link>
      <guid>https://dev.to/dmytronasyrov/llm-evaluation-scores-are-not-release-gates-1m6p</guid>
      <description>&lt;p&gt;Your new prompt scores 94% on the golden dataset. The current version scores 91%. That result supports a change, but it does not authorize a production release.&lt;/p&gt;

&lt;p&gt;An LLM evaluation score answers a bounded question about a dataset, a grader and a run configuration. A release gate answers a wider question: can this exact system version enter production without an unacceptable regression, uncontrolled side effect, policy violation or unrecoverable failure? A practical release contract uses five independent gates. Model quality is only one of them.&lt;/p&gt;

&lt;p&gt;Scores do not carry release authority.&lt;/p&gt;

&lt;h2&gt;
  
  
  An eval score is a measurement with a scope
&lt;/h2&gt;

&lt;p&gt;An LLM evaluation is useful because generative AI is variable. OpenAI's &lt;a href="https://developers.openai.com/api/docs/guides/evaluation-best-practices" rel="noopener noreferrer"&gt;evaluation guidance&lt;/a&gt; describes evals as structured tests for measuring model performance and distinguishes application-specific tests from industry benchmarks and standard numerical scores.&lt;/p&gt;

&lt;p&gt;The scope is carried by the test dataset, evaluation criteria and grader. Change the golden dataset, ground-truth labels, evaluation rubric, model version, prompt version, scorer version or dataset version and the meaning of the number changes. A useful LLM evaluation framework keeps those bindings beside every run. A 94% pass rate without them is not reproducible release evidence.&lt;/p&gt;

&lt;p&gt;That distinction matters in &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;production AI systems engineering&lt;/a&gt; because the deployed product includes model behavior, tools, retrieval, data policies and operators. A model can improve on an aggregate score while the application becomes less safe or more expensive to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one LLM evaluation metric hides blockers
&lt;/h2&gt;

&lt;p&gt;An aggregate score compresses failures that do not have equal consequences. Ten awkward answers and one unauthorized refund may produce the same pass rate as eleven awkward answers. A confidence interval can describe uncertainty in the estimate, but it cannot repair a test set that omitted the dangerous behavior. The release decision should not treat those outcomes as equivalent.&lt;/p&gt;

&lt;p&gt;Four blind spots appear repeatedly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slice loss:&lt;/strong&gt; the overall LLM evaluation score rises while a high-risk language, tool or customer segment regresses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset drift:&lt;/strong&gt; the benchmark dataset no longer represents current production traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judge drift:&lt;/strong&gt; an LLM-as-a-judge changes behavior after a model update, or a revised rubric changes what counts as correct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System omission:&lt;/strong&gt; the eval grades the final text but never checks whether the agent called the wrong tool, leaked data or created an irreversible side effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LLM regression testing must therefore preserve the full LLM evaluation pipeline: fixtures, expected outputs, grader configuration and failure taxonomy. It should also report slice-level metrics beside the aggregate. The question is not merely "Did the average improve?" It is "Which behaviors moved, which failures became possible and which risks cross the release threshold?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The five-gate LLM release contract
&lt;/h2&gt;

&lt;p&gt;Treat the release decision as a conjunction. Every required gate must pass for the same immutable candidate.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gate&lt;/th&gt;
&lt;th&gt;Required evidence&lt;/th&gt;
&lt;th&gt;Blocks release when&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Quality regression&lt;/td&gt;
&lt;td&gt;versioned test dataset, baseline run, candidate run, slice-level metrics and reviewed failures&lt;/td&gt;
&lt;td&gt;a protected slice crosses its regression threshold or a critical case fails&lt;/td&gt;
&lt;td&gt;product or domain owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Deterministic system behavior&lt;/td&gt;
&lt;td&gt;schema tests, tool-call assertions, permission checks, idempotency tests and side-effect receipts&lt;/td&gt;
&lt;td&gt;the system can call an unauthorized tool, repeat a non-idempotent action or violate an output contract&lt;/td&gt;
&lt;td&gt;application engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Safety and policy&lt;/td&gt;
&lt;td&gt;safety evaluation, LLM guardrails, prompt-injection tests, data-leakage checks and red-team findings&lt;/td&gt;
&lt;td&gt;a zero-tolerance policy case fails or residual risk exceeds the declared tolerance&lt;/td&gt;
&lt;td&gt;security or risk owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Operational recovery&lt;/td&gt;
&lt;td&gt;canary plan, production monitoring, rollback plan, pinned prior version and incident runbook&lt;/td&gt;
&lt;td&gt;the team cannot detect harm, stop traffic or restore a known version inside the required window&lt;/td&gt;
&lt;td&gt;platform or SRE owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. Decision authority&lt;/td&gt;
&lt;td&gt;signed release criteria, evidence manifest, known exceptions, expiry and named approver&lt;/td&gt;
&lt;td&gt;evidence is stale, mismatched to the candidate or no accountable owner accepts the residual risk&lt;/td&gt;
&lt;td&gt;release owner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is stricter than a single regression gate, but it is not a demand for perfect model behavior. Each team still chooses thresholds based on use case and risk tolerance. The contract only prevents a quality metric from silently carrying authority it was never designed to hold.&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%2Fm49xvyiq9ee2bk87rjqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm49xvyiq9ee2bk87rjqb.png" alt="Five-gate LLM release contract showing one candidate flowing through five parallel checks before release" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The candidate fingerprint binds every gate to the same model, prompt, dataset and scorer. One failure routes the candidate to &lt;code&gt;BLOCK&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think of the table as an LLM production readiness checklist with explicit failure authority. It is broader than an LLM eval framework because it binds quality evidence to software checks, AI governance, recovery and an approval owner. The resulting audit trail explains not only what scored well, but why this candidate was allowed to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 1: LLM regression testing protects behavior
&lt;/h2&gt;

&lt;p&gt;The first gate compares the candidate with the current production baseline on representative cases. OpenAI's &lt;a href="https://developers.openai.com/api/docs/guides/evals" rel="noopener noreferrer"&gt;eval workflow&lt;/a&gt; binds test inputs to explicit testing criteria and, where appropriate, human-labeled ground truth. That is the right foundation for model regression and prompt regression checks after a model upgrade, prompt edit or retrieval change.&lt;/p&gt;

&lt;p&gt;The gate should keep critical failures separate from averages. A medical contraindication, financial action or access-control decision may be a zero-tolerance case even when ordinary response quality uses a statistical threshold. Human evaluation remains necessary for disputed semantic cases, especially when an LLM-as-a-judge sees the same limited channel as the system it grades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 2: check evidence outside the model answer
&lt;/h2&gt;

&lt;p&gt;Text quality does not prove that the application behaved correctly. An agent can write a persuasive summary after calling six tools instead of two. It can produce valid JSON after querying data it should not access. It can report success after a write failed.&lt;/p&gt;

&lt;p&gt;Deterministic checks should inspect what code and infrastructure can prove: tool allowlists, argument schemas, authorization decisions, transaction identifiers, idempotency keys, file hashes and command exit status. These checks do not replace semantic evaluation. They cover a different failure channel.&lt;/p&gt;

&lt;p&gt;That wider contract is where &lt;a href="https://pharosproduction.com/services/mlops/" rel="noopener noreferrer"&gt;MLOps release and monitoring design&lt;/a&gt; enters the decision: the team must be able to deploy gradually, observe impact, stop traffic, restore a known version and assign a human owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 3: LLM guardrails are release criteria
&lt;/h2&gt;

&lt;p&gt;Safety evaluation should be risk-specific. Prompt injection, data leakage, harmful instructions, policy evasion and excessive tool permissions need separate policy checks because an average helpfulness score can hide every one of them.&lt;/p&gt;

&lt;p&gt;Red teaming finds candidate failures. The release gate turns selected findings into repeatable abuse testing and declares which classes are zero tolerance. LLM guardrails then enforce runtime constraints, but their presence alone is not evidence that they work. The gate must test the guardrail response and the failure path around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 4: production readiness includes rollback
&lt;/h2&gt;

&lt;p&gt;Offline evaluation happens before exposure. Online evaluation and LLM production monitoring observe behavior under real traffic. Google Cloud's &lt;a href="https://docs.cloud.google.com/architecture/deploy-operate-generative-ai-applications" rel="noopener noreferrer"&gt;operations guidance&lt;/a&gt; lists continuous evaluation as one approach to monitoring generative AI applications.&lt;/p&gt;

&lt;p&gt;Neither makes rollback optional. A canary deployment needs a traffic boundary, stop condition and known-good target. LLM observability should bind traces to the model, prompt, retrieval index, tool set and policy version that produced them. Otherwise model drift and prompt regressions arrive as anonymous dashboard changes.&lt;/p&gt;

&lt;p&gt;The gate fails when alerts have no response action, when the prior version cannot be restored or when an external provider update makes rollback impossible and no containment plan exists. Production monitoring, incident response and rollback must refer to the same candidate identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gate 5: a person owns the decision
&lt;/h2&gt;

&lt;p&gt;NIST's &lt;a href="https://airc.nist.gov/airmf-resources/airmf/5-sec-core/" rel="noopener noreferrer"&gt;AI Risk Management Framework Core&lt;/a&gt; separates Govern, Map, Measure and Manage. Measurement informs the decision to proceed, while management covers response, recovery, monitoring and assigned responsibilities. That separation is a useful model for an LLM release process.&lt;/p&gt;

&lt;p&gt;The approver is not signing a score. The approver accepts a release contract with defined evidence, thresholds, exceptions and rollback conditions. Approval should expire when any bound component changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"candidate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"provider/model@version"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dataset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eval-set-v17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scorer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rubric-v6"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"quality_regression"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deterministic_side_effects"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"safety_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rollback_readiness"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"decision_authority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PASS"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"release-owner@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-28T12:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The record ties every verdict to one candidate. If the prompt, model, dataset, scorer, tool permissions or retrieval index changes, the release evidence no longer matches.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should block an LLM release?
&lt;/h2&gt;

&lt;p&gt;Use a hard block when at least one of these conditions is true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a critical scenario fails, even if the aggregate LLM evaluation metric improves.&lt;/li&gt;
&lt;li&gt;a protected slice crosses its regression threshold.&lt;/li&gt;
&lt;li&gt;a tool call, permission or side effect cannot be verified deterministically.&lt;/li&gt;
&lt;li&gt;a safety or policy control fails its declared test.&lt;/li&gt;
&lt;li&gt;monitoring cannot identify the deployed candidate.&lt;/li&gt;
&lt;li&gt;rollback or containment cannot meet the required response window.&lt;/li&gt;
&lt;li&gt;the evidence manifest is stale or no release owner accepts the remaining risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical rule is compact: evals measure behavior, gates authorize change. Keep the score inside the first gate and require the other four to speak before production traffic moves.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>mlops</category>
      <category>testing</category>
      <category>ai</category>
    </item>
    <item>
      <title>One Payment, Three Ledgers: Where Reconciliation Actually Breaks</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Thu, 20 Aug 2026 19:55:31 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/one-payment-three-ledgers-where-reconciliation-actually-breaks-1fn</link>
      <guid>https://dev.to/dmytronasyrov/one-payment-three-ledgers-where-reconciliation-actually-breaks-1fn</guid>
      <description>&lt;p&gt;A processor says a payment settled. Your product ledger shows the customer balance and fee entries. The bank account still has no matching credit. None of those records is necessarily wrong, yet the payment is not reconciled.&lt;/p&gt;

&lt;p&gt;The mistake is asking which system has the true status. Each system owns a different fact. Reconciliation belongs to the process that can compare those facts, preserve the mismatch and prove what happened at every boundary. A useful design sets invariants across the product ledger, the processor settlement record and the bank statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  One payment creates three different facts
&lt;/h2&gt;

&lt;p&gt;Your product ledger records the economic event the application accepted: a capture, refund, fee, reserve movement, chargeback or correction. It should preserve the customer-facing and accounting consequences even when an external provider changes later.&lt;/p&gt;

&lt;p&gt;A processor owns another view. Its settlement data determines which transactions and adjustments entered a payout. Stripe, for instance, exposes immutable balance transactions and lets automatic payouts retain their association with the transactions they contain. Adyen's settlement details report includes settled payments, fees, corrections, payouts and a payout reference that can appear on the bank statement.&lt;/p&gt;

&lt;p&gt;Only the bank statement proves the cash movement. It cannot explain the composition of a processor batch, and the processor cannot prove that a credit reached the bank merely by marking a payment as settled.&lt;/p&gt;

&lt;p&gt;This separation is part of &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;payment systems engineering&lt;/a&gt; because the integration call that moves money and the evidence that closes the books have different owners. Treating a provider response as all three facts makes the happy path simple and every exception ambiguous.&lt;/p&gt;

&lt;p&gt;I use "ledger" here as shorthand for a durable reconciliation surface. A processor report or bank statement may not be a double-entry ledger. The design still needs to preserve their facts as immutable evidence rather than flattening them into one mutable payment status.&lt;/p&gt;

&lt;h2&gt;
  
  
  The invariant map
&lt;/h2&gt;

&lt;p&gt;Start with a currency and a reconciliation window. Then define the equations that must hold after accounting for cutoffs, fees, reserves, refunds, chargebacks, corrections and foreign-exchange effects.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Boundary&lt;/th&gt;
&lt;th&gt;Invariant&lt;/th&gt;
&lt;th&gt;Evidence that closes it&lt;/th&gt;
&lt;th&gt;What a mismatch means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product ledger to processor&lt;/td&gt;
&lt;td&gt;Expected provider payable from internal entries equals the processor's net settlement components&lt;/td&gt;
&lt;td&gt;internal journal entries plus transaction-level processor report&lt;/td&gt;
&lt;td&gt;missing event, duplicate event, amount mapping error, fee rule drift, or timing classification error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processor batch to bank&lt;/td&gt;
&lt;td&gt;Processor payout amount and currency equal the bank credit after declared bank or FX adjustments&lt;/td&gt;
&lt;td&gt;payout record, batch reference, value date, and bank statement line&lt;/td&gt;
&lt;td&gt;payout still in transit, wrong destination, bank fee, FX difference, rejection, or missing cash movement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Period continuity&lt;/td&gt;
&lt;td&gt;Opening unsettled balance plus new net activity minus payouts equals closing unsettled balance&lt;/td&gt;
&lt;td&gt;consecutive settlement periods and retained adjustments&lt;/td&gt;
&lt;td&gt;orphaned balance, late event, duplicated payout application, or a broken cutoff rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference completeness&lt;/td&gt;
&lt;td&gt;Every bank credit maps to one processor payout and every completed payout maps to one bank credit&lt;/td&gt;
&lt;td&gt;stable payout reference and a controlled fallback match&lt;/td&gt;
&lt;td&gt;unlinked cash, one-to-many aggregation, reused reference, or incomplete ingestion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The point is not to force all systems to agree at every moment. They operate on different clocks. The point is to know which differences are expected, which deadline makes them actionable, and what evidence will eventually close them.&lt;/p&gt;

&lt;h2&gt;
  
  
  A modeled break: settled, posted, but not received
&lt;/h2&gt;

&lt;p&gt;Assume the processor marks a card payment as settled. The product ledger has already posted the customer balance and expected fee. The safeguarding or operating bank account has no corresponding credit.&lt;/p&gt;

&lt;p&gt;Do not reverse the customer entry just because the bank credit is absent. "Payment settled" and "payout reached the bank" describe different boundaries. First ask whether the payment was included in a closed settlement batch. If it was not, the first invariant may still be open because of the provider's cutoff, reserve policy or status mapping. If it was included, locate the payout reference and compare the batch net amount with the expected bank credit.&lt;/p&gt;

&lt;p&gt;The absence becomes a bank-boundary exception only after the payout has a provider-side completion fact and the agreed arrival window has expired. Until then, the discrepancy needs a state such as &lt;code&gt;awaiting_bank_evidence&lt;/code&gt;, not a generic &lt;code&gt;failed&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;That distinction changes the recovery action. A ledger mapping defect can require a replay from immutable source events. A missing bank credit needs provider or bank investigation. Re-running the original payment cannot repair either one and may create a second economic event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a discrepancy record, not an alert string
&lt;/h2&gt;

&lt;p&gt;A reconciliation job should emit a durable object that another worker or analyst can resolve without reconstructing the original comparison from logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discrepancy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rec_01J..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"invariant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"processor_payout_equals_bank_credit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"internal_evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"journal_batch_..."&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"processor_evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"payout_..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"settlement_batch_..."&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bank_evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"awaiting_bank_evidence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"treasury_operations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"next_check_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The record names the failed invariant, the evidence already present, the evidence still missing, the current owner and the next permitted action. Its identity should remain stable across retries. Otherwise every polling cycle creates a new exception and hides the age of the original break.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://pharosproduction.com/services/payment-solutions-development/" rel="noopener noreferrer"&gt;reconciliation design for payment platforms&lt;/a&gt; becomes an architectural concern rather than a reporting feature: the discrepancy must survive provider outages, late files, replayed webhooks and human investigation without losing its lineage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect the break at the boundary that owns it
&lt;/h2&gt;

&lt;p&gt;One reconciliation worker can coordinate the process, but it should not become an unquestioned source of truth. Authority remains fact-specific.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Invariant&lt;/th&gt;
&lt;th&gt;Required evidence&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;th&gt;Detection time&lt;/th&gt;
&lt;th&gt;Recovery action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Internal entries equal processor components&lt;/td&gt;
&lt;td&gt;immutable internal journal and transaction-level settlement rows&lt;/td&gt;
&lt;td&gt;payments accounting&lt;/td&gt;
&lt;td&gt;after the processor report closes for the window&lt;/td&gt;
&lt;td&gt;replay ingestion, repair mapping, or open a controlled accounting adjustment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processor payout equals bank credit&lt;/td&gt;
&lt;td&gt;payout ID, batch reference, expected arrival window, and statement line&lt;/td&gt;
&lt;td&gt;treasury operations&lt;/td&gt;
&lt;td&gt;when the arrival window expires&lt;/td&gt;
&lt;td&gt;query payout status, trace the transfer, then escalate to provider or bank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Opening plus activity minus payouts equals closing&lt;/td&gt;
&lt;td&gt;consecutive balances and every intervening adjustment&lt;/td&gt;
&lt;td&gt;financial control&lt;/td&gt;
&lt;td&gt;at period close&lt;/td&gt;
&lt;td&gt;freeze close, locate orphaned movement, and post only an approved correction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every external line has one controlled match&lt;/td&gt;
&lt;td&gt;provider and bank references plus fallback match rationale&lt;/td&gt;
&lt;td&gt;reconciliation service&lt;/td&gt;
&lt;td&gt;during ingestion and rematching&lt;/td&gt;
&lt;td&gt;quarantine ambiguity for review instead of choosing the nearest amount&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The detection time matters as much as the equation. Flagging a payout before its contractual arrival window produces noise. Waiting until month-end to detect a duplicated settlement row turns a local ingestion bug into an accounting close problem.&lt;/p&gt;

&lt;p&gt;Matching rules also need an order. Prefer stable provider and bank references. Use amount, currency, value date, merchant account and batch metadata only as controlled secondary evidence. A fuzzy match may propose a candidate, but it should not silently convert ambiguous cash into a reconciled state.&lt;/p&gt;

&lt;h2&gt;
  
  
  The system of record depends on the question
&lt;/h2&gt;

&lt;p&gt;Teams often try to settle the argument by declaring one database the system of record. That is useful for one class of fact and dangerous when applied to all of them.&lt;/p&gt;

&lt;p&gt;For customer obligations and internal accounting, the product ledger can be authoritative. A processor remains authoritative for the composition and status of its settlement batch. Cash received belongs to the bank's evidence. The reconciliation record proves that those sources were compared under a named rule and either matched or produced a controlled exception.&lt;/p&gt;

&lt;p&gt;This model also makes observability concrete. The useful metrics are not just payment success rate. Track the age of open discrepancies, unmatched value by currency, breaks by invariant, time to first owner, repeated ingestion events and corrections posted without complete evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the three-ledger model changes
&lt;/h2&gt;

&lt;p&gt;Some architectures collapse or add boundaries.&lt;/p&gt;

&lt;p&gt;If the processor is also the contractual ledger of record, the product may not maintain a separate customer-money ledger. The application still needs evidence that processor balances reconcile with bank cash, but it should not invent a duplicate accounting authority.&lt;/p&gt;

&lt;p&gt;Prefunded settlement changes the direction of the cash invariant. You reconcile funding movements and consumption of the prefunded balance rather than waiting for a payout after each sales batch. Split settlements, marketplace subaccounts, reserves and multi-currency conversion can add more than three reconciliation surfaces.&lt;/p&gt;

&lt;p&gt;The decision rule stays the same: model one invariant for every boundary where economic meaning, provider settlement or cash possession can diverge. Assign an evidence source, deadline, owner and recovery action before calling the payment reconciled.&lt;/p&gt;

&lt;p&gt;Which system in your stack can prove a payment is settled when the processor and bank disagree?&lt;/p&gt;

</description>
      <category>fintech</category>
      <category>payments</category>
      <category>architecture</category>
      <category>backend</category>
    </item>
    <item>
      <title>MCP Went Stateless. Your Recovery Logic Didn't.</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Thu, 13 Aug 2026 11:35:31 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/mcp-went-stateless-your-recovery-logic-didnt-3l79</link>
      <guid>https://dev.to/dmytronasyrov/mcp-went-stateless-your-recovery-logic-didnt-3l79</guid>
      <description>&lt;p&gt;The 2026-07-28 MCP revision removed the initialization handshake and protocol-level sessions. That makes a remote server easier to route and scale, but it does not make tool execution stateless. If a call can charge a card, create a ticket, send a message, or mutate a repository, retries still need durable facts. The practical conclusion is simple: move state out of the transport, then make execution, side effects, results, and delivery explicit. Otherwise a stateless server will recover cleanly at the HTTP layer while duplicating work in the system that actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stateless transport removed one state owner, not state
&lt;/h2&gt;

&lt;p&gt;The new MCP version retires &lt;code&gt;initialize&lt;/code&gt;/&lt;code&gt;initialized&lt;/code&gt; and the &lt;code&gt;Mcp-Session-Id&lt;/code&gt; header. Each request carries what the server needs to interpret it, and any request can land on any compatible instance behind a normal load balancer. The official &lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28/" rel="noopener noreferrer"&gt;2026-07-28 specification release&lt;/a&gt; describes the result as a stateless protocol core.&lt;/p&gt;

&lt;p&gt;That is an important infrastructure simplification. It removes sticky routing and protocol-owned session storage from the default path. It does not answer these application questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did this logical operation already start?&lt;/li&gt;
&lt;li&gt;Did an external side effect happen?&lt;/li&gt;
&lt;li&gt;Was the result persisted?&lt;/li&gt;
&lt;li&gt;Did the caller receive that result?&lt;/li&gt;
&lt;li&gt;Who is allowed to retry each step?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The discipline of &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;production AI infrastructure engineering&lt;/a&gt; begins by naming those owners before choosing queues, databases, or worker frameworks. A session used to hide some of those decisions by giving related calls a convenient container. Once the container disappears, an implementation either models the decisions directly or leaves them implicit in process memory.&lt;/p&gt;

&lt;p&gt;Implicit state is the dangerous option. Process memory can tell the current worker what it has seen, but it cannot tell the next worker what already happened after a crash, timeout, reschedule, or deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four crash windows that matter
&lt;/h2&gt;

&lt;p&gt;Consider a tool called &lt;code&gt;issue_refund&lt;/code&gt;. The client sends one request, but the business operation crosses several boundaries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server accepts the intent.&lt;/li&gt;
&lt;li&gt;A worker starts the operation.&lt;/li&gt;
&lt;li&gt;A payment provider applies the refund.&lt;/li&gt;
&lt;li&gt;The server records the provider result.&lt;/li&gt;
&lt;li&gt;The result reaches the client.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;“The request failed” is not one state. It can mean the process died before work began, during local work, after the provider committed the refund, or after the result was stored but before the response arrived. Those states require different recovery behavior.&lt;/p&gt;

&lt;p&gt;If the server blindly replays the whole handler after every timeout, the third window can issue the refund twice. If it never retries once a worker marked the operation started, the first or second window can strand legitimate work forever. If it treats a stored result as proof that the caller received it, the fifth step can silently lose delivery.&lt;/p&gt;

&lt;p&gt;The protocol cannot resolve this ambiguity because the ambiguity belongs to the application. Stateless MCP makes that boundary visible; it does not remove it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A recovery-owner matrix
&lt;/h2&gt;

&lt;p&gt;Before writing retry code, define one logical &lt;code&gt;operation_id&lt;/code&gt; and map every crash window to durable evidence and one owner:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Crash window&lt;/th&gt;
&lt;th&gt;Durable fact required&lt;/th&gt;
&lt;th&gt;Safe recovery action&lt;/th&gt;
&lt;th&gt;Recovery owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Before execution starts&lt;/td&gt;
&lt;td&gt;operation ID, input hash, accepted status&lt;/td&gt;
&lt;td&gt;claim the operation and execute once&lt;/td&gt;
&lt;td&gt;task service or queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;During local execution, before any external effect&lt;/td&gt;
&lt;td&gt;attempt ID and lease expiry&lt;/td&gt;
&lt;td&gt;let the lease expire, then run a new attempt&lt;/td&gt;
&lt;td&gt;worker coordinator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After an external effect, before its result is recorded&lt;/td&gt;
&lt;td&gt;stable idempotency key and side-effect intent&lt;/td&gt;
&lt;td&gt;query or replay through the same idempotency key; never issue a fresh command&lt;/td&gt;
&lt;td&gt;external adapter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After the result is stored, before the client receives it&lt;/td&gt;
&lt;td&gt;immutable result plus delivery status&lt;/td&gt;
&lt;td&gt;return the stored result and retry delivery separately&lt;/td&gt;
&lt;td&gt;API or delivery worker&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table separates three ideas that are often collapsed into &lt;code&gt;status = done&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Execution state&lt;/strong&gt; says whether the logical operation produced a result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Side-effect state&lt;/strong&gt; says what changed outside the worker's database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery state&lt;/strong&gt; says whether the result crossed the final boundary to its consumer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A workable &lt;a href="https://pharosproduction.com/insights/engineering/mcp-server-development/" rel="noopener noreferrer"&gt;stateless MCP server architecture&lt;/a&gt; therefore needs a task record whose lifetime is independent of any one request or server instance. It can be compact, but it must survive the exact failures that are safe to retry.&lt;/p&gt;

&lt;p&gt;This also clarifies what an explicit MCP state handle is for. &lt;a href="https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2567-sessionless-mcp.md" rel="noopener noreferrer"&gt;SEP-2567&lt;/a&gt; replaces implicit session-scoped application state with ordinary server-minted handles that a model can carry between calls. A handle identifies a basket, browser, workflow, or operation. It is not evidence that an effect did or did not happen. The resource behind the handle still needs its own concurrency and recovery contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the operation record the source of truth
&lt;/h2&gt;

&lt;p&gt;A minimal operation record might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"operation_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refund_01J..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"input_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"effect_pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attempt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effect_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refund_01J..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"effect_receipt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"delivery_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_ready"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fields are less important than the invariants around them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reusing an &lt;code&gt;operation_id&lt;/code&gt; with different inputs must fail closed.&lt;/li&gt;
&lt;li&gt;Only one live attempt may own the current lease.&lt;/li&gt;
&lt;li&gt;Every non-idempotent adapter receives a stable effect key.&lt;/li&gt;
&lt;li&gt;A provider receipt is persisted before execution is marked complete.&lt;/li&gt;
&lt;li&gt;Delivery can be retried without rerunning execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This design changes a retry from “call the handler again” into “advance the known operation from its last durable state.” That is the difference between resilience and duplicate execution.&lt;/p&gt;

&lt;p&gt;It also gives observability a useful unit. Logs from server instance A and worker instance B are no longer unrelated request traces; they are attempts attached to one operation. Alerts can distinguish a stuck lease, an uncertain side effect, a completed result awaiting delivery, and a client that simply stopped polling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tasks help with lifecycle, not business idempotency
&lt;/h2&gt;

&lt;p&gt;The 2026-07-28 release also moves long-running work into the Tasks extension. A server can return a task handle, and the client can poll or update that task. That is a better fit for work that outlives one request, but a task handle alone does not make a payment, email, deployment, or repository mutation idempotent.&lt;/p&gt;

&lt;p&gt;The task service can own lifecycle transitions such as accepted, working, input required, completed, failed, or cancelled. The adapter that talks to an external system must still own the effect key and reconciliation behavior. The delivery layer must still own the distinction between “result exists” and “consumer received it.”&lt;/p&gt;

&lt;p&gt;This division prevents a common architectural mistake: asking one status field to describe three independent systems. A queue can truthfully say that a job completed while the email provider timed out after accepting the message. An MCP task can truthfully expose a result while the client disconnects before seeing it. Both statements can be true at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  When this machinery is unnecessary
&lt;/h2&gt;

&lt;p&gt;Not every tool needs an operation ledger. A read-only search can usually be retried from scratch. A deterministic transformation with no external effects may only need request-level timeout handling. A handler whose downstream system provides strong idempotency and queryable receipts can delegate much of the effect recovery to that system.&lt;/p&gt;

&lt;p&gt;There is also a cost to durable recovery: more states, retention rules, reconciliation paths, access control, and tests. Explicit handles can appear in chat logs or subagent context, so authenticated servers should bind a handle to the request's authorization context. For unauthenticated servers, SEP-2567 recommends treating a handle as a short-lived capability token with high entropy.&lt;/p&gt;

&lt;p&gt;The goal is not to make every tool a workflow engine. It is to match the recovery model to the irreversible boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision rule
&lt;/h2&gt;

&lt;p&gt;Use one test: &lt;strong&gt;if retrying the operation can make the outside world different twice, persist the operation and a stable idempotency key before the first side effect.&lt;/strong&gt; If execution and delivery can fail independently, persist them independently. If neither condition is true, keep the design smaller.&lt;/p&gt;

&lt;p&gt;MCP's stateless core is a real improvement because it stops transport sessions from pretending to be application state. The migration is complete only when every durable fact has an explicit home and every retry has one owner.&lt;/p&gt;

&lt;p&gt;Which failure does your implementation still treat as session-owned after the stateless change?&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>architecture</category>
      <category>devops</category>
    </item>
    <item>
      <title>LLM Observability Cost Starts With a Trace Budget</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sun, 09 Aug 2026 17:01:44 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/llm-observability-cost-starts-with-a-trace-budget-401l</link>
      <guid>https://dev.to/dmytronasyrov/llm-observability-cost-starts-with-a-trace-budget-401l</guid>
      <description>&lt;p&gt;LLM observability cost is not a single price per trace. It is the sum of several workload multipliers: requests become traces, traces contain spans, selected spans become evaluation jobs, judges consume tokens, payloads occupy storage, and retention keeps those bytes billable over time.&lt;/p&gt;

&lt;p&gt;The practical fix is to build a &lt;strong&gt;trace budget&lt;/strong&gt; before comparing vendor plans. Start with six variables you can measure in your own application: monthly traces, spans per trace, bytes per span, evaluation sampling rate, judge tokens per score, and retention days. A vendor tier is affordable only after those units have been converted into your workload.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Forecast events, bytes, scores, judge tokens, and retained data separately. Then apply each vendor's meter to the same trace budget. Never compare tier names as if they represented the same physical quantity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article is for engineers and technical leads operating production LLM features. It provides a worked example, a copyable budget receipt, and guardrails that prevent silent cost growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one trace is not one billing unit
&lt;/h2&gt;

&lt;p&gt;A trace represents one end-to-end interaction, but it can contain a changing number of observations. A simple retrieval request might create spans for orchestration, embedding, vector search, reranking, generation, and a tool call. Add retries or parallel tools and the same user request can create more events without increasing request count.&lt;/p&gt;

&lt;p&gt;That is the first trap in AI observability pricing: two systems with 100,000 monthly traces can produce very different ingestion volumes. One may average three spans per trace; the other may average 18. If a platform meters observations, processed bytes, or both, “trace count” is only the first input.&lt;/p&gt;

&lt;p&gt;The budget therefore belongs inside a &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;production AI engineering workflow&lt;/a&gt;, where feature ownership, instrumentation, evaluation, and spend share the same boundary. Otherwise the application team controls trace shape while a separate platform team receives the bill after the multiplier has already changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four cost layers inside LLM observability
&lt;/h2&gt;

&lt;p&gt;Treat the bill as four independent layers. A platform may bundle some of them, but your model should keep them separate.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Ingestion
&lt;/h3&gt;

&lt;p&gt;Ingestion is driven by events or bytes. Its useful variables are monthly traces, observations per trace, and serialized bytes per observation. Recording complete prompts, tool arguments, retrieved documents, and outputs can make byte volume grow much faster than the event count.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Retention
&lt;/h3&gt;

&lt;p&gt;Retention is a volume-time problem. Storing 1 GB for 90 days consumes roughly three times the steady-state capacity of storing the same monthly inflow for 30 days. Indexes, replicas, compression, and vendor-specific accounting can change the invoice, but they do not remove the underlying time multiplier.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Evaluation
&lt;/h3&gt;

&lt;p&gt;Evaluation adds scores. A trace can receive zero, one, or several scores from deterministic checks, human review, or LLM-as-a-judge workflows. The &lt;a href="https://www.braintrust.dev/pricing" rel="noopener noreferrer"&gt;Braintrust pricing model&lt;/a&gt;, for example, exposes processed data, scores, and retention as distinct meters. That separation is a useful reminder that capturing a trace and judging it are different operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Judge-model inference
&lt;/h3&gt;

&lt;p&gt;An LLM judge creates another model call. Its input may include the original prompt, response, retrieved context, rubric, and reference answer. The observability platform's score meter and the model provider's token charge are therefore two different cost lines for the same evaluation job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the LLM observability cost equation
&lt;/h2&gt;

&lt;p&gt;Use a vendor-neutral equation first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monthly_observability_cost =
    ingestion_cost(events, bytes)
  + retention_cost(bytes, days)
  + evaluation_platform_cost(scores)
  + judge_model_cost(input_tokens, output_tokens)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variables become easier to audit when they are arranged as an &lt;a href="https://pharosproduction.com/insights/engineering/llm-observability-cost/" rel="noopener noreferrer"&gt;LLM observability cost model by trace volume&lt;/a&gt;, because every conversion assumption sits beside the meter it converts. For each feature, record these six inputs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;How to measure it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monthly traces&lt;/td&gt;
&lt;td&gt;Count root interactions by feature and environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spans per trace&lt;/td&gt;
&lt;td&gt;Use p50 and p95, not only an average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bytes per span&lt;/td&gt;
&lt;td&gt;Measure serialized payload after redaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluation rate&lt;/td&gt;
&lt;td&gt;Divide scored production traces by eligible traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Judge tokens&lt;/td&gt;
&lt;td&gt;Capture input and output tokens per evaluation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention days&lt;/td&gt;
&lt;td&gt;Record the policy for raw, redacted, and aggregated data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not replace unknown values with zero. Mark them &lt;code&gt;unknown&lt;/code&gt;, add an instrumentation task, and calculate a range. An explicit range is more useful than a precise total built on missing multipliers.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked budget for 100,000 monthly traces
&lt;/h2&gt;

&lt;p&gt;Consider an application with these stated planning assumptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;100,000 traces per month&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6 spans per trace&lt;/strong&gt; on average&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 KB per span&lt;/strong&gt; after redaction and serialization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10% evaluation sampling&lt;/strong&gt;, with one score per selected trace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1,200 judge input tokens&lt;/strong&gt; and &lt;strong&gt;120 judge output tokens&lt;/strong&gt; per score&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;30 days of raw-trace retention&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The conversions are straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;observations = 100,000 × 6 = 600,000
raw_ingestion = 600,000 × 2 KB = 1.2 GB/month
scores = 100,000 × 10% = 10,000/month
judge_input = 10,000 × 1,200 = 12,000,000 tokens/month
judge_output = 10,000 × 120 = 1,200,000 tokens/month
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At a steady ingestion rate, increasing raw retention from 30 to 90 days raises the retained raw-data estimate from about &lt;strong&gt;1.2 GB to 3.6 GB&lt;/strong&gt; before vendor-specific compression, indexing, and replication. Increasing evaluation coverage from 10% to 25% raises the monthly score count from &lt;strong&gt;10,000 to 25,000&lt;/strong&gt; and multiplies both judge-token lines by 2.5.&lt;/p&gt;

&lt;p&gt;These are not market prices. They are workload units. Apply current vendor rates only after this conversion, and keep the rates in a separate configuration so a pricing change does not rewrite the workload model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instrument the inputs, not just the total
&lt;/h2&gt;

&lt;p&gt;A dashboard that shows only total dollars cannot explain a change. Record the dimensions that caused it: feature, environment, model, trace name, observation type, score name, and retention class.&lt;/p&gt;

&lt;p&gt;Langfuse's &lt;a href="https://langfuse.com/docs/observability/best-practices" rel="noopener noreferrer"&gt;trace-structure guidance&lt;/a&gt; describes observations grouped into traces and recommends carrying model, usage, and cost details on generation observations. Stable names matter because a renamed generation can break a cost series even when the application still works.&lt;/p&gt;

&lt;p&gt;Token coverage also needs its own reliability metric. The OpenTelemetry &lt;a href="https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/" rel="noopener noreferrer"&gt;GenAI attribute registry&lt;/a&gt; says instrumentation should make a best effort to populate input-token usage. In practice, that means tracking the percentage of generation spans with usable token counts. A total derived from 62% coverage should not be presented as the full bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four guardrails that keep the trace budget stable
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set an event budget per feature.&lt;/strong&gt; Alert when p95 spans per trace crosses the expected boundary. This catches retry loops and accidental nested instrumentation before the monthly invoice does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample evaluations by decision value.&lt;/strong&gt; Score all release candidates and high-risk paths, then sample routine production traffic. A flat 100% judge rate is rarely the only useful policy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tier retention.&lt;/strong&gt; Keep raw payloads only as long as debugging or audit needs require; retain redacted summaries and aggregate metrics longer when they carry the necessary signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail visibly on missing usage.&lt;/strong&gt; Report token-coverage and byte-coverage percentages beside every cost estimate. Missing telemetry is uncertainty, not free usage.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Review those guardrails whenever a prompt, tool graph, model, evaluator, or retention policy changes. Each can change the bill without changing request volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  A copyable trace-budget receipt
&lt;/h2&gt;

&lt;p&gt;Keep the assumptions next to the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-08&lt;/span&gt;
&lt;span class="na"&gt;feature&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;support-agent&lt;/span&gt;
&lt;span class="na"&gt;monthly_traces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100000&lt;/span&gt;
&lt;span class="na"&gt;spans_per_trace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;p50&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
  &lt;span class="na"&gt;p95&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
&lt;span class="na"&gt;bytes_per_span&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2048&lt;/span&gt;
&lt;span class="na"&gt;evaluation_sample_rate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.10&lt;/span&gt;
&lt;span class="na"&gt;scores_per_sampled_trace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="na"&gt;judge_tokens_per_score&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
&lt;span class="na"&gt;retention_days&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;raw&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
  &lt;span class="na"&gt;aggregate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;365&lt;/span&gt;
&lt;span class="na"&gt;coverage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;token_usage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.98&lt;/span&gt;
  &lt;span class="na"&gt;serialized_bytes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version this receipt with the instrumentation configuration. When the estimate changes, the diff should reveal whether traffic, trace shape, evaluation policy, token usage, or retention caused it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the biggest driver of LLM observability cost?
&lt;/h3&gt;

&lt;p&gt;There is no universal biggest driver. Event-heavy agent workflows amplify span counts, verbose payloads amplify processed bytes, broad judge coverage amplifies scores and model tokens, and long retention amplifies storage. Measure all four layers for your workload before optimizing one of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should every production trace be evaluated?
&lt;/h3&gt;

&lt;p&gt;Usually not by an expensive LLM judge. Evaluate high-risk paths and release candidates deliberately, then sample routine traffic at a rate that can detect meaningful regressions. Deterministic checks and user feedback can cover additional traces without paying judge-model inference for every request.&lt;/p&gt;

&lt;h3&gt;
  
  
  How often should a trace budget be recalculated?
&lt;/h3&gt;

&lt;p&gt;Recalculate monthly and whenever a model, prompt, tool graph, evaluator, sampling rule, payload policy, or retention period changes. Those changes can alter observations, bytes, scores, or tokens even when user traffic remains flat, so request-count monitoring alone will miss the shift.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with units, then compare plans
&lt;/h2&gt;

&lt;p&gt;An LLM observability cost estimate becomes defensible when every price is attached to a measured unit and every unknown remains visible. Count traces, expand them into observations and bytes, apply evaluation coverage, calculate judge tokens, and extend storage across the real retention window.&lt;/p&gt;

&lt;p&gt;Then compare vendors against the same receipt. The cheapest tier name is not the answer. The answer is the plan that fits your measured trace budget without hiding the multiplier most likely to grow next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>observability</category>
      <category>devops</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>AI Coding Agents Need a Handoff Contract, Not More Prompts</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sun, 09 Aug 2026 06:47:56 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/ai-coding-agents-need-a-handoff-contract-not-more-prompts-125o</link>
      <guid>https://dev.to/dmytronasyrov/ai-coding-agents-need-a-handoff-contract-not-more-prompts-125o</guid>
      <description>&lt;p&gt;An AI coding agent is not done when it says “done.” It is done when the next person or agent can accept its work without reconstructing what changed, what was assumed, what was tested, and what remains uncertain.&lt;/p&gt;

&lt;p&gt;That distinction calls for a &lt;strong&gt;handoff contract&lt;/strong&gt;: a small, structured artifact that travels with every patch. It records scope, assumptions, evidence, integration state, residual risk, and the owner of the next acceptance decision. Better prompts can improve code generation. They cannot replace this transfer of responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompts solve generation, not acceptance
&lt;/h2&gt;

&lt;p&gt;Teams often react to a weak agent result by adding another instruction: run tests, check edge cases, avoid unrelated files, explain the diff. These instructions can help. But they still describe what the sender should do; they do not define what the receiver must be able to verify.&lt;/p&gt;

&lt;p&gt;That is why a handoff belongs inside a &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;production software delivery workflow&lt;/a&gt;, where code, evidence, integration state, and acceptance travel as one object. A patch without that context may be locally correct and still be expensive to integrate.&lt;/p&gt;

&lt;p&gt;DORA's analysis of &lt;a href="https://dora.dev/insights/balancing-ai-tensions/" rel="noopener noreferrer"&gt;1,110 open-ended responses from Google software engineers&lt;/a&gt; found that time saved during initial creation was frequently reallocated to auditing, verification, and iteration. The study is qualitative evidence from a specific population, not a universal productivity benchmark. Still, it names a pattern many teams recognize: faster output can move work downstream instead of removing it.&lt;/p&gt;

&lt;p&gt;The same DORA analysis reports a tension between higher AI adoption, greater throughput, and greater delivery instability. Its broader &lt;a href="https://dora.dev/guides/dora-metrics/" rel="noopener noreferrer"&gt;software-delivery metrics framework&lt;/a&gt; deliberately measures both throughput and instability. “The agent produced more code” therefore tells us very little about whether the system can safely absorb that code.&lt;/p&gt;

&lt;h2&gt;
  
  
  A useful definition of a valid handoff
&lt;/h2&gt;

&lt;p&gt;A 2026 survey of agentic electronic design automation defines a valid handoff in terms of the recipient: the transferred artifact must satisfy the next stage's acceptance conditions and carry enough context, evidence, and provenance for that stage to proceed. The paper is about EDA, not general application development, but its &lt;a href="https://arxiv.org/html/2606.19795v1" rel="noopener noreferrer"&gt;handoff perspective&lt;/a&gt; gives software teams a useful design rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Validate the transfer from the receiver's side, not only the work from the sender's side.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That rule changes the completion question from “Did the agent follow the prompt?” to “Can the next consumer make an informed acceptance decision?”&lt;/p&gt;

&lt;h2&gt;
  
  
  The five parts of an agent handoff contract
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Scope
&lt;/h3&gt;

&lt;p&gt;Record the exact requirement, owned files, and forbidden files. “Implement authentication” is not a scope. “Add refresh-token rotation in these three modules without changing the public session schema” is.&lt;/p&gt;

&lt;p&gt;Scope prevents two opposite failures: incomplete work hidden behind a broad completion claim, and unrequested changes that make review harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Assumptions
&lt;/h3&gt;

&lt;p&gt;List the conditions the patch relies on: base commit, interface versions, environment, fixtures, feature flags, data shape, or ordering guarantees. An assumption is not an embarrassment; an invisible assumption is a defect waiting for integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Evidence
&lt;/h3&gt;

&lt;p&gt;Include the exact checks that ran and the results that matter. “Tests pass” is too lossy. A useful receipt names the command, exit status, relevant case count, and any validation that was intentionally not run.&lt;/p&gt;

&lt;p&gt;Evidence should be reproducible and proportional. A one-line configuration change rarely needs a full-system stress run. A persistence or concurrency change needs more than a type checker.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Integration state
&lt;/h3&gt;

&lt;p&gt;Say whether the patch was tested alone, applied to the intended base, combined with adjacent work, and validated through the shared seam it changes. Local green and integrated green are different states.&lt;/p&gt;

&lt;p&gt;This matters even more in &lt;a href="https://pharosproduction.com/services/ai-services/" rel="noopener noreferrer"&gt;production AI evaluation and monitoring systems&lt;/a&gt;, because prompt versions, evaluation results, drift signals, and rollback state must survive every model or workflow change. A locally successful prompt or evaluator is not yet an accepted production change.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Residual risk and acceptance owner
&lt;/h3&gt;

&lt;p&gt;Name what remains unknown, the next consumer, and the decision that consumer owns. “No known risks” is credible only when the evidence supports it. Otherwise, state the boundary plainly: migration behavior was not exercised, browser compatibility remains unverified, or the adjacent branch has not landed.&lt;/p&gt;

&lt;p&gt;The acceptance owner might be a human reviewer, an integration agent, a release gate, or an on-call engineer. The important part is that ownership is explicit.&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%2Fm5lfkew6t0aeutdp0hm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm5lfkew6t0aeutdp0hm1.png" alt="Five-part AI coding agent handoff contract: scope, assumptions, evidence, integration state, and residual risk with an acceptance owner." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The five fields that turn a completion message into an acceptance-ready handoff.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A copyable handoff format
&lt;/h2&gt;

&lt;p&gt;The contract does not need a new platform. Start with a versioned YAML block in the pull request, task artifact, or agent output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;handoff_version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="na"&gt;work_item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AUTH-217&lt;/span&gt;
&lt;span class="na"&gt;producer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coding-agent-session-42&lt;/span&gt;
&lt;span class="na"&gt;base_commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8d31c2a&lt;/span&gt;

&lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;requirement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Rotate refresh tokens after every successful use&lt;/span&gt;
  &lt;span class="na"&gt;owned_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/auth/refresh.ts&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tests/auth/refresh.test.ts&lt;/span&gt;
  &lt;span class="na"&gt;forbidden_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/auth/session-schema.ts&lt;/span&gt;

&lt;span class="na"&gt;assumptions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The token store provides compare-and-swap semantics&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Existing session payload fields remain stable&lt;/span&gt;

&lt;span class="na"&gt;evidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test -- tests/auth/refresh.test.ts&lt;/span&gt;
    &lt;span class="na"&gt;exit_status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12 passed&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run typecheck&lt;/span&gt;
    &lt;span class="na"&gt;exit_status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

&lt;span class="na"&gt;integration_state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;applied_to_base&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;adjacent_changes_combined&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;shared_seam_verified&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="na"&gt;residual_risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Concurrent refresh from two browser tabs was not exercised&lt;/span&gt;

&lt;span class="na"&gt;acceptance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integration-agent&lt;/span&gt;
  &lt;span class="na"&gt;next_gate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Combine the session-store patch and run the auth integration suite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This format makes absence visible. If &lt;code&gt;shared_seam_verified&lt;/code&gt; is false, the workflow does not have to guess whether anyone checked it. If a command is missing, the receiver can request the smallest useful check instead of rerunning everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Agent done” and “handoff valid” are different states
&lt;/h2&gt;

&lt;p&gt;Imagine two agents working in parallel. One changes a serializer. The other adds validation to its consumer. Both run focused tests, both report success, and both are truthful. When combined, the serializer emits a value that the new validator rejects.&lt;/p&gt;

&lt;p&gt;Neither local report captures the failure because the failure exists in the transfer between the two pieces of work. A handoff contract exposes the missing state:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sender report&lt;/th&gt;
&lt;th&gt;Receiver question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;“My tests pass.”&lt;/td&gt;
&lt;td&gt;Were adjacent patches combined?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“The interface is unchanged.”&lt;/td&gt;
&lt;td&gt;Which interface version and invariants were checked?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“No conflicts.”&lt;/td&gt;
&lt;td&gt;Was only textual conflict checked, or behavioral compatibility too?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“Ready to merge.”&lt;/td&gt;
&lt;td&gt;Who owns acceptance, and which gate makes it true?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The contract does not magically prevent the incompatibility. It prevents the workflow from mislabeling unintegrated work as accepted work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the contract from the next consumer's viewpoint
&lt;/h2&gt;

&lt;p&gt;A useful receiver loop has four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check completeness.&lt;/strong&gt; Are all five parts present, or is an omission explicitly marked?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check claims against artifacts.&lt;/strong&gt; Do the diff, base commit, and test receipts support the summary?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the cheapest discriminating gate.&lt;/strong&gt; Test the shared seam before rerunning an entire repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accept, return, or escalate.&lt;/strong&gt; Record the decision and its reason instead of silently repairing the patch downstream.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last step matters. If integrators repeatedly fix incomplete handoffs without returning the signal, the producing agent never receives a useful boundary and the organization hides the true cost of the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start small
&lt;/h2&gt;

&lt;p&gt;Do not begin by building a handoff service. Add the YAML block to one workflow where parallel agents touch a shared interface. Require only fields that change an acceptance decision. Track three outcomes for a few real tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how often the receiver had to reconstruct missing context;&lt;/li&gt;
&lt;li&gt;how often local green became integrated red;&lt;/li&gt;
&lt;li&gt;how long it took to reach an acceptance decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then revise the contract when a missing field causes a real ambiguity. A handoff contract should become smaller and sharper over time, not grow into ceremonial paperwork.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is this just a pull request template?
&lt;/h3&gt;

&lt;p&gt;It can live in a pull request, but it serves a broader role. A PR template is usually organized around human review. A handoff contract is a machine-readable transfer between any producer and the next acceptance stage, including agent-to-agent workflows before a PR exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should the agent decide whether its own handoff is valid?
&lt;/h3&gt;

&lt;p&gt;The agent can validate completeness and attach evidence. Final validity belongs to the receiver because only the receiver owns the next stage's acceptance conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does every task need all five parts?
&lt;/h3&gt;

&lt;p&gt;Yes, but a field can be short. For a tiny documentation edit, integration state may be one sentence and residual risk may be “none identified.” Keeping the schema stable is useful; scaling the evidence to the risk keeps it practical.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real unit of progress
&lt;/h2&gt;

&lt;p&gt;Code generation is an activity. Accepted change is progress.&lt;/p&gt;

&lt;p&gt;Once teams measure the transfer between those states, the next improvement is often not a longer prompt. It is a clearer contract at the boundary: what moved, what it depends on, what proves it, what remains unintegrated, and who can accept it next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>The AI Agents Were Done. The Delivery Clock Wasn’t.</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sat, 08 Aug 2026 06:31:14 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/the-ai-agents-were-done-the-delivery-clock-wasnt-5ah5</link>
      <guid>https://dev.to/dmytronasyrov/the-ai-agents-were-done-the-delivery-clock-wasnt-5ah5</guid>
      <description>&lt;p&gt;&lt;em&gt;The metric that stops at generated code hides review, rework, and acceptance — the work that decides whether the change can ship.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover illustration: the metric stops at generated code while delivery continues through review, rework, validation, and acceptance.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Both AI agents had finished. Their assigned checks passed. Then their patches were combined, and eight of the 24 acceptance methods turned red.&lt;/p&gt;

&lt;p&gt;On sequence 21 of a paused coding study, the integrator needed 19.516 seconds to reconstruct shared branches before all 24 methods passed. If the timer had stopped when the agents reported &lt;code&gt;done&lt;/code&gt;, the run would have looked successful. The delivery clock told a different story.&lt;/p&gt;

&lt;p&gt;AI coding productivity has a finish-line problem. Generated code, a locally green test, and an opened pull request are useful events. None of them proves that a change survived the handoff into the system that must accept it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI does not become productive when output appears. It becomes productive when accepted work moves through the system without exporting more verification than it saves.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  AI coding productivity and the seductive finish line
&lt;/h2&gt;

&lt;p&gt;AI makes activity visible almost immediately. A terminal fills. A diff appears. A worker says the task is complete. Those signals feel like speed because the old blank space has disappeared.&lt;/p&gt;

&lt;p&gt;The study used &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;a production software delivery boundary&lt;/a&gt;: the timer stopped only after the integrated tree passed all 24 frozen methods and the evidence receipt was sealed.&lt;/p&gt;

&lt;p&gt;There are at least four plausible places to stop a coding clock:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the first code is generated;&lt;/li&gt;
&lt;li&gt;the assigned local checks pass;&lt;/li&gt;
&lt;li&gt;the pull request is opened;&lt;/li&gt;
&lt;li&gt;the integrated change reaches its agreed acceptance state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first three are useful telemetry. The fourth is delivery.&lt;/p&gt;

&lt;p&gt;When a team reports only time-to-first-output, it can improve the reported metric while moving work into code review, integration, security checks, rollback preparation, or another person’s queue. The work did not disappear. It changed owners.&lt;/p&gt;

&lt;h2&gt;
  
  
  What one failed merge revealed
&lt;/h2&gt;

&lt;p&gt;Sequence 21 was small enough to inspect. Two agents worked on separate requirement partitions, but both patches touched a shared module. Each patch was locally valid against its assigned checks.&lt;/p&gt;

&lt;p&gt;The seam failed only after integration. Applying the second patch removed branches required by the first combined tree. The first full validation exposed eight failures. The integrator rebuilt the missing paths, reran the suite, and reached 24 of 24.&lt;/p&gt;

&lt;p&gt;No single worker had an obvious local failure. The workflow had a delivery failure.&lt;/p&gt;

&lt;p&gt;That distinction matters because dashboards often reward the event nearest to generation. A faster PR can coexist with a longer review. More accepted suggestions can coexist with larger batches. More completed agent tasks can coexist with a slower path to deployable software.&lt;/p&gt;

&lt;h2&gt;
  
  
  The research is messier — and more useful — than a slogan
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/" rel="noopener noreferrer"&gt;2025 randomized study&lt;/a&gt;, METR observed 16 experienced open-source developers completing 246 real issues in repositories they knew well. In that setting, developers took 19% longer when AI tools were allowed. Before the study, they expected a 24% speedup; afterward, they still believed AI had made them 20% faster.&lt;/p&gt;

&lt;p&gt;That result does not prove that AI slows most developers. METR explicitly limits the claim to the studied people, tools, repositories, and period. It does show that perceived acceleration and measured task completion can point in opposite directions.&lt;/p&gt;

&lt;p&gt;The follow-up became even more revealing. In February 2026, METR said it was &lt;a href="https://metr.org/blog/2026-02-24-uplift-update/" rel="noopener noreferrer"&gt;changing the experiment design&lt;/a&gt; because adoption had altered who would participate and which tasks they would submit. Some developers would not work without AI. Others withheld tasks they did not want randomized into a no-AI condition. Multi-agent use also made time reporting unreliable for part of the sample.&lt;/p&gt;

&lt;p&gt;The honest conclusion was not “AI won” or “AI lost.” It was that the measurement boundary no longer captured the work cleanly.&lt;/p&gt;

&lt;p&gt;The same shift appears outside coding. A &lt;a href="https://www.microsoft.com/en-us/research/publication/the-impact-of-generative-ai-on-critical-thinking-self-reported-reductions-in-cognitive-effort-and-confidence-effects-from-a-survey-of-knowledge-workers/" rel="noopener noreferrer"&gt;Microsoft Research study of 319 knowledge workers&lt;/a&gt; found that AI-assisted work changes where critical effort is applied: away from direct production and toward verification and integration. Generation becomes cheaper while judgment remains attached to the human accepting the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure the acceptance gap
&lt;/h2&gt;

&lt;p&gt;The simplest correction is to add one interval:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Acceptance gap = accepted delivery timestamp − first generated completion timestamp&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gap is not automatically waste. Review, validation, and release decisions can be the work that makes an output safe. The purpose of measuring it is not to force it to zero. The purpose is to stop pretending it is free.&lt;/p&gt;

&lt;p&gt;The same logic appears in &lt;a href="https://pharosproduction.com/services/ai-services/" rel="noopener noreferrer"&gt;production AI evaluation, quality gates, and monitoring&lt;/a&gt;: a plausible output is an intermediate state, while prompt versioning, shadow-mode validation, drift detection, and rollback procedures determine whether it can move forward.&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%2F82m8giqeruv8txxjwcmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82m8giqeruv8txxjwcmf.png" alt="Diagram of a software delivery timeline from generated code through pull request, review, rework, validation, and acceptance. A bracket marks the acceptance gap from first generated completion to accepted delivery." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The acceptance gap begins when generated work first looks complete and ends only at the agreed delivery boundary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is compatible with established delivery measurement. &lt;a href="https://dora.dev/guides/dora-metrics/" rel="noopener noreferrer"&gt;DORA’s current framework&lt;/a&gt; carries change lead time to deployment and pairs throughput with instability measures. It also warns against choosing one metric to rule them all.&lt;/p&gt;

&lt;p&gt;An AI-specific measurement should preserve the same tension: speed matters, and the accepted outcome matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  A five-event measurement card
&lt;/h2&gt;

&lt;p&gt;You do not need a new analytics platform. Capture five timestamps for one recurring task type:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generation complete:&lt;/strong&gt; the agent first presents a supposedly complete change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull request opened:&lt;/strong&gt; the change enters the shared review system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First full validation:&lt;/strong&gt; the complete acceptance suite runs against the integrated state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last rework complete:&lt;/strong&gt; required corrections stop changing the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accepted or deployed:&lt;/strong&gt; the team’s real delivery boundary is crossed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then record three companion values: the number of rework cycles, the number of acceptance failures, and whether the change caused rollback or unplanned follow-up.&lt;/p&gt;

&lt;p&gt;Compare the same task class over time. Do not compare a documentation edit with a payment-system migration and call the difference an AI effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three questions before calling AI productive
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Where does the clock stop?&lt;/strong&gt; If it stops at generation, local green, or PR creation, label the metric accordingly. Do not present an intermediate event as delivery time. The name of the metric should reveal its boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who absorbs verification?&lt;/strong&gt; An agent can reduce the author’s typing while increasing a reviewer’s reconstruction work. Count the human and machine effort needed to reach acceptance, even when it occurs in another queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What counts as failure?&lt;/strong&gt; A rejected patch, rollback, reopened issue, or second validation cycle must remain in the record. Removing inconvenient runs makes the tool look faster by redefining the work after it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the shorter clock is honest
&lt;/h2&gt;

&lt;p&gt;Sometimes AI really does shorten delivery.&lt;/p&gt;

&lt;p&gt;A narrow task with a frozen interface, fast tests, low shared-state risk, and a clear reviewer can move from request to acceptance faster because generation was the actual constraint. If accepted lead time falls while rework and failure do not rise, call it a productivity gain.&lt;/p&gt;

&lt;p&gt;The acceptance gap is not an anti-AI metric. It is what allows a positive result to survive scrutiny.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the finish line after the handoff
&lt;/h2&gt;

&lt;p&gt;The useful question is not whether AI writes code faster. It often does. The useful question is whether the system accepts valuable changes faster after review, integration, and failure recovery are included.&lt;/p&gt;

&lt;p&gt;For one recurring workflow, capture the five events. Keep the task class stable. Preserve failed runs. Then look at both generated speed and accepted delivery.&lt;/p&gt;

&lt;p&gt;That is a narrower claim than “AI transformed productivity.” It is also a definition of AI coding productivity an engineering team can verify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The delivery clock keeps running after the AI says &lt;code&gt;done&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>How We Built Kimlic: Reusable Blockchain-Based KYC with Elixir and Kubernetes</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Tue, 04 Aug 2026 11:05:13 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/how-we-built-kimlic-reusable-blockchain-based-kyc-with-elixir-and-kubernetes-1o74</link>
      <guid>https://dev.to/dmytronasyrov/how-we-built-kimlic-reusable-blockchain-based-kyc-with-elixir-and-kubernetes-1o74</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%2Fdkce21oxbgag6ypef9lj.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%2Fdkce21oxbgag6ypef9lj.jpg" alt="Kimlic KYC platform screenshots" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most KYC systems are built as isolated checkpoints.&lt;/p&gt;

&lt;p&gt;A user uploads an ID document to one service, waits for approval and repeats the same process when joining another platform. The verification may already have been completed successfully, but the result usually remains locked inside the first provider's database.&lt;/p&gt;

&lt;p&gt;For users, each repeated check can take another 15 to 20 minutes. For businesses, a single verification may cost between $5 and $15 while adding friction to the onboarding funnel.&lt;/p&gt;

&lt;p&gt;It also creates a data protection problem. The same sensitive documents can end up stored by many separate companies.&lt;/p&gt;

&lt;p&gt;Kimlic started with a different model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify the user once, create a reusable credential and allow other services to validate the required proof without asking for the same documents again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am the founder and CTO of Pharos Production. Our partnership with Kimlic began in 2018. We worked with the client to design and build a blockchain-based KYC and digital identity platform for Web3 and FinTech products.&lt;/p&gt;

&lt;p&gt;The production system now processes more than 10,000 identity verifications per day with 99.8% verification accuracy.&lt;/p&gt;

&lt;p&gt;This article explains the public architecture behind the platform, the decisions that shaped it and the lessons we learned while building reusable identity infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product challenge
&lt;/h2&gt;

&lt;p&gt;Kimlic needed to connect three requirements that often pull an identity platform in different directions.&lt;/p&gt;

&lt;p&gt;The first was reuse. Users should not have to complete the same verification process for every service.&lt;/p&gt;

&lt;p&gt;The second was privacy. Reuse should not require sensitive personal information to be copied across multiple databases or published on a blockchain.&lt;/p&gt;

&lt;p&gt;The third was compliance. Businesses still needed a reliable way to request a verification, validate its current status and preserve an auditable history of the process.&lt;/p&gt;

&lt;p&gt;The platform also had to operate under real production load:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KYC and AML requirements across at least four jurisdictions&lt;/li&gt;
&lt;li&gt;More than 10,000 verification flows per day&lt;/li&gt;
&lt;li&gt;More than 3,000 concurrent verification sessions&lt;/li&gt;
&lt;li&gt;Response times below three seconds&lt;/li&gt;
&lt;li&gt;99.9% platform uptime&lt;/li&gt;
&lt;li&gt;99.8% verification accuracy&lt;/li&gt;
&lt;li&gt;Secure APIs for external FinTech and Web3 products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was not only a smart contract project.&lt;/p&gt;

&lt;p&gt;It required blockchain engineering, identity workflow design, high-concurrency backend development, cloud infrastructure, auditability and integration APIs to function as one system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blockchain as a proof layer
&lt;/h2&gt;

&lt;p&gt;Using blockchain for KYC does not mean placing passports, addresses or other personal documents on a public ledger.&lt;/p&gt;

&lt;p&gt;That would create an obvious privacy problem. Blockchain data is difficult to remove and can remain visible long after the original business purpose has ended.&lt;/p&gt;

&lt;p&gt;Kimlic uses the blockchain as a verification and proof layer.&lt;/p&gt;

&lt;p&gt;Users complete the identity process through the platform. The system creates cryptographic evidence of the verification while limiting the disclosure of sensitive personal data.&lt;/p&gt;

&lt;p&gt;The reusable credential can then be presented to another service. That service validates the required proof instead of asking the user to upload the same identity documents again.&lt;/p&gt;

&lt;p&gt;At a simplified level, the flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User starts identity verification
                |
                v
Kimlic verification workflow
                |
                v
Identity status and evidence are created
                |
        +-------+--------+
        |                |
        v                v
Metadata and         Cryptographic
audit records        blockchain proof
        |                |
        +-------+--------+
                |
                v
User grants access to a service
                |
                v
Service validates the KYC proof through an API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This division is important.&lt;/p&gt;

&lt;p&gt;The blockchain provides tamper-resistant evidence while the application layer manages identity workflows, consent, access and compliance-related state.&lt;/p&gt;

&lt;p&gt;The result is a portable credential without turning the blockchain into a public personal-data database.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reusable credential is more than a boolean value
&lt;/h2&gt;

&lt;p&gt;It is tempting to represent KYC as one field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;verified = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A production identity platform needs a much richer model.&lt;/p&gt;

&lt;p&gt;The meaning of a verification can depend on when it was completed, which checks were performed and which jurisdictional requirements applied. Its status may also change after the initial decision.&lt;/p&gt;

&lt;p&gt;A reusable credential therefore needs a lifecycle.&lt;/p&gt;

&lt;p&gt;The platform must track the current verification state, the evidence supporting it and the consent under which another business can access it. It also needs an audit trail of important state changes.&lt;/p&gt;

&lt;p&gt;This is one reason we separated the user-facing proof from the complete internal workflow.&lt;/p&gt;

&lt;p&gt;A partner may only need to know whether an acceptable verification exists. The platform still needs the underlying metadata and audit history required to support that answer.&lt;/p&gt;

&lt;p&gt;The score, status or proof presented to an external product is only the visible surface of a larger identity system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The public architecture
&lt;/h2&gt;

&lt;p&gt;The main public technology stack behind Kimlic includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elixir and Erlang&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;React and Next.js&lt;/li&gt;
&lt;li&gt;AWS&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;Terraform&lt;/li&gt;
&lt;li&gt;Blockchain-based cryptographic proofs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       User identity portal
          React / Next.js
                 |
                 |
      Business dashboard and APIs
          React / Next.js
                 |
                 v
      Elixir and Erlang services
   Identity workflows and verification logic
        /             |              \
       /              |               \
      v               v                v
PostgreSQL      Blockchain proof    Integration APIs
metadata,       and credential      for FinTech and
states and      validation          Web3 products
audit logs
      \               |                /
       \              |               /
        +-------------+--------------+
                      |
                      v
            AWS and Kubernetes
                      |
                      v
           Infrastructure as code
                 Terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is intentionally a high-level view. It excludes proprietary verification logic, security controls and implementation details that cannot be published.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we used Elixir and Erlang
&lt;/h2&gt;

&lt;p&gt;Identity verification involves many concurrent workflows.&lt;/p&gt;

&lt;p&gt;Different users can be submitting data, waiting for checks, receiving updated statuses or granting access to business clients at the same time. Each workflow can move independently and may depend on external operations.&lt;/p&gt;

&lt;p&gt;The backend also needs to remain stable when an individual process or integration fails.&lt;/p&gt;

&lt;p&gt;Elixir and Erlang provide a strong foundation for this model. They are well suited to systems with high concurrency, isolated processes and long-running state transitions.&lt;/p&gt;

&lt;p&gt;For Kimlic, the backend is responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identity workflow orchestration&lt;/li&gt;
&lt;li&gt;Verification logic&lt;/li&gt;
&lt;li&gt;API services&lt;/li&gt;
&lt;li&gt;Real-time identity status updates&lt;/li&gt;
&lt;li&gt;Event-driven communication&lt;/li&gt;
&lt;li&gt;Integration with the blockchain proof layer&lt;/li&gt;
&lt;li&gt;Communication with user and business interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key benefit was not language syntax.&lt;/p&gt;

&lt;p&gt;The important factor was the ability to isolate work, process many verification sessions concurrently and recover from failures without treating every exception as a platform-wide incident.&lt;/p&gt;

&lt;p&gt;That became particularly relevant as the system scaled beyond 3,000 concurrent verification sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event-driven identity workflows
&lt;/h2&gt;

&lt;p&gt;A verification process contains a sequence of state changes.&lt;/p&gt;

&lt;p&gt;A user initiates the process. The platform receives the required information. Verification logic evaluates it. The identity status changes and the result becomes available to the user or an authorized business.&lt;/p&gt;

&lt;p&gt;Processing all of this as one large synchronous request would create several problems.&lt;/p&gt;

&lt;p&gt;The request could remain open while the platform waits for another component. A temporary failure could force the complete workflow to restart. Higher traffic could also make the API layer responsible for too much long-running work.&lt;/p&gt;

&lt;p&gt;Kimlic uses event-driven communication and scalable messaging patterns for workflow and state changes.&lt;/p&gt;

&lt;p&gt;This lets different parts of the platform progress independently.&lt;/p&gt;

&lt;p&gt;A request can be accepted, processed and updated without forcing the user interface to hold one connection open for the complete verification lifecycle.&lt;/p&gt;

&lt;p&gt;The architecture also makes it easier to isolate failures. One delayed operation does not need to stop unrelated verification sessions.&lt;/p&gt;

&lt;p&gt;The broader lesson is useful for any regulated workflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Model the business process as a sequence of durable state transitions instead of one oversized request-response operation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  PostgreSQL as the operational source of identity state
&lt;/h2&gt;

&lt;p&gt;The blockchain proof is only one part of the system.&lt;/p&gt;

&lt;p&gt;Kimlic also needs a reliable operational record of identity metadata, current verification states and audit events.&lt;/p&gt;

&lt;p&gt;PostgreSQL serves as the primary data store for that information.&lt;/p&gt;

&lt;p&gt;This separation gives each layer a clear responsibility:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;Identity metadata, workflow states and audit records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blockchain&lt;/td&gt;
&lt;td&gt;Cryptographic proof and tamper-resistant verification evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elixir and Erlang services&lt;/td&gt;
&lt;td&gt;Workflow orchestration, verification logic and APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js interfaces&lt;/td&gt;
&lt;td&gt;User consent, identity management and business access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS and Kubernetes&lt;/td&gt;
&lt;td&gt;Availability, deployment and horizontal scaling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform&lt;/td&gt;
&lt;td&gt;Repeatable infrastructure provisioning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Keeping operational data outside the blockchain also gives the application more control over access patterns and internal workflow changes.&lt;/p&gt;

&lt;p&gt;The blockchain does not need to become the primary database for every identity operation. It is used where its properties add value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy-preserving data sharing
&lt;/h2&gt;

&lt;p&gt;Reusable KYC creates a difficult question:&lt;/p&gt;

&lt;p&gt;How can another service trust the verification without receiving every piece of personal data collected during the original process?&lt;/p&gt;

&lt;p&gt;Kimlic addresses this through selective proof sharing and user consent.&lt;/p&gt;

&lt;p&gt;The user manages the verified identity through a secure interface. When another service requires KYC, the platform shares the necessary proof rather than broadly exposing the complete identity record.&lt;/p&gt;

&lt;p&gt;This model reduces unnecessary document duplication.&lt;/p&gt;

&lt;p&gt;It also creates a clearer access boundary. The consuming service requests a specific verification result while the user retains control over the sharing process.&lt;/p&gt;

&lt;p&gt;From an architecture perspective, privacy depends on more than encryption.&lt;/p&gt;

&lt;p&gt;A privacy-preserving identity platform also needs to control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which data is collected&lt;/li&gt;
&lt;li&gt;Where each category of data is stored&lt;/li&gt;
&lt;li&gt;Which service can request a proof&lt;/li&gt;
&lt;li&gt;Which user action grants access&lt;/li&gt;
&lt;li&gt;Which events must be recorded for an audit&lt;/li&gt;
&lt;li&gt;Which information the receiving business actually needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The safest sensitive record is often the one that never needs to be copied into another system.&lt;/p&gt;

&lt;h2&gt;
  
  
  APIs are part of the compliance product
&lt;/h2&gt;

&lt;p&gt;Kimlic was designed for use by FinTech companies, exchanges and Web3 applications.&lt;/p&gt;

&lt;p&gt;That meant the integration layer could not be treated as a secondary feature.&lt;/p&gt;

&lt;p&gt;External businesses needed secure APIs through which they could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request a KYC verification&lt;/li&gt;
&lt;li&gt;Check the current identity status&lt;/li&gt;
&lt;li&gt;Validate an existing proof&lt;/li&gt;
&lt;li&gt;Integrate the result into onboarding&lt;/li&gt;
&lt;li&gt;Maintain a traceable verification workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API is where the reusable identity model becomes commercially useful.&lt;/p&gt;

&lt;p&gt;Without a stable integration layer, the credential would remain limited to the Kimlic interface. Each new partner would require custom development and the platform would struggle to grow beyond its original use case.&lt;/p&gt;

&lt;p&gt;We therefore treated API design as part of the core architecture.&lt;/p&gt;

&lt;p&gt;The business application should not need to understand the complete internal verification pipeline. It needs a predictable contract for requesting a check and receiving a result.&lt;/p&gt;

&lt;p&gt;That contract also needs to remain stable as internal verification logic evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate interfaces for users and businesses
&lt;/h2&gt;

&lt;p&gt;The platform serves two different audiences.&lt;/p&gt;

&lt;p&gt;Users need to complete verification, view their identity status and manage consent.&lt;/p&gt;

&lt;p&gt;Business clients need to request proofs, review verification results and integrate KYC status into their own systems.&lt;/p&gt;

&lt;p&gt;Kimlic provides React and Next.js interfaces for both groups.&lt;/p&gt;

&lt;p&gt;The user experience focuses on identity management and consent. The business experience provides access to dashboards and APIs for requesting and validating proofs.&lt;/p&gt;

&lt;p&gt;Keeping these concerns separate helped us avoid exposing the full internal workflow to every participant.&lt;/p&gt;

&lt;p&gt;A user does not need a compliance operations dashboard. A business client does not need access to the user's complete identity interface.&lt;/p&gt;

&lt;p&gt;Each audience receives the surface required for its role.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compliance had to influence the architecture
&lt;/h2&gt;

&lt;p&gt;Compliance cannot be added to an identity platform after the technical design is complete.&lt;/p&gt;

&lt;p&gt;The verification model affects data collection. Data retention affects storage. Audit requirements affect event logging. Jurisdictional rules affect workflow behavior and the information a business needs to validate.&lt;/p&gt;

&lt;p&gt;Our engineers worked closely with Kimlic's compliance team while designing the platform.&lt;/p&gt;

&lt;p&gt;The objective was to ensure that technical decisions reflected the KYC and AML requirements of the target jurisdictions from the beginning.&lt;/p&gt;

&lt;p&gt;This included the relationship between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verification evidence&lt;/li&gt;
&lt;li&gt;Identity status&lt;/li&gt;
&lt;li&gt;Consent&lt;/li&gt;
&lt;li&gt;Auditability&lt;/li&gt;
&lt;li&gt;Blockchain proofs&lt;/li&gt;
&lt;li&gt;Business access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform achieved a 100% compliance audit pass rate after deployment while operating across four jurisdictions.&lt;/p&gt;

&lt;p&gt;That outcome came from treating compliance as an architectural input rather than a final checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling the platform on AWS and Kubernetes
&lt;/h2&gt;

&lt;p&gt;Identity onboarding traffic is not always consistent.&lt;/p&gt;

&lt;p&gt;A new partner launch, marketing campaign or customer migration can create a sudden increase in verification sessions. The infrastructure needs to absorb that increase without turning KYC into an onboarding bottleneck.&lt;/p&gt;

&lt;p&gt;Kimlic runs on AWS and Kubernetes.&lt;/p&gt;

&lt;p&gt;The containerized architecture allows services to scale as load increases. Workloads can be deployed and updated independently while Kubernetes handles orchestration and service recovery.&lt;/p&gt;

&lt;p&gt;Terraform manages infrastructure as code.&lt;/p&gt;

&lt;p&gt;This gives the team a repeatable way to provision and change infrastructure while reducing reliance on manual cloud configuration.&lt;/p&gt;

&lt;p&gt;The production platform supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More than 3,000 concurrent verification sessions&lt;/li&gt;
&lt;li&gt;Response times below three seconds&lt;/li&gt;
&lt;li&gt;99.9% uptime&lt;/li&gt;
&lt;li&gt;Automatic scaling during peak onboarding periods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The value of this infrastructure is visible in the user funnel.&lt;/p&gt;

&lt;p&gt;A reliable verification system keeps onboarding moving during high demand. An unreliable system converts infrastructure pressure into abandoned registrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Pharos Production delivered
&lt;/h2&gt;

&lt;p&gt;Pharos Production worked with Kimlic across the complete technical platform rather than delivering one isolated component.&lt;/p&gt;

&lt;p&gt;Our contribution included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blockchain-based credential and proof architecture&lt;/li&gt;
&lt;li&gt;Smart contract engineering&lt;/li&gt;
&lt;li&gt;Identity verification backend services&lt;/li&gt;
&lt;li&gt;Event-driven workflow processing&lt;/li&gt;
&lt;li&gt;KYC and AML integration logic&lt;/li&gt;
&lt;li&gt;PostgreSQL data and audit architecture&lt;/li&gt;
&lt;li&gt;APIs for external FinTech and Web3 products&lt;/li&gt;
&lt;li&gt;User and business web interfaces&lt;/li&gt;
&lt;li&gt;AWS and Kubernetes infrastructure&lt;/li&gt;
&lt;li&gt;Terraform-based infrastructure automation&lt;/li&gt;
&lt;li&gt;Performance and production scaling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The work required coordination between blockchain engineers, backend developers, frontend developers, DevOps specialists and compliance stakeholders.&lt;/p&gt;

&lt;p&gt;That cross-functional delivery model was necessary.&lt;/p&gt;

&lt;p&gt;A smart contract alone cannot run a KYC platform. A verification backend alone cannot create reusable credentials. A compliant workflow still needs reliable infrastructure and a usable integration layer.&lt;/p&gt;

&lt;p&gt;The platform only works when all of those components operate as one product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production results
&lt;/h2&gt;

&lt;p&gt;The public results from the project include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daily identity verifications&lt;/td&gt;
&lt;td&gt;10,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification accuracy&lt;/td&gt;
&lt;td&gt;99.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrent verification sessions&lt;/td&gt;
&lt;td&gt;3,000+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response time&lt;/td&gt;
&lt;td&gt;Below 3 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform uptime&lt;/td&gt;
&lt;td&gt;99.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target jurisdictions&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance audit pass rate&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction in onboarding time&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The measured onboarding completion rate increased from 62% to 89%.&lt;/p&gt;

&lt;p&gt;Verification volume on the same measured workload grew from 20,000 to 140,000 flows per month compared with the pre-optimization baseline.&lt;/p&gt;

&lt;p&gt;These results show the connection between architecture and business performance.&lt;/p&gt;

&lt;p&gt;Reducing duplicate checks shortens onboarding. Reliable processing prevents traffic spikes from blocking users. Reusable proofs lower the amount of work required when the same identity moves between services.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Do not use blockchain as a personal-data database
&lt;/h3&gt;

&lt;p&gt;The blockchain should store the proof required for verification rather than a public copy of the underlying identity documents.&lt;/p&gt;

&lt;p&gt;Immutability is useful for evidence. It becomes a liability when applied to sensitive data that should not remain permanently exposed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Design the credential lifecycle before choosing the stack
&lt;/h3&gt;

&lt;p&gt;A reusable identity is not a static record.&lt;/p&gt;

&lt;p&gt;Define how it is created, updated, validated and shared. Also define which state changes must remain auditable.&lt;/p&gt;

&lt;p&gt;Those decisions shape the backend, data model, APIs and blockchain layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Separate proof from operational state
&lt;/h3&gt;

&lt;p&gt;The blockchain proof and the operational identity workflow serve different purposes.&lt;/p&gt;

&lt;p&gt;Keeping them separate allows each layer to use the storage and access model appropriate to its role.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Treat consent as a system capability
&lt;/h3&gt;

&lt;p&gt;Consent cannot exist only as text next to a checkbox.&lt;/p&gt;

&lt;p&gt;The platform needs to know which user authorized which proof to be shared with which service. That decision must be reflected in the product flow and audit history.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Keep long-running work outside synchronous API requests
&lt;/h3&gt;

&lt;p&gt;Identity checks may depend on several processing steps.&lt;/p&gt;

&lt;p&gt;An event-driven workflow prevents the public API from becoming responsible for waiting on the complete lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Build integration contracts early
&lt;/h3&gt;

&lt;p&gt;Reusable credentials only create network value when other products can consume them.&lt;/p&gt;

&lt;p&gt;Stable APIs and clear business-facing workflows should be designed alongside the identity engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Bring compliance into architecture discussions
&lt;/h3&gt;

&lt;p&gt;Compliance requirements influence data storage, logging, workflow states and access control.&lt;/p&gt;

&lt;p&gt;Involving compliance specialists after implementation usually means redesigning decisions that were already embedded throughout the platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client feedback
&lt;/h2&gt;

&lt;p&gt;Kimlic's CEO highlighted both the production results and the contribution of our engineering team:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Their smart contract expertise and understanding of KYC compliance were critical to our success.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For teams evaluating Pharos Production as a development partner, the complete &lt;a href="https://pharosproduction.com/cases/kimlic-blockchain-based-kyc/" rel="noopener noreferrer"&gt;Kimlic case study&lt;/a&gt; includes the public technology stack, project results and client feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The main value of blockchain-based KYC is not putting identity data on-chain.&lt;/p&gt;

&lt;p&gt;It is making a verified result portable and independently provable while keeping sensitive information under controlled access.&lt;/p&gt;

&lt;p&gt;Kimlic turned that model into a production platform.&lt;/p&gt;

&lt;p&gt;Users can verify once and reuse the result. Businesses receive a compliant API instead of another manual document flow. The infrastructure supports thousands of concurrent sessions while preserving the auditability required for regulated identity workflows.&lt;/p&gt;

&lt;p&gt;For Pharos Production, Kimlic demonstrates how blockchain engineering, high-concurrency backend development and compliance-driven architecture can be combined within one real product.&lt;/p&gt;

&lt;p&gt;Teams building a similar KYC, digital identity or regulated onboarding platform can review the &lt;a href="https://pharosproduction.com/cases/kimlic-blockchain-based-kyc/" rel="noopener noreferrer"&gt;full technical case&lt;/a&gt; and contact us through the project page.&lt;/p&gt;

&lt;p&gt;Which part of reusable KYC creates the harder engineering problem in your experience: privacy, credential portability or regulatory consistency?&lt;/p&gt;

</description>
      <category>web3</category>
      <category>elixir</category>
      <category>architecture</category>
      <category>fintech</category>
    </item>
    <item>
      <title>How We Built Ludo's Real-Time Cross-Chain Reputation Platform</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sat, 25 Jul 2026 21:19:23 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/how-we-built-ludos-real-time-cross-chain-reputation-platform-4e4c</link>
      <guid>https://dev.to/dmytronasyrov/how-we-built-ludos-real-time-cross-chain-reputation-platform-4e4c</guid>
      <description>&lt;p&gt;Public blockchains make transactions visible.&lt;/p&gt;

&lt;p&gt;They do not automatically answer a much more useful product question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can we trust the wallet behind those transactions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am the founder and CTO of &lt;a href="https://pharosproduction.com" rel="noopener noreferrer"&gt;Pharos Production - software development company&lt;/a&gt;. Since 2021, our team has worked with Ludo to build and scale the platform's blockchain indexing, real-time data processing, smart contracts, backend infrastructure and external APIs.&lt;/p&gt;

&lt;p&gt;A wallet may have years of activity across several networks. That history can include transfers, smart contract calls and interactions with hundreds of protocols. The data is public, but turning it into a current and usable trust signal is a separate engineering problem.&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%2Fyzlalv29mp7tps8dvbh4.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%2Fyzlalv29mp7tps8dvbh4.jpg" alt="Ludo platform demo" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is the problem behind &lt;a href="https://ludo.com" rel="noopener noreferrer"&gt;Ludo - Reputation platform of Web3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ludo is a live cross-chain reputation platform that converts onchain behavior into reputation data that users and other Web3 products can consume.&lt;/p&gt;

&lt;p&gt;This article covers the architecture we can discuss publicly, the constraints that shaped it and the engineering lessons we took from the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The production requirements
&lt;/h2&gt;

&lt;p&gt;This was not a prototype built around a small sample of wallets.&lt;/p&gt;

&lt;p&gt;The platform needed to operate across more than 15 blockchain networks while supporting a growing number of users and external integrations.&lt;/p&gt;

&lt;p&gt;The production targets included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More than 2 million scored wallet addresses&lt;/li&gt;
&lt;li&gt;More than 10,000 blockchain events processed per second&lt;/li&gt;
&lt;li&gt;API response times below 200 milliseconds&lt;/li&gt;
&lt;li&gt;99.9% platform uptime&lt;/li&gt;
&lt;li&gt;More than 50 partner integrations&lt;/li&gt;
&lt;li&gt;Real-time reputation updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system also needed to support additional networks without requiring a redesign of the entire processing pipeline.&lt;/p&gt;

&lt;p&gt;Those requirements immediately ruled out an architecture based only on scheduled batch jobs or heavy calculations inside the API request path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reputation is a streaming data problem
&lt;/h2&gt;

&lt;p&gt;A reputation score is useful only while it reflects the current state of a wallet.&lt;/p&gt;

&lt;p&gt;Suppose a score is recalculated once every 24 hours. A wallet can change its behavior shortly after the calculation, while connected products continue making decisions with stale information.&lt;/p&gt;

&lt;p&gt;Calculating the complete score every time an API consumer requests it creates a different problem. The request path becomes responsible for reading and aggregating large amounts of historical data. Latency grows with the amount of activity associated with the wallet.&lt;/p&gt;

&lt;p&gt;For Ludo, we treated reputation as a continuously updated data product.&lt;/p&gt;

&lt;p&gt;Blockchain activity enters the system as a stream. New events are processed as they arrive and the relevant reputation state is updated before an external product requests it.&lt;/p&gt;

&lt;p&gt;That keeps expensive event processing outside the latency-sensitive API path.&lt;/p&gt;

&lt;p&gt;At a simplified level, the architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blockchain networks
        |
        v
Chain-specific indexing
        |
        v
Apache Kafka
        |
        v
Apache Flink
        |
        v
Reputation processing
        |
        +--------------------+
        |                    |
        v                    v
Apache Cassandra       Apache Pinot
        |                    |
        +----------+---------+
                   |
                   v
        Spring Boot API services
                   |
        +----------+-----------+----------------+
        |                      |                |
        v                      v                v
   Web platform       Browser extension   Partner APIs
                                                |
                                                v
                                      External Web3 products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a public, simplified view. It intentionally leaves out proprietary scoring rules and internal data models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separating blockchain ingestion from reputation logic
&lt;/h2&gt;

&lt;p&gt;Supporting more than 15 networks creates a problem that has little to do with the scoring formula itself.&lt;/p&gt;

&lt;p&gt;Different chains expose different data structures, finality models and indexing behavior. Even similar actions can be represented differently from one network to another.&lt;/p&gt;

&lt;p&gt;If every downstream service has to understand the native format of every blockchain, adding a new network becomes progressively more expensive. The scoring layer also becomes tightly coupled to chain-specific implementation details.&lt;/p&gt;

&lt;p&gt;The architecture therefore needs a clear boundary between blockchain ingestion and reputation processing.&lt;/p&gt;

&lt;p&gt;Chain-specific indexing is responsible for reading the network and translating relevant activity into a consistent internal representation. Downstream processing can then operate on normalized events instead of repeatedly interpreting raw chain data.&lt;/p&gt;

&lt;p&gt;This separation helped our team deliver production-grade indexing for additional blockchain networks without rebuilding the rest of the platform each time.&lt;/p&gt;

&lt;p&gt;The broader lesson is straightforward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Normalize chain-specific behavior at the system boundary. Do not allow native blockchain formats to spread through the complete backend.&lt;/p&gt;
&lt;/blockquote&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%2Fjhcecxmb2aw0aka2hm1k.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%2Fjhcecxmb2aw0aka2hm1k.jpg" alt="Ludo Web3 Reputation Dashboard" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kafka as the event backbone
&lt;/h2&gt;

&lt;p&gt;Apache Kafka handles the continuous stream of blockchain activity.&lt;/p&gt;

&lt;p&gt;Its role is larger than moving data between two services. Kafka provides a durable boundary between ingestion and processing.&lt;/p&gt;

&lt;p&gt;Blockchain indexers can publish events without being directly coupled to every consumer. Processing services can evolve independently and additional consumers can be introduced without modifying the indexing layer.&lt;/p&gt;

&lt;p&gt;This matters in a reputation platform because the same source activity may eventually support several workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reputation state updates&lt;/li&gt;
&lt;li&gt;Historical analysis&lt;/li&gt;
&lt;li&gt;Product dashboards&lt;/li&gt;
&lt;li&gt;Audit and traceability&lt;/li&gt;
&lt;li&gt;New scoring models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kafka also makes it possible to absorb short-term differences between the rate at which events arrive and the rate at which downstream services process them.&lt;/p&gt;

&lt;p&gt;For this type of system, partitioning requires particular care. Events that update the same logical entity need predictable processing order while the workload still needs to be distributed across the cluster.&lt;/p&gt;

&lt;p&gt;The exact partitioning model depends on the product's scoring rules, but the general requirement is consistent: ordering guarantees and horizontal scalability must be considered together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flink for incremental processing
&lt;/h2&gt;

&lt;p&gt;Apache Flink processes blockchain events as they move through the system.&lt;/p&gt;

&lt;p&gt;The important architectural decision was to update reputation state incrementally rather than repeatedly rebuilding it from the wallet's entire history.&lt;/p&gt;

&lt;p&gt;When a relevant event arrives, the processing layer determines how that event affects the existing reputation state. The updated result can then be persisted for fast retrieval.&lt;/p&gt;

&lt;p&gt;This approach provides two advantages.&lt;/p&gt;

&lt;p&gt;First, the amount of processing required for a new event does not need to grow with the complete age of the wallet.&lt;/p&gt;

&lt;p&gt;Second, the score can remain current without forcing API consumers to wait for historical aggregation.&lt;/p&gt;

&lt;p&gt;Real-time processing also introduces operational questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How should duplicate events be handled?&lt;/li&gt;
&lt;li&gt;What happens when events arrive late?&lt;/li&gt;
&lt;li&gt;How should a chain reorganization affect derived state?&lt;/li&gt;
&lt;li&gt;How can a calculation be replayed after scoring logic changes?&lt;/li&gt;
&lt;li&gt;Which state must remain auditable?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions cannot be solved by selecting a stream-processing framework alone. They need to be part of the data model and operating procedures from the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using different storage systems for different workloads
&lt;/h2&gt;

&lt;p&gt;A platform like Ludo does not have one universal database workload.&lt;/p&gt;

&lt;p&gt;Operational reputation state, historical data and real-time analytical queries have different access patterns. Forcing all of them into one database would simplify the technology list while making the system harder to scale.&lt;/p&gt;

&lt;p&gt;The public architecture uses several specialized components.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Primary role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apache Cassandra&lt;/td&gt;
&lt;td&gt;Scalable storage for user and reputation data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Pinot&lt;/td&gt;
&lt;td&gt;Low-latency real-time analytics and query workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delta Lake&lt;/td&gt;
&lt;td&gt;Organized historical data for analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Kafka&lt;/td&gt;
&lt;td&gt;Durable blockchain event streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Flink&lt;/td&gt;
&lt;td&gt;Stateful real-time event processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spring Boot&lt;/td&gt;
&lt;td&gt;Backend services, APIs and reputation logic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cassandra supports distributed operational storage where the access patterns are known and horizontal scale matters.&lt;/p&gt;

&lt;p&gt;Pinot serves analytical workloads that need fresh data and low query latency. This is useful for dashboards, curation tools and API consumers that need to filter or analyze reputation information.&lt;/p&gt;

&lt;p&gt;Delta Lake retains organized historical data for deeper analysis and long-term processing.&lt;/p&gt;

&lt;p&gt;This is a deliberate use of polyglot persistence. Each system has an explicit responsibility instead of becoming another item in the stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping the API path fast
&lt;/h2&gt;

&lt;p&gt;The platform needed to keep API response times below 200 milliseconds.&lt;/p&gt;

&lt;p&gt;The main architectural principle behind that target was to avoid performing full reputation calculations during an external request.&lt;/p&gt;

&lt;p&gt;By the time an API call arrives, the stream-processing layer has already processed relevant blockchain activity and updated the materialized reputation state.&lt;/p&gt;

&lt;p&gt;The API layer can focus on controlled retrieval, authorization and response construction.&lt;/p&gt;

&lt;p&gt;Spring Boot provides the backend foundation for these services. It also gives the platform a consistent way to expose reputation data to different consumers.&lt;/p&gt;

&lt;p&gt;Those consumers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Ludo web platform&lt;/li&gt;
&lt;li&gt;A browser extension&lt;/li&gt;
&lt;li&gt;A Telegram Mini App&lt;/li&gt;
&lt;li&gt;Curator tools&lt;/li&gt;
&lt;li&gt;External Web3 products&lt;/li&gt;
&lt;li&gt;Mobile integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platform also represents reputation through soulbound NFTs. Since these assets cannot be transferred or sold, the representation stays connected to the wallet activity that produced it.&lt;/p&gt;

&lt;p&gt;The NFT is the verifiable product surface. The streaming and scoring infrastructure behind it is what keeps the representation current.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration is part of the product
&lt;/h2&gt;

&lt;p&gt;It is easy to treat APIs and documentation as work that happens after the main platform is complete.&lt;/p&gt;

&lt;p&gt;That approach would have limited Ludo's value.&lt;/p&gt;

&lt;p&gt;A cross-chain reputation system becomes more useful when other products can place its trust signal inside their own workflows. That makes developer experience part of the architecture rather than a separate documentation task.&lt;/p&gt;

&lt;p&gt;Pharos Production developed and documented APIs for external platforms. We also created SDKs and integration materials intended to reduce the amount of custom work required from each partner.&lt;/p&gt;

&lt;p&gt;The result was a reduction of more than 60% in partner onboarding time.&lt;/p&gt;

&lt;p&gt;More than 50 partners now use the platform across Web3 use cases including DeFi, gaming and social products.&lt;/p&gt;

&lt;p&gt;The lesson applies beyond blockchain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An infrastructure product is not complete when its internal services work. It is complete when another team can integrate it safely without depending on its original developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Infrastructure and reliability
&lt;/h2&gt;

&lt;p&gt;The platform runs on AWS with Kubernetes and Istio.&lt;/p&gt;

&lt;p&gt;Kubernetes provides the orchestration layer needed to deploy and scale independently evolving services. Istio handles service traffic management across the cluster.&lt;/p&gt;

&lt;p&gt;Terraform supports repeatable infrastructure management while continuous load testing verifies that performance remains within the required range as the platform changes.&lt;/p&gt;

&lt;p&gt;This operating model was designed around two practical requirements.&lt;/p&gt;

&lt;p&gt;The first was traffic variability. Blockchain activity and partner demand do not always grow at a predictable rate.&lt;/p&gt;

&lt;p&gt;The second was continuous expansion. Adding networks and integrations introduces new services, data flows and deployment requirements.&lt;/p&gt;

&lt;p&gt;The infrastructure therefore needed to scale during traffic spikes without interrupting the products that rely on the reputation API.&lt;/p&gt;

&lt;p&gt;The resulting platform maintains 99.9% uptime while processing more than 10,000 blockchain events per second without long queuing delays or data loss.&lt;/p&gt;

&lt;p&gt;At this scale, uptime and latency are not only infrastructure metrics. They are part of the trust model.&lt;/p&gt;

&lt;p&gt;A reputation signal is difficult to depend on when the API becomes unavailable during the exact periods when activity increases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Pharos Production delivered
&lt;/h2&gt;

&lt;p&gt;Our work on Ludo covered more than one isolated service.&lt;/p&gt;

&lt;p&gt;Pharos Production contributed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart contracts deployed across multiple blockchain networks&lt;/li&gt;
&lt;li&gt;Cross-chain indexing and data aggregation&lt;/li&gt;
&lt;li&gt;Real-time event-processing infrastructure&lt;/li&gt;
&lt;li&gt;Reputation backend services&lt;/li&gt;
&lt;li&gt;Scalable server architecture&lt;/li&gt;
&lt;li&gt;Web and mobile integration APIs&lt;/li&gt;
&lt;li&gt;API documentation and SDKs&lt;/li&gt;
&lt;li&gt;Web, browser and Telegram product interfaces&lt;/li&gt;
&lt;li&gt;AWS and Kubernetes infrastructure&lt;/li&gt;
&lt;li&gt;Performance testing and production scaling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project required blockchain engineering, backend architecture, data engineering and DevOps work to function as one delivery stream.&lt;/p&gt;

&lt;p&gt;That combination is important.&lt;/p&gt;

&lt;p&gt;A scoring model cannot become a reliable product without current source data. A data pipeline cannot create value without an accessible API. An API cannot become infrastructure for other businesses without predictable performance and operational reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production results
&lt;/h2&gt;

&lt;p&gt;The current public project results are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Supported blockchain networks&lt;/td&gt;
&lt;td&gt;15+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scored wallet addresses&lt;/td&gt;
&lt;td&gt;2M+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processing throughput&lt;/td&gt;
&lt;td&gt;10K+ events per second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API response time&lt;/td&gt;
&lt;td&gt;Below 200 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform uptime&lt;/td&gt;
&lt;td&gt;99.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partner integrations&lt;/td&gt;
&lt;td&gt;50+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction in partner onboarding time&lt;/td&gt;
&lt;td&gt;More than 60%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These figures are useful as proof of scale, but the more important result is architectural.&lt;/p&gt;

&lt;p&gt;Ludo moved from a Web3 reputation concept to production infrastructure that other products can use inside live workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five lessons I would carry into another real-time Web3 platform
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Start with the product decision
&lt;/h3&gt;

&lt;p&gt;A reputation score has no meaning without the decision it is intended to support.&lt;/p&gt;

&lt;p&gt;Before choosing a database or writing a scoring formula, define what another person or system will do with the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Make freshness an explicit requirement
&lt;/h3&gt;

&lt;p&gt;"Real time" should not be a vague product claim.&lt;/p&gt;

&lt;p&gt;Define how quickly a blockchain event must affect the result. That decision shapes ingestion, processing, storage and API design.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Isolate chain-specific complexity
&lt;/h3&gt;

&lt;p&gt;Each new blockchain will introduce its own implementation details.&lt;/p&gt;

&lt;p&gt;Keep those details at the indexing boundary and give downstream systems a stable internal event model.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Keep heavy computation outside the request path
&lt;/h3&gt;

&lt;p&gt;An API with a strict latency target should retrieve prepared state rather than rebuild it from complete historical data.&lt;/p&gt;

&lt;p&gt;Streaming and materialized state make that possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Design external integration from the beginning
&lt;/h3&gt;

&lt;p&gt;Documentation, SDKs, versioning and predictable API behavior are core parts of an infrastructure product.&lt;/p&gt;

&lt;p&gt;They should not be postponed until after the internal platform is considered finished.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client perspective
&lt;/h2&gt;

&lt;p&gt;Sergiu Draganus, co-founder and CEO of Ludo, has publicly confirmed that Pharos Production delivered the project's smart contracts, cross-chain data aggregation, scalable server infrastructure and documented integration APIs.&lt;/p&gt;

&lt;p&gt;For teams carrying out technical vendor due diligence, Sergiu can provide a first-hand client reference about the collaboration and the process of building the platform with Pharos Production.&lt;/p&gt;

&lt;p&gt;You can also review the &lt;a href="https://pharosproduction.com/cases/ludo-reputation-platform-of-web3/" rel="noopener noreferrer"&gt;complete Ludo case study&lt;/a&gt; with the project stack, results and client feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Public blockchain data does not create trust by itself.&lt;/p&gt;

&lt;p&gt;It provides evidence.&lt;/p&gt;

&lt;p&gt;The engineering challenge is to collect that evidence across networks, process it while it is still current and deliver it through infrastructure that other products can reliably use.&lt;/p&gt;

&lt;p&gt;That is what our teams built with Ludo.&lt;/p&gt;

&lt;p&gt;Where would you draw the boundary between a universal cross-chain reputation score and a score designed for one specific product?&lt;/p&gt;

</description>
      <category>web3</category>
      <category>ai</category>
      <category>llm</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>What Is MiCA? The EU Crypto-Assets Regulation Explained</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sun, 28 Jun 2026 22:08:15 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/what-is-mica-the-eu-crypto-assets-regulation-explained-22gk</link>
      <guid>https://dev.to/dmytronasyrov/what-is-mica-the-eu-crypto-assets-regulation-explained-22gk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;One rulebook for crypto across 27 EU states: who it applies to, the token categories, the timeline and what compliance actually requires.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;MiCA (Markets in Crypto-Assets Regulation) is the EU's single framework for crypto-assets, applying across all 27 member states with one passport for authorized firms.&lt;/li&gt;
&lt;li&gt;It covers crypto-asset service providers (CASPs) and stablecoin issuers, which fall into three token categories: asset-referenced tokens (ART), e-money tokens (EMT) and other crypto-assets.&lt;/li&gt;
&lt;li&gt;Rules applied in phases: stablecoins from June 2024, CASPs from December 2024, with national transition into 2025-2026.&lt;/li&gt;
&lt;li&gt;Compliance is architectural, not a bolt-on: KYC/AML, transaction monitoring, market-abuse surveillance and proof of reserves must be built into the platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MiCA (Markets in Crypto-Assets Regulation) is the European Union's comprehensive framework for regulating crypto-assets and the firms that issue or service them.&lt;/strong&gt; It applies across all 27 EU member states, replacing a patchwork of national rules with a single regime and a passport that lets an authorized firm operate EU-wide. MiCA covers crypto-asset service providers (CASPs), stablecoin issuers and crypto-asset white papers, and it became fully applicable through 2024 and 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MiCA?
&lt;/h2&gt;

&lt;p&gt;MiCA stands for Markets in Crypto-Assets. It is an EU regulation (Regulation 2023/1114) that creates harmonized rules for the issuance, offer and trading of crypto-assets and for the provision of crypto-asset services. Before MiCA, crypto firms faced 27 different national approaches. MiCA replaces that with one rulebook: a firm authorized in one member state can passport its services across the entire EU and EEA, the same single-market model that governs traditional finance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who does MiCA apply to?
&lt;/h2&gt;

&lt;p&gt;MiCA applies to two broad groups: issuers of crypto-assets and crypto-asset service providers (CASPs). CASPs include exchanges, custodians, brokers, trading platforms, portfolio managers and advisers. Issuers of asset-referenced tokens and e-money tokens face additional requirements around reserves and authorization. If you operate any crypto business serving EU customers you are likely in scope. See &lt;a href="https://pharosproduction.com/insights/engineering/mica-casp-services-explained/" rel="noopener noreferrer"&gt;the 10 CASP services under MiCA&lt;/a&gt; for the full breakdown of regulated activities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three categories of crypto-assets under MiCA
&lt;/h2&gt;

&lt;p&gt;MiCA classifies crypto-assets into three types, each with different rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asset-referenced tokens (ART): tokens that reference multiple currencies, commodities or crypto-assets to maintain stable value.&lt;/li&gt;
&lt;li&gt;E-money tokens (EMT): tokens that reference a single official currency, functioning like electronic money.&lt;/li&gt;
&lt;li&gt;Other crypto-assets: utility tokens and most other tokens not covered by existing financial rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Getting this classification right determines which obligations apply. &lt;a href="https://pharosproduction.com/insights/engineering/art-vs-emt-mica-token-classification/" rel="noopener noreferrer"&gt;Our guide to ART vs EMT classification&lt;/a&gt; explains the boundaries and the software each token type needs. Where a token behaves like a financial instrument, MiCA may not apply at all - &lt;a href="https://pharosproduction.com/insights/engineering/mica-vs-mifid-ii-financial-instruments/" rel="noopener noreferrer"&gt;MiCA vs MiFID II&lt;/a&gt; covers that line.&lt;/p&gt;

&lt;h2&gt;
  
  
  MiCA timeline: when did it take effect?
&lt;/h2&gt;

&lt;p&gt;MiCA entered into force in 2023 and became applicable in phases. The rules for stablecoins (asset-referenced and e-money tokens) applied from June 2024, and the rules for crypto-asset service providers applied from December 2024, with national transitional periods running into 2025 and 2026. Firms operating in the EU need authorization or must wind down activities once their transitional window closes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key MiCA requirements
&lt;/h2&gt;

&lt;p&gt;MiCA obligations span the full lifecycle of a crypto business:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CASP authorization: a licensing process with capital, governance and custody requirements.&lt;/li&gt;
&lt;li&gt;Crypto-asset white papers: mandatory disclosure documents for token offerings.&lt;/li&gt;
&lt;li&gt;Market abuse rules (Title VI): prohibitions on insider dealing, wash trading and spoofing, with surveillance obligations - see &lt;a href="https://pharosproduction.com/insights/engineering/crypto-market-abuse-mica-title-vi/" rel="noopener noreferrer"&gt;crypto market abuse under MiCA Title VI&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Reserves and safeguarding: stablecoin issuers must hold and prove adequate reserves.&lt;/li&gt;
&lt;li&gt;KYC, AML and the Travel Rule: onboarding and transaction-monitoring duties - see &lt;a href="https://pharosproduction.com/insights/engineering/mica-kyc-requirements-2026/" rel="noopener noreferrer"&gt;MiCA KYC requirements&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full operational picture is in our &lt;a href="https://pharosproduction.com/insights/engineering/mica-compliance-checklist-2026/" rel="noopener noreferrer"&gt;MiCA compliance checklist&lt;/a&gt;, and the spend involved is broken down in &lt;a href="https://pharosproduction.com/insights/business/mica-compliance-cost-2026/" rel="noopener noreferrer"&gt;MiCA compliance cost in 2026&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  MiCA vs other crypto regulations
&lt;/h2&gt;

&lt;p&gt;MiCA is the most comprehensive crypto framework globally, but it is not the only one. The UK, US and Dubai take different approaches, which matters for firms operating across borders. Our &lt;a href="https://pharosproduction.com/insights/business/mica-vs-uk-us-dubai-crypto-compliance/" rel="noopener noreferrer"&gt;MiCA vs UK, US and Dubai compliance map&lt;/a&gt; compares the regimes. Within the EU, the key boundary question is whether a token is a financial instrument under &lt;a href="https://pharosproduction.com/insights/engineering/mica-vs-mifid-ii-financial-instruments/" rel="noopener noreferrer"&gt;MiFID II rather than MiCA&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What MiCA means for crypto software
&lt;/h2&gt;

&lt;p&gt;MiCA compliance is architectural, not a bolt-on. CASP authorization, transaction monitoring, market-abuse surveillance, proof of reserves and Travel Rule data exchange all have to be built into the platform. Retrofitting them after launch is expensive and risky. Pharos Production builds &lt;a href="https://pharosproduction.com/industries/mica-compliance-software-development/" rel="noopener noreferrer"&gt;MiCA compliance software&lt;/a&gt; - KYC/AML platforms, transaction monitoring and regulatory reporting - designed for CASPs and stablecoin issuers operating under the regulation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reviewed by Dmytro Nasyrov, Founder and CTO, Pharos Production.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://pharosproduction.com/insights/engineering/what-is-mica/" rel="noopener noreferrer"&gt;pharosproduction.com/insights/engineering/what-is-mica/&lt;/a&gt;. Written by Dmytro Nasyrov, Founder and CTO at &lt;a href="https://pharosproduction.com/dmytro-nasyrov/" rel="noopener noreferrer"&gt;Pharos Production&lt;/a&gt;, a &lt;a href="https://pharosproduction.com/industries/mica-compliance-software-development/" rel="noopener noreferrer"&gt;MiCA compliance software&lt;/a&gt; company.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mica</category>
      <category>cryptoregulation</category>
      <category>web3</category>
      <category>fintech</category>
    </item>
    <item>
      <title>State of Smart Contract Audits 2026: What 30+ Engagements Tell Us About Cost, Quality and Coverage</title>
      <dc:creator>Dmytro Nasyrov</dc:creator>
      <pubDate>Sun, 28 Jun 2026 22:07:34 +0000</pubDate>
      <link>https://dev.to/dmytronasyrov/state-of-smart-contract-audits-2026-what-30-engagements-tell-us-about-cost-quality-and-coverage-5em</link>
      <guid>https://dev.to/dmytronasyrov/state-of-smart-contract-audits-2026-what-30-engagements-tell-us-about-cost-quality-and-coverage-5em</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Real audit pricing tiers, critical-bug density and the findings that actually dominate in 2026 - from a 30+ engagement archive.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Top-tier smart contract audits in 2026 cost 80,000-350,000 USD per scope. Mid-tier 25,000-80,000 USD. Boutique 8,000-25,000 USD. Source: Pharos engagement archive 2024-2026 cross-checked against public OpenZeppelin and Trail of Bits engagement disclosures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Critical bug density per 1,000 lines of Solidity averaged 0.4-0.7 across our 2023-2025 engagements before remediation. Industry public reports cluster between 0.3 and 1.1 (Pharos internal data, Halborn 2025 Web3 Threat Report).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reentrancy is no longer the top finding. Oracle manipulation, access-control drift and cross-chain message replay now dominate critical findings (Chainalysis 2025, CertiK Hack3d 2024).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-firm audit cycles - two independent firms in shadow mode - are now standard for any TVL above 50M USD. Single-firm audits correlate with higher post-launch incident rates in our sample.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formal verification adoption crossed an inflection point in 2025. Roughly one third of our high-value engagements now ship with at least one Certora or Halmos invariant suite alongside the human review.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pharos Production runs &lt;a href="https://pharosproduction.com/services/security-audits-and-gas-optimization/" rel="noopener noreferrer"&gt;smart contract security audits&lt;/a&gt; and &lt;a href="https://pharosproduction.com/services/smart-contracts-development/" rel="noopener noreferrer"&gt;smart contract development&lt;/a&gt; for DeFi and Web3 teams. The data below comes from that engagement archive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;p&gt;This piece combines two data sources. First, the Pharos engagement archive 2018-2026, covering more than 30 smart contract audit and audit-adjacent projects across Ethereum, Polygon, BNB Chain, Solana and several L2 rollups. Engagements span DeFi protocols, NFT systems, cross-chain bridges, RWA platforms and FinTech custody backends. Names are withheld under NDA. Numbers are reported as ranges, not per-client identifiers.&lt;/p&gt;

&lt;p&gt;Second, public data from tier-1 audit firms and incident trackers: &lt;a href="https://github.com/trailofbits/publications" rel="noopener noreferrer"&gt;Trail of Bits publication archive&lt;/a&gt;, &lt;a href="https://blog.openzeppelin.com/security-audits/" rel="noopener noreferrer"&gt;OpenZeppelin audit reports&lt;/a&gt;, &lt;a href="https://consensys.io/diligence/audits/" rel="noopener noreferrer"&gt;ConsenSys Diligence audit archive&lt;/a&gt;, &lt;a href="https://www.halborn.com/blog" rel="noopener noreferrer"&gt;Halborn research blog&lt;/a&gt;, &lt;a href="https://www.certik.com/resources/blog" rel="noopener noreferrer"&gt;CertiK Hack3d annual reports&lt;/a&gt;, &lt;a href="https://www.chainalysis.com/reports/" rel="noopener noreferrer"&gt;Chainalysis Crypto Crime Report 2025&lt;/a&gt; and &lt;a href="https://defillama.com/" rel="noopener noreferrer"&gt;DeFiLlama exploit data&lt;/a&gt;. Where Pharos internal numbers and industry data agree we treat the claim as well supported. Where they disagree we flag it.&lt;/p&gt;

&lt;p&gt;All figures are advisory not financial advice. Sample bias is discussed in section 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit Cost Trends 2024-2026
&lt;/h2&gt;

&lt;p&gt;Audit cost is a function of scope complexity, code novelty, deadline and firm reputation - not lines of code alone. Across our 2024-2026 engagements pricing settled into three tiers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boutique tier&lt;/strong&gt; - small specialist teams, 8,000-25,000 USD per scope. Useful for narrow contracts, library forks or pre-launch sanity checks. Boutique findings are typically high signal but low coverage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mid tier&lt;/strong&gt; - established regional firms with 5-15 auditors, 25,000-80,000 USD. This is where most production DeFi protocols below 50M USD TVL get their first audit. Reports are formatted, fix-cycle is included, response time is days not weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top tier&lt;/strong&gt; - Trail of Bits, OpenZeppelin, ConsenSys Diligence, Halborn, Spearbit, Cantina, Sigma Prime - 80,000-350,000 USD and up. Engagements at the high end include formal specification review, fuzzing harness construction and post-deploy retainer time. Booking lead time was 4-8 weeks in 2024 and has since compressed to 2-4 weeks for most firms (Pharos internal observation, cross-checked against OpenZeppelin public scheduling data).&lt;/p&gt;

&lt;p&gt;Regional variation matters. EU and US firms charge a 30-60 percent premium over equally credentialed Asia-Pacific and Eastern European firms for comparable scopes. We see no quality delta in the report quality of mid-tier non-US firms in our sample.&lt;/p&gt;

&lt;p&gt;Trend to watch - multi-firm audits. For any deployment with TVL projection above 50M USD a two-firm shadow audit is now table stakes. &lt;a href="https://a16zcrypto.com/posts/" rel="noopener noreferrer"&gt;a16z crypto&lt;/a&gt; and Paradigm portfolio guidance both reflect this. Cost goes up roughly 1.6-1.8x not 2x, since the second firm often runs in parallel with a narrower invariant focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug Density per 1k LOC
&lt;/h2&gt;

&lt;p&gt;Bug density is the most useful single number for engineering managers planning remediation budget. Across 30+ Pharos engagements, pre-remediation findings broke down approximately as follows per 1,000 lines of Solidity (excluding test code, comments and OpenZeppelin imports). These are Pharos internal observations.&lt;/p&gt;

&lt;p&gt;SeverityPer 1k LOC, our sampleNotes&lt;/p&gt;

&lt;p&gt;Critical0.4-0.7Direct loss-of-funds or admin takeover paths&lt;br&gt;
High1.1-1.8Logic flaws requiring privileged or unlikely conditions&lt;br&gt;
Medium2.5-4.0DoS, griefing, accounting drift&lt;br&gt;
Low4-8Style, gas inefficiency, minor edge cases&lt;br&gt;
Informational6-15Documentation, naming, missing events&lt;/p&gt;

&lt;p&gt;Public Halborn and CertiK reports cluster critical density between 0.3 and 1.1 per 1k LOC depending on protocol category. Bridges and cross-chain messaging consistently show the highest density, simple ERC-20 forks the lowest. Our numbers sit inside that band, weighted toward DeFi which is most of our engagement mix.&lt;/p&gt;

&lt;p&gt;A useful planning heuristic - budget at least 1 engineering week per critical and high finding for fix and re-test. For a 5,000 LOC codebase that is typically 8-12 engineer-weeks of remediation before re-audit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Most Common Vulnerability Classes 2024-2026
&lt;/h2&gt;

&lt;p&gt;Reentrancy taught a generation of Solidity developers and is now commodity-defended. The dominant classes in 2024-2026 are different.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Oracle manipulation - low-liquidity TWAP windows, spot-price reads, unverified Chainlink fallback paths. This is the single largest exploit value category in Chainalysis 2025 data. We flagged at least one oracle issue in roughly 70 percent of DeFi engagements (Pharos internal observation).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access control drift - upgradeable proxies with under-scoped role hierarchies, EIP-2535 diamond facets shipped without role audits, governance time-locks bypassed via emergency multisigs. CertiK Hack3d 2024 lists access control as the largest dollar-loss category for the year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MEV and sandwich-resistant ordering - finding subtle, exploit subtler. Most reports surface MEV exposure as informational, but the actual dollar drain accumulates silently. &lt;a href="https://eips.ethereum.org/EIPS/eip-7702" rel="noopener noreferrer"&gt;EIP-7702&lt;/a&gt; and EIP-4844 reshape this surface in 2025-2026.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flash-loan composability - the 2020-2022 flash-loan era never ended, it refactored. The new shape is multi-protocol price feedback loops where each protocol passes its own assertions but the composed flow is exploitable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cross-chain message replay - LayerZero, Wormhole, CCIP and IBC patterns. Bridges remain the highest dollar-loss category per incident in Chainalysis 2025.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reentrancy still appears - mostly in lower-severity findings around ERC-777 and ERC-1155 hooks, or in non-standard tokens that pass control mid-transfer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time-to-Audit and Audit-to-Fix Cycles
&lt;/h2&gt;

&lt;p&gt;Across our 2024-2026 engagements typical timelines settled at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Booking to kickoff: 2-6 weeks for top-tier, 1-3 weeks for mid-tier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initial review: 5-15 working days for a single contract suite under 5,000 LOC, 3-6 weeks for a full protocol of 15,000+ LOC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix cycle: 1-3 weeks for the team to remediate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-audit: 3-7 working days&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Final report and public disclosure: 1-2 weeks after re-audit signoff&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pharos shadow-mode pattern - we deliberately overlap our internal review with the external firm's review for the first 5 working days. This catches the cheapest 30-50 percent of findings before they consume external auditor time, and gives the external firm a head-start on the deeper invariant work. OpenZeppelin and Trail of Bits engagement notes describe similar overlap patterns in their public retros.&lt;/p&gt;

&lt;p&gt;Net calendar - plan for 8-14 weeks from booking to public final report on a non-trivial protocol. Compress this at your peril.&lt;/p&gt;

&lt;h2&gt;
  
  
  The False-Positive Tax
&lt;/h2&gt;

&lt;p&gt;Static analysis tools - Slither, Mythril, Aderyn, Wake, Semgrep rules - are essential and overrated. Across our 2024-2025 engagements, automated tooling produced an average of 40-90 raw findings per 1,000 LOC. After human triage, less than 10 percent typically survive as real high or medium issues (Pharos internal observation).&lt;/p&gt;

&lt;p&gt;The other 90 percent is the false-positive tax. It is paid by engineers who chase every red badge, by junior auditors who pad reports with noise and by clients who think a clean Slither run means a clean codebase.&lt;/p&gt;

&lt;p&gt;Our position: tooling is necessary as a coverage floor and catastrophic when treated as a coverage ceiling. The real audit happens in invariant identification, manual flow tracing and adversarial scenario construction. Trail of Bits has argued this in public repeatedly. Our own data agrees.&lt;/p&gt;

&lt;p&gt;Practical rule - measure auditor hours against findings-per-hour after triage, never against raw scanner output. The latter rewards noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Audit Quality Actually Means
&lt;/h2&gt;

&lt;p&gt;The term audit collapses three distinct activities. Quality requires all three.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Surface scanning - automated tools, syntax-level checks, dependency hygiene. Necessary, not sufficient. Cost-of-execution is cheap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invariant testing - statements that must hold for all states, asserted via fuzzers like Echidna, Foundry invariants, Medusa or formal tools like Halmos and Certora. Cost-of-execution is moderate. Catches whole classes of bugs that surface scanning cannot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adversarial reasoning - human auditors constructing exploit chains across functions, contracts, protocols and time. Cost-of-execution is high. Catches the bugs that ship to mainnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Formal verification adoption crossed an inflection point in 2025. Roughly one third of our high-value engagements now ship with at least one Certora or Halmos invariant suite. a16z crypto guidance and EF research grants have both pushed in this direction. The remaining two thirds rely on Foundry invariant fuzzing as a cheaper proof-carrying baseline. &lt;a href="https://csrc.nist.gov/pubs/ir/8408/final" rel="noopener noreferrer"&gt;NIST IR 8408&lt;/a&gt; references invariant assurance as a stablecoin technical hygiene baseline - a useful external anchor for non-blockchain stakeholders evaluating audit reports.&lt;/p&gt;

&lt;p&gt;Proof-carrying patterns - shipping a contract alongside an invariant suite that re-runs in CI for every PR - are the single largest leap in audit quality we have seen this cycle. They convert audit findings from one-off events into continuous regression checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost-vs-Quality Decision Matrix
&lt;/h2&gt;

&lt;p&gt;Project typeRecommended tierWhy&lt;/p&gt;

&lt;p&gt;ERC-20 fork, no novel logicBoutiqueDiminishing returns above 25k USD&lt;br&gt;
DeFi primitive, under 10M USD TVLMid + invariant suiteCatch invariant violations cheaply&lt;br&gt;
DeFi primitive, 10-50M USD TVLTop tier single-firmReputation matters for LP trust&lt;br&gt;
DeFi primitive, above 50M USD TVLTop tier dual-firm shadowInsurance-grade assurance&lt;br&gt;
Cross-chain bridge, any TVLTop tier dual-firm + formal verificationHighest dollar-loss category in incidents&lt;br&gt;
RWA or FinTech custodyTop tier + legal review + SOC 2 alignmentRegulatory exposure compounds technical risk&lt;br&gt;
NFT mint, no royalties or feesBoutiqueSurface area is small&lt;br&gt;
Governance systemTop tier with timelock specialistAccess control drift is a top-three loss category&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology Caveats and Limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sample bias&lt;/strong&gt; - the Pharos engagement archive over-represents DeFi, FinTech adjacent custody backends and cross-chain projects. ERC-20 fork audits and pure NFT mint audits are under-represented in our numbers. Critical density figures for bridges and DeFi protocols should not be extrapolated to simpler categories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NDA constraints&lt;/strong&gt; - we cannot publish per-client breakdowns. All numbers are reported as ranges across the sample, never as point estimates tied to identifiable engagements. Where ranges feel wide that is the cost of confidentiality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time bias&lt;/strong&gt; - our 2018-2022 engagements skew the historic comparison toward earlier vulnerability classes such as reentrancy. Trend statements about 2024-2026 prevalence are based on the 2023-2026 subset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External data&lt;/strong&gt; - tier-1 audit firms publish report archives but not raw finding-density data. Cross-checks against Halborn, CertiK and Chainalysis are at the category level, not contract level. We treat agreement at the category level as a confirmation signal, not a numeric calibration.&lt;/p&gt;

&lt;p&gt;Numbers in this report should be read as well grounded order-of-magnitude estimates, not engineering precision. Where you need precision for a procurement decision, talk to us directly or to any of the firms we cite.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://pharosproduction.com/insights/engineering/state-of-smart-contract-audits-2026/" rel="noopener noreferrer"&gt;pharosproduction.com/insights/engineering/state-of-smart-contract-audits-2026/&lt;/a&gt;. Written by Dmytro Nasyrov, Founder and CTO at &lt;a href="https://pharosproduction.com/dmytro-nasyrov/" rel="noopener noreferrer"&gt;Pharos Production&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>smartcontracts</category>
      <category>security</category>
      <category>web3</category>
      <category>defi</category>
    </item>
  </channel>
</rss>
