<?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: iamthat</title>
    <description>The latest articles on DEV Community by iamthat (@mrpkk).</description>
    <link>https://dev.to/mrpkk</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%2F4191367%2F88a51282-c1a0-4bbb-b6da-92c493eb5039.jpg</url>
      <title>DEV Community: iamthat</title>
      <link>https://dev.to/mrpkk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrpkk"/>
    <language>en</language>
    <item>
      <title>What a demand letter has to contain to be read as a demand</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sat, 07 Nov 2026 04:00:10 +0000</pubDate>
      <link>https://dev.to/mrpkk/what-a-demand-letter-has-to-contain-to-be-read-as-a-demand-37ab</link>
      <guid>https://dev.to/mrpkk/what-a-demand-letter-has-to-contain-to-be-read-as-a-demand-37ab</guid>
      <description>&lt;p&gt;A demand letter is judged on two things: what is asked, and what supports the ask.&lt;/p&gt;

&lt;p&gt;Most drafts fail on the second part. They describe the grievance at length and then ask for a refund, a repair or a payment without naming the provision that creates the obligation. The recipient reads it as a complaint, not as a position.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five answers, one letter
&lt;/h2&gt;

&lt;p&gt;Legal Letter takes five answers about the facts and returns a formal letter: the facts, the demand, and the provisions that support it. The preview is free; the clean copy is $3 in USDC, no account. Six jurisdictions are covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not do
&lt;/h2&gt;

&lt;p&gt;The citation is printed as text with the source, and the output says it is legal information, not legal advice. No deadline is invented and no amount is promised.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ailegal.legal/legal-letter" rel="noopener noreferrer"&gt;https://ailegal.legal/legal-letter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>legaltech</category>
      <category>law</category>
      <category>consumer</category>
      <category>tools</category>
    </item>
    <item>
      <title>Large capital rarely loses money on volatility. It loses on unverified facts.</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Thu, 05 Nov 2026 02:20:09 +0000</pubDate>
      <link>https://dev.to/mrpkk/large-capital-rarely-loses-money-on-volatility-it-loses-on-unverified-facts-l6b</link>
      <guid>https://dev.to/mrpkk/large-capital-rarely-loses-money-on-volatility-it-loses-on-unverified-facts-l6b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Large capital rarely loses money on volatility. It loses on unverified facts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three places where the loss is measurable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A $100M reserve, attested quarterly.&lt;/strong&gt; Between attestations the market cannot see whether the reserve is covered, so it prices the risk in: a 1 % discount is $1M. A signed reserve report with addresses, amounts and offline verification costs $300; a monthly stream costs $99.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A $5M tokenised asset.&lt;/strong&gt; Real estate, farmland, carbon. The buyer cannot confirm the asset exists and in what state, so the deal stalls. A report with photos, coordinates, capture time and an Ed25519 signature costs $300 - 0.006 % of the deal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A $50k dispute over a transfer.&lt;/strong&gt; One side says the payment happened, the other says it did not. A signed receipt with the transaction hash, verifiable without our server, costs from $0.50.&lt;/p&gt;

&lt;p&gt;The flow is not slowing down: stablecoins moved $7.2T in a month, more than ACH; 62.5M stablecoin transactions per day; x402 agent payments reached 196M transactions and $42M of settled volume; about 269M addresses hold stablecoins.&lt;/p&gt;

&lt;p&gt;Money moves faster than confirmations. That gap is the product.&lt;/p&gt;

&lt;p&gt;What we built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proof of Reserve - reserve confirmed between audits, verifiable offline;&lt;/li&gt;
&lt;li&gt;Proof of Place - the asset was here, at this time, in this state;&lt;/li&gt;
&lt;li&gt;Payment receipts and agent spend limits - the transfer is proven, the limit fires.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we do not do: we do not prove ownership, we do not claim "unfakeable", we do not store biometrics. Every report states its limits on page one.&lt;/p&gt;

&lt;p&gt;Who this is for: RWA issuers, DAO treasuries, insurers, OTC desks, agent-payment platforms.&lt;/p&gt;

&lt;p&gt;If you have a deal or a reserve where confirmation is missing, send a message - we will look at your data first.&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%2Ft3gxjx25r80qfkvkef7i.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%2Ft3gxjx25r80qfkvkef7i.jpg" alt="Reserve. Place. Payment." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rwa</category>
      <category>crypto</category>
      <category>stablecoins</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Proof of Place: what a satellite can and cannot prove</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Mon, 02 Nov 2026 23:17:50 +0000</pubDate>
      <link>https://dev.to/mrpkk/proof-of-place-what-a-satellite-can-and-cannot-prove-3lid</link>
      <guid>https://dev.to/mrpkk/proof-of-place-what-a-satellite-can-and-cannot-prove-3lid</guid>
      <description>&lt;h1&gt;
  
  
  Proof of Place: what a satellite can and cannot prove
&lt;/h1&gt;

&lt;p&gt;Tokenised real estate, carbon plots, insured warehouses, leased equipment — the same question keeps coming back in a different costume: &lt;strong&gt;was the thing actually there, then, in that state?&lt;/strong&gt; Not "does the issuer say so". Was it there.&lt;/p&gt;

&lt;p&gt;Satellite imagery is the first answer everybody reaches for, and it is a good answer for about a third of the cases. This is a map of which third, written from the side that has to hand the report to a client.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four layers, weakest to strongest
&lt;/h2&gt;

