<?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: Harshith Vaddiparthy</title>
    <description>The latest articles on DEV Community by Harshith Vaddiparthy (@harshithvaddiparthy).</description>
    <link>https://dev.to/harshithvaddiparthy</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%2F4069322%2F82ebffbf-389c-4dd7-ab65-15aadbc02eb4.png</url>
      <title>DEV Community: Harshith Vaddiparthy</title>
      <link>https://dev.to/harshithvaddiparthy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshithvaddiparthy"/>
    <language>en</language>
    <item>
      <title>Forking Macro: A Technical Walkthrough of Agent Collaboration</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Wed, 19 Aug 2026 20:33:54 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/forking-macro-a-technical-walkthrough-of-agent-collaboration-6ab</link>
      <guid>https://dev.to/harshithvaddiparthy/forking-macro-a-technical-walkthrough-of-agent-collaboration-6ab</guid>
      <description>&lt;p&gt;Multi-agent demos often hide the most difficult engineering problem.&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI tools to assist with research organization and drafting. I reviewed, edited, fact-checked, and source-checked this article before publication.&lt;/p&gt;

&lt;p&gt;Spawning workers is not collaboration. A collaborative system must manage context, permissions, handoffs, concurrent state, and verification across humans and agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://macro.com" rel="noopener noreferrer"&gt;Macro&lt;/a&gt; is a workspace that &lt;a href="https://macro.com/posts/why-macro-is-open-source" rel="noopener noreferrer"&gt;describes its open-source decision publicly&lt;/a&gt; and is useful to examine through this lens. Its official repository is published at &lt;a href="https://github.com/macro-inc/macro" rel="noopener noreferrer"&gt;&lt;code&gt;macro-inc/macro&lt;/code&gt;&lt;/a&gt;. The root license presents AGPLv3, but a nested web-app license says all rights reserved. That conflict matters and is covered below. The published stack includes Rust and SolidJS. Macro connects documents, email, tasks, calls, channels, CRM, memory, and agents.&lt;/p&gt;

&lt;p&gt;I am using Macro and &lt;a href="https://github.com/harshith-vaddiparthy/macro" rel="noopener noreferrer"&gt;forked the repository&lt;/a&gt;. On August 19, 2026, GitHub compare showed the fork's &lt;code&gt;main&lt;/code&gt; identical to upstream &lt;code&gt;main&lt;/code&gt;, 0 commits ahead and 0 behind, at &lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Important scope note: no local clone, modified branch, self-hosted deployment, or benchmark is claimed in this article. The walkthrough maps verified repository and documentation claims to a reproducible evaluation plan. It does not pretend I ran tests for which I have no artifact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository snapshot
&lt;/h2&gt;

&lt;p&gt;At review time, the official repository showed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Snapshot on 2026-08-19&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stars&lt;/td&gt;
&lt;td&gt;3,696&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forks&lt;/td&gt;
&lt;td&gt;362&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commits in &lt;code&gt;main&lt;/code&gt; history&lt;/td&gt;
&lt;td&gt;5,066&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open issues&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open pull requests&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tags&lt;/td&gt;
&lt;td&gt;213&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latest visible release&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v2026.8.18.2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewed commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are activity signals, not performance results. The latest values will change.&lt;/p&gt;

&lt;p&gt;The cover uses Macro's &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/.github/readme/star-history-dark.svg" rel="noopener noreferrer"&gt;older embedded star-history snapshot&lt;/a&gt;, which shows 3,608 stars. The live count at this review checkpoint was 3,696.&lt;/p&gt;

&lt;p&gt;Macro &lt;a href="https://x.com/macrodotcom/status/2087901565357031661" rel="noopener noreferrer"&gt;said on August 13&lt;/a&gt; that the repository briefly reached number one on GitHub Trending. The company &lt;a href="https://x.com/macrodotcom/status/2087590351565435053" rel="noopener noreferrer"&gt;said on August 12&lt;/a&gt; that it had received an influx of users, pull requests, and feature requests. Both are attributed company statements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce the source boundary first
&lt;/h2&gt;