&lt;p&gt;Every "proof of place" product is some combination of these, and the honest ones say which layers they checked and which they could not.&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;What it checks&lt;/th&gt;
&lt;th&gt;What it still misses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File integrity&lt;/td&gt;
&lt;td&gt;hash, re-saves, edit history, metadata consistency&lt;/td&gt;
&lt;td&gt;a photo taken elsewhere and re-wrapped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;td&gt;capture time vs the claim, file timestamps, frame order&lt;/td&gt;
&lt;td&gt;a wrong device clock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Place, declared&lt;/td&gt;
&lt;td&gt;GPS/EXIF against the described site&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GPS is forgeable by design&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Place, visual&lt;/td&gt;
&lt;td&gt;landmarks, skyline, signage, terrain, shadows and sun angle for the date&lt;/td&gt;
&lt;td&gt;a convincing reconstruction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Independent capture&lt;/td&gt;
&lt;td&gt;someone we hire stands there and shoots&lt;/td&gt;
&lt;td&gt;only as good as that person's honesty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note the direction: each layer costs more and proves more, and none of them proves ownership. Who owns a site is a registry question. A photograph cannot answer it, and a product that blurs the two is selling the wrong thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a satellite actually gives you
&lt;/h2&gt;

&lt;p&gt;Three real advantages, and they are not small:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Independence.&lt;/strong&gt; The image is not produced by the party making the claim. That is the whole point. A satellite pass is a third party looking, and neither the issuer nor the auditor controls what it saw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrospective.&lt;/strong&gt; Archive imagery lets you check a claim about the past. If someone says the site was cleared in March, an April pass is evidence about March that nobody could have staged later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A date you did not choose.&lt;/strong&gt; Tasking gives you a capture in a window — usually 24 to 72 hours for a commercial optical satellite — and the timestamp is the vendor's, not the client's.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What it cannot do, in the order people get burned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;It looks from above.&lt;/strong&gt; A roof, a yard, an empty field, a foundation, a row of containers. Interiors, basements, stock levels under a canopy, the condition of anything indoors: outside the view. Half of the warehouse claims I get asked about are interior claims.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optical means weather.&lt;/strong&gt; Cloud cover is not an edge case, it is a schedule. A site in monsoon season can go weeks without a usable optical pass. SAR solves cloud and gives you structure rather than a photograph — and then you need someone who can read SAR, which is a different skill and a different price.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution sets the question, not the answer.&lt;/strong&gt; At tens of centimetres you can tell a truck from a container. You cannot tell one container from another. So "the asset is there" resolves only as far as "something of that shape and size is there". If the claim is "container MSKU-1234567 is there", the satellite does not close it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A pass is a moment.&lt;/strong&gt; One image on the 14th says nothing about the 1st through the 13th. Claims about continuous presence need a stream, and a stream is a subscription, not a report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasking costs hundreds, not tens.&lt;/strong&gt; A tasked scene from a commercial provider is a real line item. Any product that quotes you a $50 "satellite verification" is either using stale archive, or using nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheap check almost nobody runs: shadows
&lt;/h2&gt;

&lt;p&gt;This is the part I would put in every report if clients did not find it strange.&lt;/p&gt;

&lt;p&gt;A photo claims a date, a time and a place. The sun has exactly one position for that triple. So the azimuth of every shadow in the frame — and its length relative to the object that cast it — must agree with the sun's position at those coordinates at that moment.&lt;/p&gt;

&lt;p&gt;It costs nothing to compute and it catches the most common forgery: a real photo of the right place, taken on a different day, relabelled.&lt;/p&gt;

&lt;p&gt;It also fails honestly, and you have to know when: overcast light with no distinct shadow, indoor shots, wide-angle distortion near the frame edge, and an unknown time zone. When it cannot be applied, the report says "sun angle: not applicable, reason", not "sun angle: pass".&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "independent capture" is the strongest tier and the weakest claim
&lt;/h2&gt;

&lt;p&gt;If the photos are not the client's, they are not the client's story.&lt;/p&gt;

&lt;p&gt;And then the honest sentence: this tier is only as good as the operator. It removes the client from the chain of custody, it does not remove human incentives from the world. What you can do is make the operator's contribution visible and attributable — named, paid directly, capture metadata preserved — so that a dispute has a person to examine rather than an anonymous upload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not average the layers into a score
&lt;/h2&gt;

&lt;p&gt;The temptation is a single number: confidence 0.87. Resist it. A score lets a report hide a disagreement, and the disagreements are the product.&lt;/p&gt;

&lt;p&gt;If the GPS says one site and the landmarks say another, the report states both and says they disagree. If the satellite shows a cleared yard and the client's photos show stock, the report says which is which and when each was captured. Averaging those into 0.6 throws away the only thing the client is paying for: a named reason to go look.&lt;/p&gt;

&lt;p&gt;The same principle shows up in reserve reporting, where a ratio computed over half a reserve is refused rather than printed with a footnote. A number that survives only with a caveat is not a number.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this product is, said plainly
&lt;/h2&gt;

&lt;p&gt;A report on photos you send: &lt;strong&gt;$300&lt;/strong&gt;, three working days, per layer verdict plus the gaps. With independent capture — a hired operator, or a satellite pass in a 24–72 hour window — &lt;strong&gt;Pricing is not set yet: the idea is still being shaped. Continuous checking on one site: **a monthly option (price to be set)&lt;/strong&gt;, cancel by not paying.&lt;/p&gt;

&lt;p&gt;And the boundaries, on the page, next to the price:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;not proof of ownership;&lt;/li&gt;
&lt;li&gt;GPS coordinates are forgeable, and metadata is never sold as proof;&lt;/li&gt;
&lt;li&gt;satellites see from above only;&lt;/li&gt;
&lt;li&gt;not a legal opinion, not an appraisal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test of a verification report is not whether it says yes. It is whether it can come back &lt;strong&gt;no&lt;/strong&gt; and still be worth the money. A report that can only confirm is a receipt for optimism.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://attest.rta.lat/proof-of-place" rel="noopener noreferrer"&gt;attest.rta.lat/proof-of-place&lt;/a&gt;&lt;/p&gt;

</description>
      <category>geospatial</category>
      <category>verification</category>
      <category>satellite</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>A log where every row says allowed proves nothing</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Mon, 02 Nov 2026 23:17:44 +0000</pubDate>
      <link>https://dev.to/mrpkk/a-log-where-every-row-says-allowed-proves-nothing-66j</link>
      <guid>https://dev.to/mrpkk/a-log-where-every-row-says-allowed-proves-nothing-66j</guid>
      <description>&lt;h1&gt;
  
  
  A log where every row says &lt;em&gt;allowed&lt;/em&gt; proves nothing
&lt;/h1&gt;

&lt;p&gt;An auditor asked one team to show a refusal. The team produced a log with 1,509 rows. Every row said &lt;code&gt;allowed&lt;/code&gt;. The auditor's question was not "is this signed" — it was "what did you ever stop".&lt;/p&gt;

&lt;p&gt;That story is now a small industry cliché, and teams have adapted: they add denials. Which is where the interesting failure starts. A log full of denials can be just as empty as a log with none, and it survives review much longer, because nobody looks at a denial twice.&lt;/p&gt;

&lt;p&gt;Here is the version of that problem I hit in my own code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The row looks complete
&lt;/h2&gt;

&lt;p&gt;A mandate checker decides whether an agent may spend. Each decision is appended to a ledger. A row from ours:&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;"at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1761740400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pay_invoice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verdict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DENY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payee_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;"0xAAA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"audience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"client-7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount_minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1250&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;"USDC"&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;Nine fields, a named rule, the amount, the payee, the audience. It answers "what happened" and "which rule fired". And it cannot answer the only question a reviewer actually has:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1250 out of what?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The threshold the amount was compared against is &lt;code&gt;mandate.max_amount_minor&lt;/code&gt;. It is not in the row. Neither is the mandate version, nor the value the rule read. So the row says "this was over the limit" and leaves the limit to memory.&lt;/p&gt;

&lt;p&gt;Two consequences, both practical.&lt;/p&gt;

&lt;p&gt;First, the row is not falsifiable later. If the mandate was 1000 that day and 5000 a month later, the row still reads the same. Anyone reviewing the log after the mandate file changed has no way to recompute the decision. They can verify the signature. They cannot verify the judgement.&lt;/p&gt;

&lt;p&gt;Second, and worse, a row like this cannot distinguish a real denial from a broken check. Which brings me to the second failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Denials that are technically true
&lt;/h2&gt;

&lt;p&gt;Under a post about audit logs, someone described their own log: 119,636 rows, 37 denials. All signed. 36 of the 37 had the same reason — &lt;code&gt;output empty or not a string&lt;/code&gt; — while the tool's payload actually carried the text under &lt;code&gt;result.text&lt;/code&gt;, not &lt;code&gt;output&lt;/code&gt;. The checker looked in the wrong place, found nothing, and denied.&lt;/p&gt;

&lt;p&gt;Every one of those 36 rows is cryptographically valid. The signature is correct, the chain is intact, the reason field is populated, the policy id is named. And all 36 are noise: they record a bug in the checker, not a decision about the agent.&lt;/p&gt;

&lt;p&gt;That is the trap. A signature proves &lt;strong&gt;what the checker read&lt;/strong&gt;. It does not prove &lt;strong&gt;what the subject did&lt;/strong&gt;. If the checker reads the wrong field, you get a beautifully attested log of the wrong question.&lt;/p&gt;

&lt;p&gt;It also cuts the other way: 36 false denials hide the one real one perfectly. A reviewer who skims reasons sees the same string 36 times and stops reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  The minimal fix
&lt;/h2&gt;

&lt;p&gt;Record what was compared, not only what was decided. Three fields, inside the signed body, on the same chain:&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;"verdict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DENY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rule_input"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"amount_minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"max_amount_minor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mandate_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:1f4c…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"policy_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&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;ul&gt;
&lt;li&gt;
&lt;code&gt;rule_input&lt;/code&gt; — the two values the comparison actually used. Not the path, the values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mandate_hash&lt;/code&gt; — which mandate this decision was made against. The mandate itself can live elsewhere; the row only needs to point at the exact version.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;policy_version&lt;/code&gt; — so that when the rule order changes, old rows are not silently reinterpreted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the check that makes the log worth reading is one line per row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verdict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DENY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rule_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unfalsifiable denial: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A denial with no inputs is a refusal to explain. It should fail the same way a bad signature fails.&lt;/p&gt;

&lt;p&gt;For the "wrong field" problem there is no schema fix — &lt;code&gt;rule_input&lt;/code&gt; at least makes it visible, because the row will show &lt;code&gt;{}&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; where a value was expected, and a human reading twenty of those in a row will notice the pattern that a machine happily signs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this still does not fix
&lt;/h2&gt;