&lt;p&gt;If you want to inspect the same fork, begin by recording the exact source state. The commands below verify Git identity only. They do not install or run Macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/harshith-vaddiparthy/macro.git
&lt;span class="nb"&gt;cd &lt;/span&gt;macro
git remote add upstream https://github.com/macro-inc/macro.git
git fetch upstream main
git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
git status &lt;span class="nt"&gt;--short&lt;/span&gt;
git rev-parse HEAD
git rev-parse upstream/main
git rev-list &lt;span class="nt"&gt;--left-right&lt;/span&gt; &lt;span class="nt"&gt;--count&lt;/span&gt; upstream/main...HEAD
git log &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before building, compare the full SHA with the current upstream default branch and read the repository's current README. Do not assume dependencies or setup commands from this dated article are still correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolve the license boundary before reuse
&lt;/h2&gt;

&lt;p&gt;The root &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/LICENSE.txt" rel="noopener noreferrer"&gt;&lt;code&gt;LICENSE.txt&lt;/code&gt;&lt;/a&gt; presents AGPLv3. The same reviewed tree contains &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/apps/web/LICENSE" rel="noopener noreferrer"&gt;&lt;code&gt;apps/web/LICENSE&lt;/code&gt;&lt;/a&gt; with the exact line &lt;code&gt;Copyright 2023 CoParse, Inc. All rights reserved.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Those terms conflict with a repository-wide assumption that every file is AGPLv3. The affected scope needs clarification from Macro's maintainers. Until then, do not assume every web-app file, screenshot, or asset can be reused under the root license.&lt;/p&gt;

&lt;p&gt;This article does not decide which terms control. Before modifying, distributing, hosting, or reusing repository material, inspect the applicable path, request maintainer clarification, and obtain appropriate legal advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  A technical model of Macro's collaboration surface
&lt;/h2&gt;

&lt;p&gt;The documented system can be understood as six connected layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Work surfaces
  email | tasks | documents | calls | channels | CRM
                         |
                         v
Shared memory refreshed nightly from team activity
                         |
              explicit context via @mentions
                         |
                         v
Agents operating under the user's permissions
                         |
       read | draft | write | update | post | automate
                         |
                         v
Shared document state using CRDT collaboration
                         |
                         v
External coding agents through an MCP endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an editorial model based on Macro's website, documentation, and README. It is not a literal internal service diagram.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Work surfaces
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; says agents can access email, tasks, documents, calls, and channels under the user's permissions. Documented actions include search and read, document writing, task and CRM updates, email drafting, channel posts, call reading, and automation.&lt;/p&gt;

&lt;p&gt;The engineering advantage is context locality. The agent does not need a separate integration for every step if the workspace already exposes the relevant object and action.&lt;/p&gt;

&lt;p&gt;The risk is authority aggregation. A workspace that unifies several tools can give one agent a broad action surface. The permission model, confirmation boundaries, audit trail, and revocation behavior therefore matter as much as tool coverage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Shared memory
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/unified-memory" rel="noopener noreferrer"&gt;Unified Memory documentation&lt;/a&gt; says memory refreshes nightly from team activity.&lt;/p&gt;

&lt;p&gt;A shared memory layer can reduce repeated context assembly. It can also create subtle failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stale information remains retrievable;&lt;/li&gt;
&lt;li&gt;two sources disagree;&lt;/li&gt;
&lt;li&gt;deletion does not propagate as expected;&lt;/li&gt;
&lt;li&gt;an agent retrieves a related but non-authoritative artifact;&lt;/li&gt;
&lt;li&gt;the user cannot see why a particular item was selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test memory against the latency of the workflow. A nightly refresh may fit a weekly recap. It may not fit an incident response or a decision made minutes ago.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Explicit context
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; presents &lt;code&gt;@mentions&lt;/code&gt; as a way to pin context for an agent.&lt;/p&gt;

&lt;p&gt;This gives the system two retrieval modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;broad organizational context from shared memory;&lt;/li&gt;
&lt;li&gt;task-specific context selected by a human or collaborator.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That distinction is useful because retrieval relevance is not the same as authority. The closest semantic match may not be the document that governs the current decision. Pinning context creates a direct signal about which source matters now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Handoffs
&lt;/h3&gt;

&lt;p&gt;The official repository includes an agent task-handoff screenshot. A handoff is the state boundary between actors, so evaluate it as structured data rather than a friendly message.&lt;/p&gt;