&lt;p&gt;Being honest about the ceiling matters more than the fix.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Omission.&lt;/strong&gt; A complete, valid chain can be a subset of what happened. Chaining protects against editing, not against silence. If the process that writes the log can choose not to write, no hash helps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selection.&lt;/strong&gt; Nothing stops a system from showing a different chain to a different reviewer. Publishing a chain head somewhere you do not control is the only partial answer, and it costs money and explanation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Truth of the policy.&lt;/strong&gt; The log proves the rule was applied as written. It does not prove the rule was right. A perfectly enforced bad limit is a perfectly enforceable bad limit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The gap in our own code
&lt;/h2&gt;

&lt;p&gt;The version of the record I quoted at the top is the one shipping today. &lt;code&gt;rule_input&lt;/code&gt; and &lt;code&gt;mandate_hash&lt;/code&gt; are proposed, not shipped — I am writing this before the commit exists, because the finding is more useful than the announcement. When the field lands, the article gets a line with the commit and the log stays honest.&lt;/p&gt;

&lt;p&gt;If you are auditing an agent's spend log right now, the test is one question: &lt;strong&gt;pick any denial and ask what value it compared against.&lt;/strong&gt; If the answer requires opening a file that has since changed, the denial is decoration.&lt;/p&gt;

&lt;p&gt;Signed refusals with the values they compared: &lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;attest.rta.lat/deny-evidence&lt;/a&gt; — the record there carries &lt;code&gt;meta.requested_amount&lt;/code&gt; and &lt;code&gt;meta.allowed_max&lt;/code&gt; for exactly this reason.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>audit</category>
      <category>python</category>
    </item>
    <item>
      <title>A resume is read as a match check, not as a story</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sun, 01 Nov 2026 04:00:12 +0000</pubDate>
      <link>https://dev.to/mrpkk/a-resume-is-read-as-a-match-check-not-as-a-story-16m9</link>
      <guid>https://dev.to/mrpkk/a-resume-is-read-as-a-match-check-not-as-a-story-16m9</guid>
      <description>&lt;p&gt;The first pass over a resume is not reading. It is a match check: does the top of the page say which role this person is applying for, and does the rest support it?&lt;/p&gt;

&lt;p&gt;When the top of the page holds a summary that could belong to anyone, the reader has to work out the intent. That work is where attention ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four fields
&lt;/h2&gt;

&lt;p&gt;Resume Builder asks for the target role, experience as one line per job, skills, and an optional name. It returns a resume and a cover letter built around that role — not a template with placeholder text to delete.&lt;/p&gt;

&lt;p&gt;Price is $5 in USDC on Base, no account. Files are processed in memory and not stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest limit
&lt;/h2&gt;

&lt;p&gt;A generated resume does not make experience appear. It removes the work of arranging what exists, and it keeps the role visible at the top where the first pass happens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ailegal.legal/resume-builder" rel="noopener noreferrer"&gt;https://ailegal.legal/resume-builder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>resume</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>What $99 a month proves about your AI agent</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sat, 31 Oct 2026 06:16:41 +0000</pubDate>
      <link>https://dev.to/mrpkk/what-99-a-month-proves-about-your-ai-agent-9g9</link>
      <guid>https://dev.to/mrpkk/what-99-a-month-proves-about-your-ai-agent-9g9</guid>
      <description>&lt;p&gt;When an AI agent spends money, two artifacts exist. The first is the transaction: a hash on a chain, visible to anyone. The second is the decision to allow it — and when the decision was &lt;em&gt;no&lt;/em&gt;, almost nobody keeps the second one.&lt;/p&gt;

&lt;p&gt;Ask a team what their agent refused last month and you usually get a dashboard, a screenshot, or a log where every row says &lt;code&gt;allowed&lt;/code&gt;. A dashboard is a claim made by the same system that is being questioned. That is why the interesting artifact is not the allow list. It is the refusal, written down in a form someone else can check.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a refusal record has to contain
&lt;/h2&gt;

&lt;p&gt;The record has to answer four questions without help from the service that produced it: what was asked, which policy decided, who asked, and can this file be changed after the fact.&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;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;sha256 of the previous record&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ts"&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-10-29T09:14:02+00:00"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payee not in allowlist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"policy_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;"E03-allowlist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"task_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;"task_7f21"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"artifact_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:9c1e..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent:research-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"requested_amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12.50"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"allowed_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.05"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"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;"&amp;lt;sha256 of this body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;Ed25519 signature&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"public_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;"&amp;lt;base64 key&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519"&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;Three properties do the work. &lt;code&gt;prev&lt;/code&gt; chains each record to the one before it, so deleting a row breaks every row after it. The signature covers the body including &lt;code&gt;prev&lt;/code&gt;, so a record cannot be rewritten and re-signed without the key. The public key is embedded, so verification needs no network call and no account with the vendor.&lt;/p&gt;

&lt;p&gt;Writing one is a single request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://attest.rta.lat/deny &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'content-type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"reason":"payee not in allowlist","policy_id":"E03-allowlist",
       "task_id":"task_7f21","artifact_hash":"sha256:9c1e","actor":"agent:research-1"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading them back is the other one: &lt;code&gt;GET /deny?since=...&amp;amp;limit=100&lt;/code&gt;. Offline check is a function call against the exported log, not a login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;attest.deny&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify_log&lt;/span&gt;
&lt;span class="nf"&gt;verify_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What it proves, and what it does not
&lt;/h2&gt;