&lt;p&gt;A robust handoff should preserve at least:&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;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;are&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;we&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trying&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;produce?"&lt;/span&gt;
&lt;span class="na"&gt;source_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;documents,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;calls,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tasks,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;govern&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;work?"&lt;/span&gt;
&lt;span class="na"&gt;completed_work&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;already&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changed?"&lt;/span&gt;
&lt;span class="na"&gt;open_questions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;remains&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;unresolved?"&lt;/span&gt;
&lt;span class="na"&gt;next_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;should&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;happen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;next?"&lt;/span&gt;
&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;person&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;responsible&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now?"&lt;/span&gt;
&lt;span class="na"&gt;verification&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;can&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;next&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;actor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;claims?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML is an evaluation template, not Macro configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 5: Concurrent document state
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/docs" rel="noopener noreferrer"&gt;Documents documentation&lt;/a&gt; says its documents use CRDTs with Cloudflare Durable Objects. The README describes swarms of agents acting as peers in CRDT collaboration.&lt;/p&gt;

&lt;p&gt;A conflict-free replicated data type allows concurrent updates to converge without using a simple last-write-wins overwrite. This is relevant when humans and several agents edit a shared document.&lt;/p&gt;

&lt;p&gt;CRDTs solve a state problem. They do not solve a meaning problem.&lt;/p&gt;

&lt;p&gt;Two changes can merge correctly and contradict each other. One agent can add a decision while another rewrites the assumption behind it. A production workflow still needs editorial ownership, review boundaries, and a way to identify which claims require verification.&lt;/p&gt;

&lt;p&gt;Useful CRDT tests include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;two agents insert text at the same location;&lt;/li&gt;
&lt;li&gt;a human deletes a section while an agent edits it;&lt;/li&gt;
&lt;li&gt;one participant works from a delayed client;&lt;/li&gt;
&lt;li&gt;several edits reference the same task or decision;&lt;/li&gt;
&lt;li&gt;a reconnect occurs after substantial concurrent work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measure both state convergence and semantic coherence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 6: External agents over MCP
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/AI/mcp/overview" rel="noopener noreferrer"&gt;MCP overview&lt;/a&gt; names Claude Code and Codex CLI. Its &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; separately names Cursor. MCP gives an AI client a standard interface to external context and tools.&lt;/p&gt;

&lt;p&gt;The valuable pattern is a closed state loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shared task -&amp;gt; coding agent -&amp;gt; repository work -&amp;gt; task update -&amp;gt; team recap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An integration is incomplete if it only sends context to the agent. The agent should return a structured status, evidence, and unresolved questions to the workspace where the team coordinates.&lt;/p&gt;

&lt;p&gt;Macro's published &lt;a href="https://docs.macro.com/AI/recipes" rel="noopener noreferrer"&gt;Agent Recipes&lt;/a&gt; include MCP-driven coding-agent task updates, along with daily briefs, project status, weekly recap, call-to-tasks, draft email, and channel summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a bounded evaluation, not a swarm demo
&lt;/h2&gt;

&lt;p&gt;A weekly project recap is a good first workflow because it is recurring, reviewable, and reversible.&lt;/p&gt;

&lt;p&gt;Define the test before connecting broad authority:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test dimension&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Evidence to capture&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;Did the agent use the governing sources?&lt;/td&gt;
&lt;td&gt;Source links and retrieval trace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Freshness&lt;/td&gt;
&lt;td&gt;Did it include a recent change?&lt;/td&gt;
&lt;td&gt;Source timestamp versus output timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permission&lt;/td&gt;
&lt;td&gt;Could it access only allowed objects?&lt;/td&gt;
&lt;td&gt;Account role and denied-access test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handoff&lt;/td&gt;
&lt;td&gt;Did it preserve owners and open questions?&lt;/td&gt;
&lt;td&gt;Structured comparison with source tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action boundary&lt;/td&gt;
&lt;td&gt;Did it draft or mutate shared state?&lt;/td&gt;
&lt;td&gt;Before and after object state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;What happened during a conflicting edit?&lt;/td&gt;
&lt;td&gt;Revision history and final document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification&lt;/td&gt;
&lt;td&gt;Can a human reconstruct the output?&lt;/td&gt;
&lt;td&gt;Action log, citations, and correction record&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Run the workflow in three rounds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Happy path:&lt;/strong&gt; clean sources, no conflicts, draft-only output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adversarial path:&lt;/strong&gt; one stale document, one contradictory update, and one inaccessible source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent path:&lt;/strong&gt; a human or second agent changes a related artifact while the workflow is active.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The primary metric should be correction cost. Record how long a person spends finding missing context, checking claims, fixing ownership, and restoring state. Fast generation does not help if review becomes expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the architecture is promising
&lt;/h2&gt;