&lt;p&gt;This table is the reason the product exists, and it is more useful than any feature list:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proves&lt;/th&gt;
&lt;th&gt;Does not prove&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The record was not changed after issue&lt;/td&gt;
&lt;td&gt;That no other chain was shown to someone else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The chain has no gaps (each &lt;code&gt;prev&lt;/code&gt; matches)&lt;/td&gt;
&lt;td&gt;That every refusal in your system reached this log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The signature verifies offline with the embedded key&lt;/td&gt;
&lt;td&gt;That the policy behind the refusal was correct&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Read the right column twice. A signed refusal log is evidence that a specific decision happened and was recorded in a way that cannot be quietly edited. It is not a certificate of good judgement, and it is not a control: it records what was stopped, it does not stop anything. If you need enforcement before the action, that is a separate layer — a mandate checked against the proposed action, not a log written after it.&lt;/p&gt;

&lt;p&gt;Anyone who sells you "compliance" as a single artifact is selling you the left column and hoping you do not read the right one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it costs money at all
&lt;/h2&gt;

&lt;p&gt;Recording a refusal is cryptography, not inference. There is no model in the path: Ed25519 signing and a SHA-256 chain cost nothing per record, which is why the price is flat rather than metered.&lt;/p&gt;

&lt;p&gt;The paid plan is $99 for 30 days, unlimited records, one-time payment, no auto-renewal. A trial key starts at 0.01 USDC and covers 100 records over 7 days; free evaluation is 20 records a day. Payment is USDC on Base to the address on the page, and the page issues the API key after the transfer.&lt;/p&gt;

&lt;p&gt;Now the honest part about the subscription: &lt;strong&gt;the price is not the proof.&lt;/strong&gt; Paying monthly proves you had $99 and a reason. What proves something is the artifact, and the artifact does not expire with the subscription. Records you already hold keep verifying offline after the plan ends, because verification uses the public key inside the record, not a call to the vendor. If a service's evidence stops working when you stop paying, it was never evidence — it was a rented dashboard.&lt;/p&gt;

&lt;p&gt;So what does $99 a month actually prove? That you decided the question "what did the agent refuse, and can I show it later" is worth a fixed line item rather than a screenshot. The rest is arithmetic: signing a record is Ed25519, not inference, so the five-hundredth refusal in a month costs the same as the first — zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fits in a real conversation
&lt;/h2&gt;

&lt;p&gt;An auditor asks for a refusal and gets a signed chain with the policy and the numbers. An incident review needs a timeline; the gap is usually exactly where the agent was stopped, and this is the file that fills it. A customer asks what your agent is not allowed to do; the answer is a set of policy ids with the records that applied them.&lt;/p&gt;

&lt;p&gt;None of those conversations are won by a dashboard. They are won by a file the other side can check without trusting you.&lt;/p&gt;

&lt;p&gt;The contract, the offline verifier and the pricing block are here: &lt;strong&gt;&lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/deny-evidence&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>legaltech</category>
      <category>showdev</category>
    </item>
    <item>
      <title>A contract scanner that refuses to guess</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sat, 31 Oct 2026 06:16:35 +0000</pubDate>
      <link>https://dev.to/mrpkk/a-contract-scanner-that-refuses-to-guess-40h</link>
      <guid>https://dev.to/mrpkk/a-contract-scanner-that-refuses-to-guess-40h</guid>
      <description>&lt;p&gt;Every AI contract tool I have tried answers with confidence. Ask about a clause that is not in the document, and you get a plausible paragraph with an article number that does not exist. The failure is not that the answer is wrong. The failure is that the wrong answer looks exactly like the right one.&lt;/p&gt;

&lt;p&gt;Contract Scan is a small tool that does the opposite, and I want to describe precisely where it stops instead of what it promises. It takes a text PDF or a plain text file and returns two risk flags for free, then five flags with the exact wording to fix for $5 in USDC. That is the whole product. The interesting part is the refusals.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens when it cannot read
&lt;/h2&gt;

&lt;p&gt;The file is the first thing that can be wrong, so the tool answers about the file before answering about the contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An image-only scan&lt;/strong&gt; returns &lt;code&gt;422&lt;/code&gt; with "the file looks like a scan, no extractable text". It does not run OCR and it does not guess at clauses it cannot see.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An empty file&lt;/strong&gt; returns &lt;code&gt;no text found&lt;/code&gt;. A whitespace-only file returns &lt;code&gt;422&lt;/code&gt; as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A file over 8 MB&lt;/strong&gt; returns &lt;code&gt;413&lt;/code&gt; with the limit, not a &lt;code&gt;500&lt;/code&gt; after two minutes of silence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A PDF that is not a PDF&lt;/strong&gt; returns the exception class in the message, so you know whether the problem is encryption, a broken stream or the wrong file entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is impressive engineering. It is just the difference between "I could not analyse this" and a confident paragraph about a contract the service never read.&lt;/p&gt;

&lt;h2&gt;
  
  
  The free pass is rules, not a model
&lt;/h2&gt;

&lt;p&gt;The five risk types are fixed: auto-renewal, unlimited liability, penalties and forfeitures, unilateral change, and a distant forum or arbitration. The preview runs deterministic patterns over the extracted text. The same document produces the same flags on every call, in milliseconds: ten contracts take about 4 ms on the server.&lt;/p&gt;

&lt;p&gt;Determinism matters for a boring reason. If a scanner is a model wrapped in a prompt, two runs on the same contract can disagree, and then the output is not a document you can attach to an email to the other side. It is a conversation you had with a service.&lt;/p&gt;

&lt;p&gt;The paid report adds a model pass on top of the rules, because live contracts are written in wording no regex anticipates: "liable for all damages", "courts of Delaware", "indemnify". Every flag in the report carries &lt;code&gt;source: rules&lt;/code&gt; or &lt;code&gt;source: model&lt;/code&gt;, so you can see which mechanism produced it. A flag with no provenance is an opinion with a timestamp.&lt;/p&gt;

&lt;h2&gt;
  
  
  We published the accuracy, including the failure
&lt;/h2&gt;

&lt;p&gt;This is the part that most tools skip. The rules were measured on ten contracts written as real documents, for a named reader: a tenant in Moscow, a client in New York, an employee in St Petersburg. Each contract had risks planted deliberately, and each flag was checked against the quoted wording rather than eyeballed.&lt;/p&gt;

&lt;p&gt;The first measurement, before any of this was announced:&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;Measured&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Completeness (planted risks found)&lt;/td&gt;
&lt;td&gt;25 / 34 = &lt;strong&gt;73.5 %&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;≥ 80 %&lt;/td&gt;
&lt;td&gt;not met&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;False flags&lt;/td&gt;
&lt;td&gt;4 / 29 = &lt;strong&gt;13.8 %&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;≤ 10 %&lt;/td&gt;
&lt;td&gt;not met&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flags pointing at a real risk&lt;/td&gt;
&lt;td&gt;25 / 29 = 86.2 %&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server errors on edge inputs&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;met&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both thresholds were missed, and the misses were not random. Russian contracts scored 11 of 18 (61 %) against 14 of 16 (88 %) for English ones, because the English rules were written from live contracts and the Russian ones from a dictionary of legal phrases. Nine of nine misses traced back to three holes: Russian morphology, English synonyms for a penalty, and the concept of a "home court", which is not a risk at all when you are the local party.&lt;/p&gt;

&lt;p&gt;The same exercise found two ways the scanner could answer "clean" on a dangerous contract: a &lt;code&gt;cp1251&lt;/code&gt;-encoded text file silently lost all Cyrillic, and a PDF longer than 40 pages was cut off at page 40. A silent clean is the worst output a scanner can produce, worse than an error.&lt;/p&gt;

&lt;p&gt;Both are fixed, with tests, in the same day's commits. The rules now return 35 of 35 planted risks with 0 false flags on that corpus — and that sentence needs a caveat the size of the corpus: &lt;strong&gt;the fixes were written against these ten documents, so the second number is a regression baseline, not an accuracy promise.&lt;/strong&gt; It says the holes are closed. It does not say the next hundred contracts will score the same, and it is pinned in the test suite precisely so that it cannot quietly drift.&lt;/p&gt;

&lt;p&gt;If you count risks outside the declared five-type checklist — a five-year non-compete, "as is" with no warranty, termination without a cure period — the ceiling was 61 % on the original run. That is the honest limit of a five-template triage, and it should never be confused with a legal review.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to the file
&lt;/h2&gt;

&lt;p&gt;Files are processed in memory and discarded when the request ends. Only aggregate counters survive: how many operations ran, not the documents. There is no account, so there is no account to leak. Payment is 5 USDC on Base to the address shown on the page; you paste the transaction hash and the page says so when the hash is wrong instead of pretending it worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;It is a reading aid with quoted wording. It is not legal advice, it does not know which side of the contract you are on, and it does not promise an outcome. When the document cannot be read, it says so; when the rules miss, the published number says so for it.&lt;/p&gt;

&lt;p&gt;Two free flags, five in the report, and the accuracy table above are all on the page:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ailegal.legal/contract-scan" rel="noopener noreferrer"&gt;https://ailegal.legal/contract-scan&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>legaltech</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Your agent's log has 1,509 rows and zero denials. That is the problem.</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sat, 31 Oct 2026 05:37:56 +0000</pubDate>
      <link>https://dev.to/mrpkk/your-agents-log-has-1509-rows-and-zero-denials-that-is-the-problem-3kk4</link>
      <guid>https://dev.to/mrpkk/your-agents-log-has-1509-rows-and-zero-denials-that-is-the-problem-3kk4</guid>
      <description>&lt;p&gt;An agent that never refuses anything is not a working agent. It is a script with a credit card.&lt;/p&gt;

&lt;p&gt;I keep seeing the same artefact offered as proof of control: a log where every row says &lt;strong&gt;allowed&lt;/strong&gt;. Fifteen hundred rows, zero denials, exported to CSV for the auditor. It proves traffic. It does not prove that anything was ever stopped.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a refusal actually looks like
&lt;/h2&gt;

&lt;p&gt;A deny record is small and boring on purpose:&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;"v"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;sha256 of the previous record&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ts"&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-10-31T09:14:02+00:00"&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"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"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;"spend_limit_per_call"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"requested"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"amount_usdc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"amount_usdc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent:invoice-runner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519:..."&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;Four properties make it evidence rather than a note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It exists only when something was refused. If the file is empty, either nothing was stopped or nothing was checked. Both are answers.&lt;/li&gt;
&lt;li&gt;It chains. &lt;code&gt;prev&lt;/code&gt; binds each record to the one before it; deleting a row breaks every row after it.&lt;/li&gt;
&lt;li&gt;It is signed offline. A verifier checks the chain and the signature without trusting the service that produced it.&lt;/li&gt;
&lt;li&gt;It names the policy and the numbers. "Denied" is an opinion; "asked 40, limit 5, policy spend_limit_per_call" is a fact.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The question that breaks most demos
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Show me one refusal from last week, with the policy that fired.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most systems cannot answer it, because denials are logged at the same level as successes and thrown away first.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;It is not a compliance certificate, and it does not make an agent safe. It makes one narrow claim verifiable: this action was stopped, at this time, under this policy, and the record has not been edited since. Everything else still needs a human.&lt;/p&gt;