&lt;p&gt;Macro's direction connects several primitives that are often separated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an inspectable public implementation with a license-scope conflict that needs clarification;&lt;/li&gt;
&lt;li&gt;shared organizational context;&lt;/li&gt;
&lt;li&gt;explicit context selection;&lt;/li&gt;
&lt;li&gt;permission-aware actions;&lt;/li&gt;
&lt;li&gt;concurrent collaborative documents;&lt;/li&gt;
&lt;li&gt;MCP access for external coding agents;&lt;/li&gt;
&lt;li&gt;recipes that return work to a shared system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combination is the important part. An agent becomes more useful when it can read current work, make a bounded contribution, and return state that another person or agent can continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What remains unproven here
&lt;/h2&gt;

&lt;p&gt;This review does not establish:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;production reliability or security;&lt;/li&gt;
&lt;li&gt;latency and cost at scale;&lt;/li&gt;
&lt;li&gt;the quality of memory retrieval;&lt;/li&gt;
&lt;li&gt;behavior under permission changes;&lt;/li&gt;
&lt;li&gt;audit-log completeness;&lt;/li&gt;
&lt;li&gt;semantic quality under concurrent edits;&lt;/li&gt;
&lt;li&gt;successful self-hosting from Harshith's fork;&lt;/li&gt;
&lt;li&gt;a modification or benchmark at revision &lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are test targets, not conclusions to smuggle into a launch post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The hard part of multi-agent software is not multiplying workers. It is coordinating context, authority, shared state, handoffs, and verification.&lt;/p&gt;

&lt;p&gt;Macro is worth studying because its public architecture addresses those concerns directly. Shared memory gives agents organizational context. &lt;code&gt;@mentions&lt;/code&gt; narrow attention. Permission-bound actions connect context to work. CRDTs support concurrent collaboration. MCP can return coding-agent state to the team's workspace. Studying public code is different from assuming every path has uniform reuse terms, so the nested-license conflict remains a real diligence item.&lt;/p&gt;

&lt;p&gt;None of these features eliminates the need for verification. Together, they provide a concrete public system against which developers can test collaboration claims.&lt;/p&gt;

&lt;p&gt;Credit to &lt;a href="https://x.com/j_becke" rel="noopener noreferrer"&gt;Jacob Beckerman&lt;/a&gt;, whose profile identifies him as Macro's founder and CEO, and the &lt;a href="https://macro.com" rel="noopener noreferrer"&gt;Macro team&lt;/a&gt; for publishing the work. This is an independent technical analysis and does not imply endorsement.&lt;/p&gt;

&lt;p&gt;For the broader product argument, FAQ, sources, and dated updates, read the &lt;a href="https://www.harshith.com/blog/macro-open-source-agent-collaboration" rel="noopener noreferrer"&gt;canonical guide&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>architecture</category>
      <category>mcp</category>
    </item>
    <item>
      <title>AI Engineer Is Now the Most Common AI Role. The Talent Pipeline Has Not Caught Up.</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Tue, 18 Aug 2026 08:28:19 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/ai-engineer-is-now-the-most-common-ai-role-the-talent-pipeline-has-not-caught-up-19l0</link>
      <guid>https://dev.to/harshithvaddiparthy/ai-engineer-is-now-the-most-common-ai-role-the-talent-pipeline-has-not-caught-up-19l0</guid>
      <description>&lt;p&gt;LinkedIn's August 2026 research gives software teams a useful view of how AI engineering work is changing.&lt;/p&gt;

&lt;p&gt;The reported numbers are substantial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;U.S. AI job postings have roughly doubled since 2023.&lt;/li&gt;
&lt;li&gt;The typical AI posting lists about $177,000 in compensation, compared with $80,000 for a non-AI role.&lt;/li&gt;
&lt;li&gt;AI Engineer has overtaken Machine Learning Engineer as the most common AI role on LinkedIn.&lt;/li&gt;
&lt;li&gt;Forward Deployed Engineer is now the third most common AI builder occupation.&lt;/li&gt;
&lt;li&gt;VP of AI postings have grown roughly sixfold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The talent pipeline is much narrower than the demand. Women represented 26% of U.S. AI hires in 2025, compared with 50% of non-AI hires. About 91% of AI workers hold a bachelor's degree or higher. Across 27 countries, women held only 13% of C-suite AI roles at AI companies.&lt;/p&gt;

&lt;p&gt;These are LinkedIn's reported findings. My analysis below is about what engineering leaders and developers should do with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Define the work, not just the title
&lt;/h2&gt;

&lt;p&gt;LinkedIn notes that "AI Engineer" may partly be replacing older language. Some positions that would once have been called machine learning engineering are now receiving a broader label.&lt;/p&gt;

&lt;p&gt;That makes title-based hiring less reliable.&lt;/p&gt;

&lt;p&gt;A useful AI Engineer specification should answer concrete questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this person building model-backed product features or training models?&lt;/li&gt;
&lt;li&gt;Will they own data preparation, application code, testing, deployment, or monitoring?&lt;/li&gt;
&lt;li&gt;What quality, latency, security, and cost constraints matter?&lt;/li&gt;
&lt;li&gt;Which decisions belong to this role, and which belong to platform, product, or data teams?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two companies can advertise the same title while expecting very different work. Candidates should not have to reverse-engineer the role from a list of libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Forward Deployed Engineer growth is a deployment signal
&lt;/h2&gt;

&lt;p&gt;Forward Deployed Engineer becoming the third most common AI occupation is important because the role sits close to implementation.&lt;/p&gt;

&lt;p&gt;Companies are not only looking for people who understand models. They need engineers who can enter a real operating environment, clarify requirements, integrate with existing software and data, and help users adopt the result.&lt;/p&gt;

&lt;p&gt;For developers, this rewards a broader portfolio. A small but complete project can be stronger evidence than a collection of disconnected demos. Show the problem definition, architecture, implementation, tests, operational constraints, and the decisions you would revisit.&lt;/p&gt;

&lt;p&gt;For teams, interview loops should reflect this work. Ask a candidate to turn an ambiguous request into a testable specification. Let them build or critique a bounded service. Evaluate the reasoning, implementation, and communication with the same rubric for every candidate.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Do not turn the 91% degree figure into another automatic filter
&lt;/h2&gt;

&lt;p&gt;The report describes the current workforce. It does not prove that every AI builder role requires a bachelor's degree.&lt;/p&gt;

&lt;p&gt;LinkedIn also states that its findings are descriptive and correlational. Member histories are self-reported, and compensation analysis covers postings that voluntarily disclose pay.&lt;/p&gt;

&lt;p&gt;If a degree is genuinely necessary, explain why. Otherwise, define alternative evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A working software artifact with readable code&lt;/li&gt;
&lt;li&gt;Contributions to a relevant project&lt;/li&gt;
&lt;li&gt;A paid apprenticeship or internal rotation&lt;/li&gt;
&lt;li&gt;Strong adjacent experience in software, data, security, product, or a target industry&lt;/li&gt;
&lt;li&gt;A structured work sample scored against published criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Removing a degree requirement without creating an evidence standard does not produce skills-first hiring. It produces inconsistent judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Measure access through the engineering ladder
&lt;/h2&gt;

&lt;p&gt;The gender gap appears in hiring and becomes larger in AI leadership. That means the relevant system includes sourcing, interviews, project assignment, promotion, and sponsorship.&lt;/p&gt;

&lt;p&gt;Engineering leaders should measure who advances at each stage. They should also inspect who receives the high-visibility technical work that produces future staff engineers, architects, directors, and AI leaders.&lt;/p&gt;

&lt;p&gt;This is not separate from technical quality. A team that repeatedly searches within the same narrow network is limiting the number of capable people it can discover.&lt;/p&gt;

&lt;h2&gt;
  
  
  What developers should take from this
&lt;/h2&gt;

&lt;p&gt;AI roles are growing, but the title alone is becoming less informative.&lt;/p&gt;

&lt;p&gt;Build evidence around the work you want to do. Demonstrate software fundamentals, the ability to frame a problem, thoughtful use of models, testing, cost and latency awareness, and clear technical communication. If you are moving from an adjacent field, make the transferable foundation visible.&lt;/p&gt;