&lt;p&gt;If you already keep such a log, the only thing I would ask: can someone verify it without your dashboard? If yes, you are ahead of most teams shipping agents today.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build &lt;code&gt;attest&lt;/code&gt;, a deterministic verifier for agent artefacts — schema, emptiness, provenance, and mandate authority, one Ed25519-signed verdict. The deny log is public: &lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/deny-evidence&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Two clauses carry most of the risk in a contract you are about to sign</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Sat, 31 Oct 2026 00:56:42 +0000</pubDate>
      <link>https://dev.to/mrpkk/two-clauses-carry-most-of-the-risk-in-a-contract-you-are-about-to-sign-4286</link>
      <guid>https://dev.to/mrpkk/two-clauses-carry-most-of-the-risk-in-a-contract-you-are-about-to-sign-4286</guid>
      <description>&lt;p&gt;A contract is signed at the point of least attention: the PDF is open on a phone, and the only question is where to click.&lt;/p&gt;

&lt;p&gt;The expensive parts are rarely in bold. An early-exit penalty, a clause that lets the other side change terms later, a deadline that moves — these decide the cost of the deal, and they sit in the same font as everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the check does
&lt;/h2&gt;

&lt;p&gt;Contract Scan takes a text PDF or a plain text file and returns two risk flags free, in seconds, without an account. The full report lists five fixes and includes a letter to the other side — $5 in USDC on Base, no card.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to the file
&lt;/h2&gt;

&lt;p&gt;Files are processed in memory and discarded when the request ends. Only aggregate counters are kept — how many operations ran, not the documents themselves. There is no account, so there is no account to leak.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;The output is a reading aid with cited wording, not legal advice, and it does not promise an outcome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ailegal.legal/contract-scan" rel="noopener noreferrer"&gt;https://ailegal.legal/contract-scan&lt;/a&gt;&lt;/p&gt;

</description>
      <category>legaltech</category>
      <category>contracts</category>
      <category>tools</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Three products, one question: what was the agent allowed to do?</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Thu, 29 Oct 2026 17:13:37 +0000</pubDate>
      <link>https://dev.to/mrpkk/three-products-one-question-what-was-the-agent-allowed-to-do-5edh</link>
      <guid>https://dev.to/mrpkk/three-products-one-question-what-was-the-agent-allowed-to-do-5edh</guid>
      <description>&lt;p&gt;The portfolio looks like three products. Operationally it is one question asked at three moments.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Before exposure: MCP Security Pass — $500
&lt;/h2&gt;

&lt;p&gt;A server is about to be published. The question is: what can an agent do with it, and what happens when it tries something outside the intended scope?&lt;/p&gt;

&lt;p&gt;The pass is a 10-check review: auth, authorization, least privilege, tool descriptions, input validation, secrets, denial logging, replay, transport, supply chain. Output: findings, severity, evidence, fix order.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. During operation: Deny Evidence — $29/month
&lt;/h2&gt;

&lt;p&gt;The server is live. The question changes: what did the agent try, and what was refused?&lt;/p&gt;

&lt;p&gt;A log of &lt;code&gt;allowed&lt;/code&gt; rows cannot answer that. A signed refusal record can: policy, reason, task, artifact hash, timestamp. Verifiable offline, without custody.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. For the buyer: EU AI Act Evidence Pack — $1,500
&lt;/h2&gt;

&lt;p&gt;The product is being sold into the EU. The question becomes: where is the evidence package?&lt;/p&gt;

&lt;p&gt;The pack maps the system to record-keeping, human oversight and technical documentation, and includes the deny log as evidence. Five days; express 72 hours for $3,000. Evidence, not a legal opinion or a certification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why they are separate
&lt;/h2&gt;

&lt;p&gt;A security review does not need a monthly subscription. A refusal log does not need a consulting engagement. An EU pack does not need a custom audit of every server. Sell the smallest artifact that answers the buyer's actual question.&lt;/p&gt;

&lt;p&gt;The shared principle: &lt;strong&gt;do not claim safety; produce a record that can be checked&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The portfolio&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deny Evidence&lt;/strong&gt; — signed refusal log, $29/month: &lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/deny-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Security Pass&lt;/strong&gt; — $500 review before you expose a server: &lt;a href="https://rta.lat/audit/" rel="noopener noreferrer"&gt;https://rta.lat/audit/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EU AI Act Evidence Pack&lt;/strong&gt; — $1,500 / 5 days; $3,000 / 72 hours: &lt;a href="https://attest.rta.lat/eu-ai-act-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/eu-ai-act-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>compliance</category>
      <category>mcp</category>
    </item>
    <item>
      <title>What a $29 refusal log actually contains (and what it cannot prove)</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Thu, 29 Oct 2026 17:13:36 +0000</pubDate>
      <link>https://dev.to/mrpkk/what-a-29-refusal-log-actually-contains-and-what-it-cannot-prove-2ni0</link>
      <guid>https://dev.to/mrpkk/what-a-29-refusal-log-actually-contains-and-what-it-cannot-prove-2ni0</guid>
      <description>&lt;p&gt;A refusal log is not a folder of error messages. It is a small evidence format with a specific job: let a third party verify that an enforcement point made a decision, on a specific input, at a specific time.&lt;/p&gt;