&lt;p&gt;The market signal is not simply "learn AI." It is that companies need people who can turn AI capability into dependable, useful software, while the current routes into that work remain unusually narrow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://news.linkedin.com/2026/new-linkedin-research-finds-women-account-for-just-26-percent-of-ai-hires-as-ai-jobs-surge" rel="noopener noreferrer"&gt;LinkedIn News&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://delivery-p143253-e1476319.adobeaemcloud.com/adobe/assets/urn:aaid:aem:81d35729-ba25-4ecd-9365-146d22005a2b/original/as/The_AI_Talent_Divide_2026.pdf" rel="noopener noreferrer"&gt;The AI Talent Divide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://delivery-p143253-e1476319.adobeaemcloud.com/adobe/assets/urn:aaid:aem:86b04a27-f4b1-4047-a228-b9c1a6f21448/original/as/The_Triple_Penalty_2026.pdf" rel="noopener noreferrer"&gt;The Triple Penalty&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>womenintech</category>
      <category>ai</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Designing Browser Agents That Don’t Double-Post: State, Idempotency, and Verification</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Mon, 17 Aug 2026 07:04:50 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/designing-browser-agents-that-dont-double-post-state-idempotency-and-verification-3be</link>
      <guid>https://dev.to/harshithvaddiparthy/designing-browser-agents-that-dont-double-post-state-idempotency-and-verification-3be</guid>
      <description>&lt;p&gt;Browser agents are easy to demo and difficult to operate.&lt;/p&gt;

&lt;p&gt;A demo can navigate to a page, fill an editor, and click Publish. A durable agent must answer a longer list of questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is it acting through the correct account?&lt;/li&gt;
&lt;li&gt;Has another scheduled run already reserved this action?&lt;/li&gt;
&lt;li&gt;Did the click create an external effect?&lt;/li&gt;
&lt;li&gt;Can that effect be identified with a canonical URL or exact state?&lt;/li&gt;
&lt;li&gt;If the browser timed out, is a retry safe?&lt;/li&gt;
&lt;li&gt;Can the next run resume without duplicating the action?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I encountered a small example of this while building a browser-based publishing agent. The agent needed to shorten a draft, but the web editor appended the replacement text instead of replacing the original. A naive implementation could have continued clicking or restarted the publishing flow. The safer implementation read the editor state back, detected that it did not match the intended payload, refused to publish, and recorded a failure.&lt;/p&gt;

&lt;p&gt;That is the core principle of this design:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The model chooses an action. The surrounding system makes the action trustworthy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article develops a minimal architecture for that surrounding system. The examples use Python-like code and SQLite, but the patterns apply to any stack that operates external interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with an explicit action lifecycle
&lt;/h2&gt;

&lt;p&gt;Do not let an agent move directly from “the model suggested this” to “click the button.” Give every external mutation a lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;observed
   ↓
planned / reserved
   ↓
executing
   ├──────────────→ verified ──→ budget committed
   ├──────────────→ failed
   └──────────────→ ambiguous
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important state is &lt;code&gt;ambiguous&lt;/code&gt;. It means the system attempted a mutation but could not prove whether the external effect occurred.&lt;/p&gt;

&lt;p&gt;An ambiguous action is not a failed action. It must be reconciled before any retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Persist intent before performing the mutation
&lt;/h2&gt;

&lt;p&gt;A durable action record should capture enough information for a future run to understand what was intended and how to verify it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;idempotency_key&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;run_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;action_type&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;actor&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;intended_payload&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'planned'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'executing'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'ambiguous'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'verified'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'failed'&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;canonical_result&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;failure_reason&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verified_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;intended_payload&lt;/code&gt; should contain the exact information needed for later comparison. For a post, that could include text, media hashes, alt text, and an expected parent URL. For a follow, the target account is sufficient.&lt;/p&gt;

&lt;p&gt;Avoid persisting browser cookies or session tokens in this operational database. Authentication should remain inside the controlled browser profile.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build a deterministic idempotency key
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;idempotency_key&lt;/code&gt; prevents multiple runs from independently executing the same intention.&lt;/p&gt;

&lt;p&gt;A useful key is based on stable fields:&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;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;material&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;action_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;actor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;target_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;separators&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reserve the action before opening the mutation UI:&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;def&lt;/span&gt; &lt;span class="nf"&gt;reserve_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        INSERT INTO actions (
            id,
            idempotency_key,
            run_id,
            action_type,
            actor,
            target_url,
            intended_payload,
            status,
            created_at,
            updated_at
        )
        VALUES (?, ?, ?, ?, ?, ?, ?, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;planned&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
        ON CONFLICT(idempotency_key) DO NOTHING
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rowcount&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;reserve_action()&lt;/code&gt; returns &lt;code&gt;False&lt;/code&gt;, the run must inspect the existing record. It must not create a slightly different key simply to force the action through.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Prevent concurrent operators with a lease
&lt;/h2&gt;

&lt;p&gt;Idempotency protects individual intentions. A lease prevents two scheduled runs from controlling the same browser workflow concurrently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;operator_lease&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;acquired_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;heartbeat_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expires_at&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lease acquisition should be atomic:&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;def&lt;/span&gt; &lt;span class="nf"&gt;acquire_lease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expires_at&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BEGIN IMMEDIATE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT owner_id, expires_at FROM operator_lease WHERE name = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,),&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&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;current&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;expired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expires_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        INSERT INTO operator_lease (
            name, owner_id, acquired_at, heartbeat_at, expires_at
        )
        VALUES (?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?)
        ON CONFLICT(name) DO UPDATE SET
            owner_id = excluded.owner_id,
            acquired_at = excluded.acquired_at,
            heartbeat_at = excluded.heartbeat_at,
            expires_at = excluded.expires_at
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expires_at&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Long browser rounds should refresh the heartbeat. A run should release the lease in a &lt;code&gt;finally&lt;/code&gt; block, while expiry handles processes that disappear entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Perform preflight checks before every mutation
&lt;/h2&gt;

&lt;p&gt;Browser state can change between actions. A preflight at the beginning of a run is not enough if the run lasts several minutes.&lt;/p&gt;

&lt;p&gt;Before each public mutation, verify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser is on the expected origin.&lt;/li&gt;
&lt;li&gt;The signed-in identity is exactly the intended actor.&lt;/li&gt;
&lt;li&gt;No login, CAPTCHA, restriction, or rate-limit screen is visible.&lt;/li&gt;
&lt;li&gt;The agent still owns the browser task space.&lt;/li&gt;
&lt;li&gt;The target URL resolves to the intended object.&lt;/li&gt;
&lt;li&gt;The relevant control has an unambiguous current state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Treat identity or target uncertainty as a hard stop. Do not work around it with alternate endpoints, extracted cookies, or stealth behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Separate preparation from the external effect
&lt;/h2&gt;

&lt;p&gt;Drafting text, rendering an image, and calculating a target URL are reversible preparation. Clicking Publish is an external mutation.&lt;/p&gt;

&lt;p&gt;Keep those phases separate:&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;def&lt;/span&gt; &lt;span class="nf"&gt;execute_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;preflight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;prepared&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prepare_exact_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&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;prepared&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;

    &lt;span class="nf"&gt;set_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;executing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prepared&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;BrowserOutcomeUnknown&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;set_ambiguous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="n"&gt;verification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify_live_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&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;verification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exact_match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;mark_verified&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;canonical_result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;verification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;verification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;definitive_absence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;mark_failed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;external effect absent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;set_ambiguous&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result could not be proven&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;perform_once()&lt;/code&gt; is intentionally named. It should not contain a generic retry decorator.&lt;/p&gt;

&lt;p&gt;Retries may be safe for observation operations such as loading a page. They are unsafe around mutations unless the destination supports a genuine idempotency token.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Define verification contracts by action type
&lt;/h2&gt;

&lt;p&gt;Verification should be stricter than “the click did not throw an exception.”&lt;/p&gt;

&lt;p&gt;For a published post, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exact signed-in author;&lt;/li&gt;
&lt;li&gt;exact normalized text;&lt;/li&gt;
&lt;li&gt;expected media count and type;&lt;/li&gt;
&lt;li&gt;alt text when available;&lt;/li&gt;
&lt;li&gt;parent relationship for a reply;&lt;/li&gt;
&lt;li&gt;canonical status URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a like, verify that the target-specific control changed from a like state to an unlike state. For a follow, verify that the control associated with the exact account now represents “Following.”&lt;/p&gt;

&lt;p&gt;For a thread, store each part separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;thread_parts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;thread_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;position&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expected_parent_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;published_url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verified&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not publish part &lt;code&gt;n + 1&lt;/code&gt; until part &lt;code&gt;n&lt;/code&gt; has a verified canonical URL. That URL becomes the expected parent for the next part. If the run stops midway, recovery resumes from the first unverified part rather than rebuilding the thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Reconcile before retrying
&lt;/h2&gt;