&lt;p&gt;Here is the shape we use.&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;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"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;"payee_not_allowlisted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recipient is not in the task mandate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"task_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;"tsk_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;"actor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agent:research-7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"artifact_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;"created_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-10-29T12:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519:…"&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;h2&gt;
  
  
  What it makes possible
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read-only enforcement&lt;/strong&gt; — a database tool can show that a write was attempted and refused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spend control&lt;/strong&gt; — a payment rail can show that a payee or amount was outside the mandate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buyer review&lt;/strong&gt; — a security team can verify the record offline without calling your API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incident review&lt;/strong&gt; — "what did the agent try?" becomes a query, not a meeting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it cannot prove
&lt;/h2&gt;

&lt;p&gt;It cannot prove the model's intent. It cannot prove that no other path bypassed the gateway. It cannot turn a missing log into a complete one. Those limits belong in the document, not in a footnote.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification, not trust
&lt;/h2&gt;

&lt;p&gt;The record is signed with Ed25519 and canonicalized before signing. A verifier only needs the public key and the JSON. If the JSON changes, verification fails. That is the whole trick: make the evidence portable, not platform-bound.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;$29/month&lt;/strong&gt;, the product is intentionally small. It is a refusal record, not a SIEM. The point is to make the missing question visible before a buyer asks it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The portfolio&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deny Evidence&lt;/strong&gt; — signed refusal log, $29/month: &lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/deny-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Security Pass&lt;/strong&gt; — $500 review before you expose a server: &lt;a href="https://rta.lat/audit/" rel="noopener noreferrer"&gt;https://rta.lat/audit/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EU AI Act Evidence Pack&lt;/strong&gt; — $1,500 / 5 days; $3,000 / 72 hours: &lt;a href="https://attest.rta.lat/eu-ai-act-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/eu-ai-act-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>mcp</category>
      <category>api</category>
    </item>
    <item>
      <title>The EU AI Act deadline passed. The missing artifact is a refusal log.</title>
      <dc:creator>iamthat</dc:creator>
      <pubDate>Thu, 29 Oct 2026 17:13:25 +0000</pubDate>
      <link>https://dev.to/mrpkk/the-eu-ai-act-deadline-passed-the-missing-artifact-is-a-refusal-log-3b06</link>
      <guid>https://dev.to/mrpkk/the-eu-ai-act-deadline-passed-the-missing-artifact-is-a-refusal-log-3b06</guid>
      <description>&lt;p&gt;The EU AI Act's high-risk and transparency obligations have been applying since &lt;strong&gt;2 August 2026&lt;/strong&gt;. If you sell an AI system into the EU, the buyer conversation has changed from "is it accurate?" to "show me the evidence".&lt;/p&gt;

&lt;h2&gt;
  
  
  What is actually being asked for
&lt;/h2&gt;

&lt;p&gt;For a high-risk system, the evidence maps to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;record-keeping&lt;/strong&gt; — logs that show the system's operation over its lifetime;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;human oversight&lt;/strong&gt; — who can intervene, how, and what the record looks like;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;technical documentation&lt;/strong&gt; — the model/system description, intended purpose, limitations, and risk controls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For transparency-scope products the set is narrower. The classification drives the scope; a blanket "we are AI Act compliant" claim is not evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The artifact most teams forget
&lt;/h2&gt;

&lt;p&gt;A log of successful calls is not enough. The reviewer wants to know what was &lt;strong&gt;refused&lt;/strong&gt; and why: which policy fired, which payee was blocked, which task budget was exhausted. That is the deny log.&lt;/p&gt;

&lt;p&gt;A useful pack contains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;system description and intended purpose;&lt;/li&gt;
&lt;li&gt;model card with known limitations;&lt;/li&gt;
&lt;li&gt;audit-log schema and a sample;&lt;/li&gt;
&lt;li&gt;human-oversight procedure;&lt;/li&gt;
&lt;li&gt;risk-classification memo;&lt;/li&gt;
&lt;li&gt;deny/refusal evidence with a verifiable record;&lt;/li&gt;
&lt;li&gt;data-flow and subprocessor map.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The &lt;strong&gt;EU AI Act Evidence Pack&lt;/strong&gt; in 5 days for &lt;strong&gt;$1,500&lt;/strong&gt;; express 72 hours for &lt;strong&gt;$3,000&lt;/strong&gt;. It is an evidence package, not a legal opinion and not a certification. The output is designed for a security/legal reviewer to inspect, not for a marketing page.&lt;/p&gt;

&lt;p&gt;If your team is still debating whether the product is in scope, start with the classification memo. That is usually the cheapest decision to get right.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The portfolio&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deny Evidence&lt;/strong&gt; — signed refusal log, $29/month: &lt;a href="https://attest.rta.lat/deny-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/deny-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Security Pass&lt;/strong&gt; — $500 review before you expose a server: &lt;a href="https://rta.lat/audit/" rel="noopener noreferrer"&gt;https://rta.lat/audit/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EU AI Act Evidence Pack&lt;/strong&gt; — $1,500 / 5 days; $3,000 / 72 hours: &lt;a href="https://attest.rta.lat/eu-ai-act-evidence" rel="noopener noreferrer"&gt;https://attest.rta.lat/eu-ai-act-evidence&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>compliance</category>
      <category>law</category>
      <category>eu</category>
    </item>
  </channel>
</rss>