&lt;p&gt;At the beginning of every run, process unfinished actions before creating new ones.&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;def&lt;/span&gt; &lt;span class="nf"&gt;reconcile_unfinished&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;load_unfinished_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_exact_live_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exact_match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;mark_verified&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;canonical_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;definitive_absence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;mark_failed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;safe to replan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HardStop&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;Action &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; remains ambiguous&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difficult function is &lt;code&gt;search_exact_live_result()&lt;/code&gt;. Its implementation depends on the platform, but the contract should remain narrow. Search the intended actor or destination, compare exact payload attributes, and use a bounded time window.&lt;/p&gt;

&lt;p&gt;Do not accept a vaguely similar result as proof. It is better to stop one run than to manufacture certainty.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Commit budgets only after verification
&lt;/h2&gt;

&lt;p&gt;Autonomous systems need action budgets, but reservation and consumption are different.&lt;/p&gt;

&lt;p&gt;Check the budget before acting. Consume it only after the result is verified. A malformed draft that never publishes should not reduce the successful-publication allowance.&lt;/p&gt;

&lt;p&gt;Budgets should also aggregate related formats. If text posts, image posts, and threads all count as original publications, enforce both their format-specific limits and a shared original-content limit.&lt;/p&gt;

&lt;p&gt;This prevents a system from bypassing an overall limit by switching action labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Use a useful failure taxonomy
&lt;/h2&gt;

&lt;p&gt;Not every non-success is the same:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definitive failure:&lt;/strong&gt; The external effect did not occur. The action may be replanned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ambiguous outcome:&lt;/strong&gt; The mutation may have occurred, but verification is incomplete. Reconcile before retrying.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard stop:&lt;/strong&gt; Identity, authentication, target, ownership, restriction, or repeated selector uncertainty makes further mutations unsafe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality skip:&lt;/strong&gt; The system has permission and capacity to act, but the proposed action lacks sufficient evidence or usefulness.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recording these categories makes strategy analysis more honest. A quality skip is not a broken agent. It can be evidence that the quality boundary is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Keep the model inside the boundary
&lt;/h2&gt;

&lt;p&gt;The language model can help with discovery, ranking, drafting, and deciding which action has the highest expected value. It should not redefine the execution guarantees at runtime.&lt;/p&gt;

&lt;p&gt;Keep these controls deterministic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lease acquisition;&lt;/li&gt;
&lt;li&gt;idempotency-key uniqueness;&lt;/li&gt;
&lt;li&gt;budget enforcement;&lt;/li&gt;
&lt;li&gt;action-state transitions;&lt;/li&gt;
&lt;li&gt;verification requirements;&lt;/li&gt;
&lt;li&gt;hard-stop conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This division lets the model be creative where creativity is useful and constrained where external side effects demand precision.&lt;/p&gt;

&lt;h2&gt;
  
  
  A complete run
&lt;/h2&gt;

&lt;p&gt;The resulting operator loop is straightforward:&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;def&lt;/span&gt; &lt;span class="nf"&gt;run_operator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;acquire_lease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;browser-operator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;()):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;locked_skip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;reconcile_unfinished&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;verify_identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;observations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collect_due_observations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;quality_gate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;record_quality_skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;

            &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;within_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;reserve_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;

            &lt;span class="nf"&gt;execute_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;action_is_verified&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;commit_budget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;summarize_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;release_lease&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;browser-operator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example omits platform-specific selectors deliberately. Selectors change. The reliability contract should survive those changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final principle
&lt;/h2&gt;

&lt;p&gt;Browser agents operate in a world where the interface, network, identity, and human owner can all change underneath them. More capable models improve planning, but they do not remove that uncertainty.&lt;/p&gt;

&lt;p&gt;The durable design is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;observe → plan → reserve → act once → verify → commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the result is unclear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stop → reconcile → prove → continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The safest agent is not the one that retries most aggressively. It is the one that can distinguish a failed action from a failed observation, preserve that distinction across runs, and refuse to guess when an external effect is at stake.&lt;/p&gt;

&lt;p&gt;The model is not the system. State, idempotency, verification, and recovery are the parts that turn model output into trustworthy operation.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
