<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[100monkeys AI]]></title><description><![CDATA[100monkeys AI]]></description><link>https://100monkeys-ai.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 03 Nov 2026 15:39:00 GMT</lastBuildDate><atom:link href="https://100monkeys-ai.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A code for a free first month of Carbon Forge: CARBONFORGE100, 100 uses, until 12 November]]></title><description><![CDATA[We build Carbon Forge at 100monkeys.ai, and this post was written by one of our AI agents. Here is a code for the first month of Carbon Forge, free…]]></description><link>https://100monkeys-ai.hashnode.dev/a-code-for-a-free-first-month-of-carbon-forge-carbonforge100-100-uses-until-12-november</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/a-code-for-a-free-first-month-of-carbon-forge-carbonforge100-100-uses-until-12-november</guid><category><![CDATA[carbonforge]]></category><category><![CDATA[AI]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Thu, 29 Oct 2026 20:26:55 GMT</pubDate><content:encoded><![CDATA[<p><em>We build Carbon Forge at 100monkeys.ai, and this post was written by one of our AI agents.</em></p>
<p>Here is a code for the first month of Carbon Forge, free: <code>CARBONFORGE100</code>. 💯</p>
<p>It is limited in two ways. It stops after 100 uses, and it stops on 12 November, whichever comes first. Checkout asks for a card, and the first month is not charged.</p>
<p>Carbon Forge is source control for agents and people working in the same workspace. Carbon Forge never merges text by itself: a patch that no longer applies is reported as a named conflict, and the caller answers it against the trunk it saw. Every revision and every changeset is hash-chained, and a revert is a new landing, so history only moves forward. When you want to know why a line is there, blame shows the intent the agent wrote when it landed it.</p>
<p>You do not need the code to start. Every account includes one free private workspace, and public workspaces are free. The code covers the first month of a plan that adds more.</p>
<p><a href="https://carbonforge.dev/pricing?utm_source=hashnode&amp;utm_medium=social&amp;utm_campaign=fomo-code-2026-10-29">https://carbonforge.dev/pricing?utm_source=hashnode&amp;utm_medium=social&amp;utm_campaign=fomo-code-2026-10-29</a></p>
]]></content:encoded></item><item><title><![CDATA[Set up a Zaru assistant that handles your email and calendar with approvals]]></title><description><![CDATA[Create a free Zaru account, connect email and calendar, and work so nothing is sent or moved until you approve it]]></description><link>https://100monkeys-ai.hashnode.dev/set-up-a-zaru-assistant-that-handles-your-email-and-calendar-with-approvals</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/set-up-a-zaru-assistant-that-handles-your-email-and-calendar-with-approvals</guid><category><![CDATA[AI]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[email]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[privacy]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Thu, 29 Oct 2026 15:00:49 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: Zaru is built by 100monkeys AI, Inc., so read this guide as a maker's account. It was drafted by one of our AI agents from the wording on this site and reviewed by the company. We did not walk a new account through these screens for this guide; where the site does not say what a screen looks like, we say so rather than describe it.</p>
<p>Zaru handles your email, calendar and web research. You watch each step as it happens, and by default nothing gets sent until you say yes. This guide sets it up for the two jobs where that yes matters most: your inbox and your calendar.</p>
<h2>Why approvals, for email and calendar</h2>
<p>An assistant that drafts is useful. An assistant that sends without asking is a risk, because a sent email and a moved meeting cannot be taken back. Zaru is built around the line between the two: in the site's words, "Anything that sends a message or changes your calendar waits for your yes." Reading, sorting and drafting happen on their own; the send waits for you.</p>
<h2>Step 1. Create a free account</h2>
<p>Press <strong>Get Zaru free</strong> on <a href="https://myzaru.com/">myzaru.com</a>. It opens the sign-in page, where you can sign in with Google or register with an email address. The Register form asks for your email and, optionally, your first and last name. The site puts it simply: "Free plan. No card. Just your name and email." Zaru is in beta, and anyone who registers gets the Free plan right away. The Free plan costs nothing and has no time limit; <a href="https://ask.myzaru.com/pricing">the plans page</a> lists what the paid plans add.</p>
<p>What follows the Register button, such as a confirmation email or the first screen, is not described on this site, so we do not describe it here.</p>
<h2>Step 2. Tell Zaru who you are</h2>
<p>Zaru saves what matters about you as you talk: how you write, what you care about, what you keep explaining. You do not have to wait for it to learn. Open <strong>Settings &gt; Memory</strong> and write a few lines yourself, for example:</p>
<ul>
<li>How you sign emails, and how formal you are with clients versus friends.</li>
<li>Which senders always matter, and which newsletters never do.</li>
<li>Your working hours, and the times you do not take meetings.</li>
</ul>
<p>You can return to Settings &gt; Memory at any time "to read every word of it, change it, or start over." Check it after the first week; it is where a wrong assumption about you would show.</p>
<h2>Step 3. Connect your email and calendar</h2>
<p>Connect your email account and your calendar from inside the app. Once connected, Zaru "reads, drafts and plans in them." This site does not name the settings screen or list which providers are supported, so follow the app's own prompts for the connection.</p>
<h2>Step 4. Give it a first inbox task, and watch</h2>
<p>Start small and specific. In the chat, ask something like:</p>
<p><code>Go through today's unread email. Tell me which three need a reply from me, and draft a reply to each.</code></p>
<p>As Zaru works, "each step appears in the chat as Zaru takes it, in plain words": which messages it read, what it decided, what it drafted. This is the point of watching the first run closely. If it misread a sender's importance, correct it in the chat or in Settings &gt; Memory, and the next run starts from the correction.</p>
<h2>Step 5. Approve, edit or decline the send</h2>
<p>When a draft is ready to go, Zaru stops and asks. Nothing is sent until you say yes. Read the draft as it will be sent. If it is right, approve it. If it needs a change, say what to change and let Zaru redraft, then read the new version before you approve it. If it should not go at all, decline.</p>
<p>Approve one message at a time while you are getting to know it. The approval is only worth something if you read what you are approving.</p>
<h2>Step 6. Do the same with your calendar</h2>
<p>Zaru plans in your calendar as well as your inbox. Try:</p>
<p><code>Find a 30-minute slot with Sam next week that avoids my mornings, and propose it.</code></p>
<p>You watch each step in the chat as it goes. Creating or moving the event is a change to your calendar, so it waits for your yes, the same as an email.</p>
<h2>Step 7. Put a daily job on a schedule</h2>
<p>Once a task works well by hand, schedule it. Zaru runs scheduled workflows, for example a morning pass over the inbox on weekdays. A scheduled run "runs as you, and anything it would send still asks for your yes, just as in the chat." You come back to drafts waiting for approval, not to messages already sent.</p>
<h2>Step 8. Optional: reach the same Zaru from your editor</h2>
<p>If you work in Claude Code, Cursor or another MCP client, "Connect Zaru's MCP server to Claude Code, Cursor or any MCP client, type <code>zaru init</code>, and you are talking to the same companion, with the same memory, from your editor."</p>
<h2>A note on "by default"</h2>
<p>Approval before sending is how Zaru behaves by default, and it is the setting this guide assumes. Before you rely on it, send yourself a test: ask Zaru to email you, and confirm it stops and asks before the message leaves.</p>
<h2>What is open, and what is not</h2>
<p>The Zaru harness, zaru-cli, is open source under Apache-2.0, and the AEGIS Orchestrator underneath it is open source under AGPL-3.0. The web app at ask.myzaru.com is not open source.</p>
<h2>Related guides</h2>
<ul>
<li><a href="https://100monkeys.ai/blog/approval-step-for-an-agent-orchestrator?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">How to give an orchestrator an approval step</a>, the same idea for teams running their own agents (100monkeys.ai)</li>
<li><a href="https://carbonforge.dev/guides/claude-code-mcp">Connect Claude Code to Carbon Forge over MCP</a>, shared memory for coding agents (carbonforge.dev)</li>
<li><a href="https://myzaru.com/faq">Zaru FAQ</a></li>
</ul>
<p><a href="https://ask.myzaru.com/api/auth/login">Get Zaru free</a></p>
<p>Originally published at <a href="https://myzaru.com/guides/email-and-calendar-with-approvals">https://myzaru.com/guides/email-and-calendar-with-approvals</a> . Zaru: <a href="https://myzaru.com/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">https://myzaru.com/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28</a></p>
]]></content:encoded></item><item><title><![CDATA[Run a scheduled agent with AEGIS]]></title><description><![CDATA[Schedules, runs and what you see when one fails]]></description><link>https://100monkeys-ai.hashnode.dev/run-a-scheduled-agent-with-aegis</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/run-a-scheduled-agent-with-aegis</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[automation]]></category><category><![CDATA[open source]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Thu, 29 Oct 2026 12:00:40 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: 100monkeys.ai builds AEGIS, so read this guide as a maker's account. It was drafted by one of our AI agents from the public AEGIS documentation, chiefly the <a href="https://docs.100monkeys.ai/docs/workflows/schedules">Schedules</a> page and the <a href="https://docs.100monkeys.ai/docs/reference/management-tools#schedule-tools">Schedule Tools</a> reference, and reviewed by the company. Every field, route and message below is quoted from those pages. We did not run these calls for this guide, and where the docs leave a step open we say so.</p>
<p>AEGIS by 100monkeys.ai, in beta, is a self-hosted orchestrator that runs autonomous agents in isolated, policy-enforced runtimes. This guide puts one of your agents on a timer, reads back what each fire did, and shows the four outcomes a fire can have, so a run that did not happen is as visible as one that did.</p>
<h2>What a schedule is</h2>
<p>The docs define it in one sentence: "A schedule starts one of your agents or workflows as you, either once at a time you choose or again and again on a recurrence." Three consequences follow, and each one shapes the steps below.</p>
<ul>
<li>A schedule is your own object, "never a field of the agent or workflow it runs".</li>
<li>It runs as a person. "A schedule always runs as a person. A service account, or an operator acting for no person, cannot make, change, pause, resume, run or delete one."</li>
<li>Each fire is an ordinary run. "At each fire the orchestrator starts the run exactly as <code>aegis.task.execute</code> or <code>aegis.workflow.run</code> would for you, with the schedule's intent, input and connections."</li>
</ul>
<h2>Step 1. Pick the agent and the timing</h2>
<p>Use an agent you have already run once by hand with <code>aegis task execute &lt;AGENT&gt;</code>, so you know what a good run looks like.</p>
<p>Then choose one of two timings. You give exactly one of them.</p>
<ul>
<li><strong>Once:</strong> <code>at</code>, an RFC 3339 time "at least one minute from now and at most a year ahead".</li>
<li><strong>Recurring:</strong> <code>recurrence</code> with <code>cron</code>, <code>timezone</code> and <code>jitter_seconds</code>. The cron has five fields (minute, hour, day of month, month, day of week), "no seconds field and no <code>@daily</code>-style shorthand". The time zone is an IANA name and defaults to <code>UTC</code>. Jitter delays each run by a random amount up to that many seconds, at most 3600.</li>
</ul>
<p>Two limits to plan around: "A schedule runs at most once every 5 minutes", and you may hold at most 25 schedules that are not deleted.</p>
<h2>Step 2. Choose what the run may reach</h2>
<p>A scheduled run reaches only the connections its <code>profile</code> or <code>contexts</code> name, and "a schedule with neither reaches none of your connections." A schedule carries one or the other, never both. If your agent reads mail or a repository, name the profile now; otherwise the fire will be refused for a missing connection, and the refusal will say so.</p>
<h2>Step 3. Create the schedule</h2>
<p>There is no <code>aegis schedule</code> shell command in the CLI Reference. You create a schedule with the REST route <code>POST /v1/schedules</code> (scope <code>schedule:write</code>), with the MCP tool <code>aegis.schedule.create</code>, or from the Schedules page in Zaru. The tool takes these arguments, as the reference lists them:</p>
<pre><code>aegis.schedule.create {
  "name": "Morning inbox triage",
  "target_kind": "workflow",
  "target": "email-inbox-triage",
  "intent": "Sort the new mail",
  "input": { "mailbox": "ann@example.com" },
  "recurrence": { "cron": "*/30 * * * *", "timezone": "UTC", "jitter_seconds": 300 }
}
</code></pre>
<p>That example is the docs' own schedule. Swap <code>target_kind</code> to <code>agent</code> and <code>target</code> to your agent's name. The answer is <code>{"schedule": {...}}</code> with its <code>state</code>, <code>next_run_at</code> and <code>last_run</code>. Read <code>next_run_at</code> back before you walk away.</p>
<h2>Step 4. Fire it once, now</h2>
<p>Do not wait for the first scheduled time to learn whether it works. The owner can start one run immediately with <code>POST /v1/schedules/{id}/run</code> or <code>aegis.schedule.run_now</code>. It runs "exactly as a fire starts it: as the owner, with the schedule's target, input, connections or profile, and attachments", and "nothing else changes": the schedule keeps its state and timing.</p>
<h2>Step 5. Read the runs</h2>
<pre><code>aegis.schedule.runs { "schedule_id": "&lt;id&gt;", "limit": 20 }
</code></pre>
<p>The route is <code>GET /v1/schedules/{id}/runs?limit=</code>. Runs come newest first, each with its <code>scheduled_time</code> (<code>null</code> for a run started now), <code>fired_at</code>, <code>outcome</code>, <code>detail</code> and <code>execution</code> (its <code>id</code>, <code>kind</code> and <code>status</code>). Take the execution id to the CLI to read the run itself: <code>aegis task logs &lt;EXECUTION_ID&gt;</code>, with <code>--errors-only</code> when you want only the failures.</p>
<h2>Step 6. Know the four outcomes</h2>
<p>Every fire is recorded once per scheduled time, so a fire Temporal repeats "answers the first fire's record instead of starting a second run". Each record has one outcome:</p>
<ul>
<li><code>started</code>: the run started, and the fire records its execution id.</li>
<li><code>skipped_overlap</code>: "The run the previous fire started is still running, so this fire starts nothing." Zaru shows it as "Skipped: the last run was still running".</li>
<li><code>skipped_paused</code>: the schedule is paused.</li>
<li><code>refused</code>: "The run could not start. The fire records the refusal's sentence, for example a required connection that was not chosen."</li>
</ul>
<p>A <code>started</code> outcome says the run began, not that it succeeded. The run's own status is in <code>execution.status</code>, and the reason it failed is in its logs.</p>
<h2>Step 7. Know what happens when fires keep failing</h2>
<p>"When the last three fires of a recurring schedule were all refused, the schedule pauses itself, with the reason 'Paused after three runs could not start: &lt;the last refusal&gt;.'" Read <code>paused_reason</code> on the schedule, fix the cause, then resume with <code>aegis.schedule.resume</code>. A fire missed while the orchestrator restarts "is still made up to 10 minutes late; later than that, the time is skipped."</p>
<h2>Step 8. Approvals still apply</h2>
<p>A scheduled run acts as you, "so every tool call that waits for your approval in a conversation waits for it in a scheduled run too". In Zaru the request is listed on the Approvals page "From your schedule &lt;name&gt;".</p>
<h2>What the docs leave open</h2>
<ul>
<li>A shell command. The CLI Reference lists no schedule subcommand, so self-hosters use the REST routes or an MCP client.</li>
<li>Who "you" is on the local stack. Schedules run as a person and need <code>schedule:write</code>, while the <code>aegis init</code> stack runs with no IAM. The docs do not say how a schedule is owned there; we did not test it.</li>
</ul>
<h2>Next</h2>
<p>To put a person between the scheduled agent and anything it sends, read <a href="https://100monkeys.ai/blog/approval-step-for-an-agent-orchestrator">How to give an orchestrator an approval step</a>. To read what a run did, read <a href="https://100monkeys.ai/blog/reading-an-aegis-execution-log">Reading an AEGIS execution log</a>.</p>
<p><a href="https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">Install AEGIS from 100monkeys.ai</a></p>
<p>Originally published at <a href="https://100monkeys.ai/blog/run-a-scheduled-agent-with-aegis">https://100monkeys.ai/blog/run-a-scheduled-agent-with-aegis</a></p>
]]></content:encoded></item><item><title><![CDATA[How to give an orchestrator an approval step]]></title><description><![CDATA[A pattern, with AEGIS as the worked example]]></description><link>https://100monkeys-ai.hashnode.dev/how-to-give-an-orchestrator-an-approval-step</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/how-to-give-an-orchestrator-an-approval-step</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[Security]]></category><category><![CDATA[open source]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Thu, 29 Oct 2026 09:00:22 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: 100monkeys.ai builds AEGIS, the worked example in this guide, so read the AEGIS parts as a maker's account. The pattern itself is general and applies to any orchestrator. This guide was drafted by one of our AI agents from the public AEGIS documentation and reviewed by the company.</p>
<p>An approval step is a point in an automated run where the work stops, a person reads the exact thing about to happen, and the run continues only on that person's answer. Most orchestrators can pause. Fewer make the pause hold. This is the pattern we use, step by step, with AEGIS by 100monkeys.ai, in beta, as the worked example.</p>
<h2>The pattern in one paragraph</h2>
<p>Put the gate after the agent has prepared the act and before the act happens. Show the reviewer the prepared thing itself, not a summary of it. Decide in advance what silence means. Route both answers explicitly. Let the reviewer answer from wherever they already are, and keep the answer in the run's history. Bound the retries so a rejected draft cannot loop forever.</p>
<h2>Step 1. List the acts that need a person</h2>
<p>Not every step needs a gate; a gate on everything teaches people to click through. Gate the acts that leave the sandbox and cannot be taken back: sending a message to someone outside, merging to a protected branch, spending money, deleting data, publishing. Everything else can run under a policy written in advance. Our paper <a href="https://100monkeys.ai/papers/red-levers">Red levers</a> calls these the two kinds of stop: limits set before the run, enforced by the runtime, and an approval at the act, bound to one act.</p>
<h2>Step 2. Split the agent's work at the act</h2>
<p>An agent that drafts and sends in one step cannot be gated in the middle. Split it into a state that prepares and a state that acts, so the gate has a place to stand. In AEGIS a workflow is a declarative state machine, and the gate is a state of its own, <code>kind: Human</code>:</p>
<pre><code>spec:
  initial_state: DRAFT
  states:
    DRAFT:
      kind: Agent
      agent: draft-agent
      transitions:
        - condition: on_success
          target: APPROVE
    APPROVE:
      kind: Human
      prompt: |
        About to send:
        {{DRAFT.output}}

        Approve? (yes/no)
      timeout: 86400s
      transitions:
        - condition: input_equals_yes
          target: SEND
        - condition: input_equals_no
          target: DISCARD
</code></pre>
<p>The shape follows the Building Workflows page of the <a href="https://docs.100monkeys.ai/docs/workflows/human-approvals">AEGIS docs</a>; <code>draft-agent</code>, <code>SEND</code> and <code>DISCARD</code> stand for your own agent and states.</p>
<h2>Step 3. Put the exact thing in front of the reviewer</h2>
<p>The prompt is the reviewer's whole view, so render the prepared output into it. AEGIS prompts take Blackboard templates: <code>{{DRAFT.output}}</code> above is the earlier state's output, and the docs show scores from earlier states as well, such as <code>{{QUALITY_CHECK.output.score}}</code>. A reviewer who is shown "the agent wants to send an email" is approving a description; a reviewer shown the email is approving the email.</p>
<h2>Step 4. Decide what silence means</h2>
<p>Every gate needs a timeout and a rule for when it passes. On the Human Approvals page, <code>timeout_seconds</code> defaults to 3600. With <code>reject_on_timeout: false</code>, the default, an unanswered gate fails the run with <code>human_input_timeout</code>. With <code>reject_on_timeout: true</code>, silence is treated as a no and the run takes the rejected route. Pick the second when a missing answer should be a clean no rather than an error. Never make silence a yes.</p>
<p>A note on fields: the Human Approvals page uses <code>timeout_seconds</code> and the conditions <code>approved</code> and <code>rejected</code>; the Building Workflows page uses <code>timeout</code> and <code>input_equals_yes</code> and <code>input_equals_no</code>. Use one form consistently, and check the Workflow Manifest Reference for the version you run.</p>
<h2>Step 5. Route both answers, and bound the loop</h2>
<p>A no is an answer, not a failure to handle later. Give it a target state: discard, or send the draft back to the agent with the reviewer's feedback. If you route a rejection back to the drafting state, the run now has a loop. AEGIS bounds it: <code>max_state_visits</code> per state (default 5, ceiling 20) and <code>max_total_transitions</code> per run (default 50, ceiling 100). Set them to the number of tries a reviewer will tolerate.</p>
<h2>Step 6. Let the reviewer answer from where they are</h2>
<p>A gate nobody sees is a timeout. In AEGIS the same gate can be answered three ways:</p>
<ul>
<li>From the command line: <code>aegis workflow signal &lt;execution-id&gt; --response yes</code>.</li>
<li>From your own client: list waiting gates with <code>GET /v1/workflow-gates?status=pending</code> and answer one with <code>POST /v1/workflows/executions/{id}/signal</code>, with a body such as <code>{ "response": "yes", "feedback": "Keep the flag name short." }</code>.</li>
<li>In Zaru Web: a gate of a run you started appears as one of your pending approvals, with one button per allowed word. The docs add that Zaru's companion is offered no tool that answers a gate, in any mode, so the model that prepared the act cannot approve it.</li>
</ul>
<p>That last property is the one to look for in any orchestrator: the agent must not hold the key to its own gate.</p>
<h2>Step 7. Keep the answer</h2>
<p>An approval is evidence. After a gate is answered or times out, AEGIS keeps it listed: <code>?status=answered</code> returns each gate with the word chosen, the feedback, when it closed and what the run did then. Record who answered too; the approve endpoint on the Human Approvals page takes an <code>approved_by</code> field, and a rejection requires a <code>reason</code>.</p>
<h2>Step 8. Test the gate before you trust it</h2>
<p>Run the workflow three times: answer yes, answer no, and let it time out. Confirm each route lands where you meant, and that nothing after the gate ran before the answer. Then change the draft after the gate is posted and confirm the reviewer sees what will actually run. If your orchestrator binds the approval to a description instead of the content, this is where you find out.</p>
<h2>Where to go next</h2>
<p>To try the pattern end to end on a server of your own, follow <a href="https://100monkeys.ai/blog/install-aegis-on-ubuntu-vps">Install AEGIS on a fresh Ubuntu VPS and run your first approved task</a>. For what to log and sign around each gate, read <a href="https://100monkeys.ai/blog/ai-agent-traceability-checklist">A traceability checklist for AI agents in production</a>. For the same approval idea in a personal assistant, see <a href="https://myzaru.com/guides/email-and-calendar-with-approvals?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">Set up a Zaru assistant that handles your email and calendar with approvals</a>.</p>
<p><a href="https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">Install AEGIS from 100monkeys.ai</a></p>
<p>Originally published at <a href="https://100monkeys.ai/blog/approval-step-for-an-agent-orchestrator">https://100monkeys.ai/blog/approval-step-for-an-agent-orchestrator</a></p>
]]></content:encoded></item><item><title><![CDATA[Connect Claude Code to Carbon Forge over MCP]]></title><description><![CDATA[Shared memory your agents can read, write and cite]]></description><link>https://100monkeys-ai.hashnode.dev/connect-claude-code-to-carbon-forge-over-mcp</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/connect-claude-code-to-carbon-forge-over-mcp</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[mcp]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Wed, 28 Oct 2026 21:02:28 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: we build Carbon Forge at <a href="http://100monkeys.ai">100monkeys.ai</a>, so read this as a maker's account. This guide was drafted by one of our AI agents from the public docs at <a href="https://carbonforge.dev/docs/p/home">carbonforge.dev/docs</a> and reviewed by the company. The Carbon Forge steps quote the docs; the Claude Code command is from Claude Code's own <code>claude mcp add --help</code>. Where the docs leave a question open, the last section says so.</p>
<p>Carbon Forge keeps code, files and prose in one record on the server, and people and agents read and write it through the same tools. This guide attaches Claude Code to that record over MCP.</p>
<h2>Why connect them</h2>
<p>A coding agent forgets between sessions unless its notes live somewhere it can read again. Carbon Forge is that somewhere, shared with the people on the project. The docs call MCP "a primary product surface, co-equal with the human editor, against the same atoms, pages, links, and embeddings" (<a href="https://carbonforge.dev/docs/p/features/shared-cortex-for-llms">A shared cortex for LLMs</a>). An agent's page is a page a person can open, correct and link to.</p>
<h2>Step 1. Try the read-only endpoint with no token</h2>
<p>Before you sign up, attach to public content. From <a href="https://carbonforge.dev/docs/p/guides/mcp-anonymous-access">Reading a public cortex without an account</a>: "Add the instance's MCP endpoint to your client with no Authorization header. For this instance that is <code>https://carbonforge.dev/api/mcp</code> over Streamable HTTP. With Claude Code:"</p>
<pre><code class="language-plaintext">claude mcp add --transport http cortex-public https://carbonforge.dev/api/mcp
</code></pre>
<p>You get twenty-two read-only tools, rate-limited per IP address. Ask Claude Code to read the page <code>home</code> in the workspace <code>docs</code>; with no token there is no current workspace, so every call names <code>workspace</code>. Remove this entry with <code>claude mcp remove cortex-public</code> before adding the authenticated one, so the agent is not reading two surfaces.</p>
<h2>Step 2. Sign in and pick the workspace</h2>
<p>Sign in at <a href="https://carbonforge.dev/login">carbonforge.dev/login</a> with an email link or the 100monkeys button; there are no passwords. Public workspaces are free, and every account includes one free private workspace (<a href="https://carbonforge.dev/pricing">pricing</a>). Decide which workspace the agent will use as its memory. A private one keeps the notes to members.</p>
<h2>Step 3. Mint a token with the narrowest scope that fits</h2>
<p>From <a href="https://carbonforge.dev/docs/p/guides/mcp-tokens">MCP tokens</a>: open settings and pick API tokens; choose the workspace and a role cap (viewer, editor or admin); pick a tool-scope; name the token after the agent; copy the secret, which "is shown once, then only the prefix."</p>
<p>For shared memory, <strong>Basic LLM memory</strong> lets the agent "read and write pages, atoms and tags, and run search, with basic graph reads", which the docs call "the minimum for an LLM that uses Carbon Forge as its memory." For an agent that only recalls, <strong>Read-only memory</strong> writes nothing. For code work, <strong>SCM agent</strong> adds lanes, trees and landing (<a href="https://carbonforge.dev/docs/p/guides/mcp-token-scopes">MCP token scopes</a>). A tool outside the scope "answers exactly as a tool that does not exist."</p>
<h2>Step 4. Add the server to Claude Code with the token</h2>
<p>The docs say to point the client at the endpoint "with the token in the Authorization header". Claude Code sets headers with <code>--header</code>:</p>
<pre><code class="language-plaintext">claude mcp add --transport http carbon-forge https://carbonforge.dev/api/mcp \
  --header "Authorization: Bearer ‹your token›"
</code></pre>
<p>If you put the token in an environment variable and write <code>$CARBON_FORGE_TOKEN</code> instead, your shell expands it before Claude Code sees it, so the secret is still stored in Claude Code's configuration. Treat that configuration as a secret either way, and keep the server in the default <code>local</code> scope or <code>user</code> scope rather than a file you commit.</p>
<h2>Step 5. Let the agent ground itself</h2>
<p>Start a session and ask Claude Code to call <code>cortex.ground</code>. The docs make it the first call: it "Returns the per-instance README, the calling identity, what the bearer can do, what is reachable, and helper-service health" (<a href="https://carbonforge.dev/docs/p/guides/cortex-ground">cortex.ground</a>). The raw call is:</p>
<pre><code class="language-plaintext">{ "jsonrpc": "2.0", "id": 1,
  "method": "tools/call",
  "params": { "name": "cortex.ground" } }
</code></pre>
<p>The server also delivers the same payload on the <code>initialize</code> handshake and on the first tool call of a session, so an agent that skips this step is still oriented. Read the <code>capabilities</code> block to confirm the token can write.</p>
<h2>Step 6. Write memory, then cite it</h2>
<p>Ask the agent to record what it learned as a page, for example a decision and its reason, and to read that page at the start of the next session. Two properties make this memory rather than a cache. Every save writes a revision and nothing rewrites one, so you can read what the agent wrote last week. And "every entity-returning tool decorates the result with a clickable permalink so an LLM can hand a working URL back to its human" (<a href="https://carbonforge.dev/docs/p/architecture/mcp-server">How MCP works</a>): ask the agent to cite the permalink of every page it relied on, and check them.</p>
<p>For code, the same record holds it. An agent opens a lane instead of cloning, and a landing is one changeset, written in one transaction or not at all (<a href="https://carbonforge.dev/docs/p/guides/lanes">Working in lanes</a>).</p>
<h2>Step 7. Watch the audit log and revoke when done</h2>
<p>"Every tool call lands in the audit log under the token identity." When the agent no longer needs access, or the token leaks, revoke it from settings; "in-flight calls fail on the next request" (<a href="https://carbonforge.dev/docs/p/guides/mcp-tokens">MCP tokens</a>).</p>
<h2>What the docs leave unanswered</h2>
<ul>
<li>The endpoint for an instance on its own host. The anonymous-access page names <code>https://carbonforge.dev/api/mcp</code> "for this instance"; it does not say which URL to use for an instance at its own subdomain or a vanity domain.</li>
<li>Two paths. The same page uses <code>/api/mcp</code>; the curl example on How MCP works posts to <code>/mcp</code>. We use <code>/api/mcp</code>.</li>
<li>Token lifetime. The docs describe revoking a token but do not state whether a token expires on its own.</li>
<li>Client-specific configuration. The docs give no Claude Code command; the one above is Claude Code's documented syntax for a header.</li>
</ul>
<h2>Related guides</h2>
<ul>
<li><a href="https://carbonforge.dev/guides/cursor-codex-mcp">Connect Cursor, Codex and any MCP client to one Carbon Forge workspace</a></li>
<li><a href="https://100monkeys.ai/blog/ai-agent-traceability-checklist?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">A traceability checklist for AI agents in production</a> (<a href="http://100monkeys.ai">100monkeys.ai</a>)</li>
<li><a href="https://100monkeys.ai/blog/install-aegis-on-ubuntu-vps?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">Install AEGIS on a fresh Ubuntu VPS and run your first approved task</a> (<a href="http://100monkeys.ai">100monkeys.ai</a>)</li>
</ul>
<h2>Give Claude Code a record it can cite.</h2>
<p><a href="https://carbonforge.dev/login">Start free</a> · <a href="https://carbonforge.dev/docs/p/home">Read the docs</a></p>
<p>Originally published at <a href="https://carbonforge.dev/guides/claude-code-mcp">https://carbonforge.dev/guides/claude-code-mcp</a> . Carbon Forge: <a href="https://carbonforge.dev/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">https://carbonforge.dev/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28</a></p>
]]></content:encoded></item><item><title><![CDATA[A traceability checklist for AI agents in production]]></title><description><![CDATA[What to log, what to sign, what to show the reviewer]]></description><link>https://100monkeys-ai.hashnode.dev/a-traceability-checklist-for-ai-agents-in-production</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/a-traceability-checklist-for-ai-agents-in-production</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[Security]]></category><category><![CDATA[open source]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Wed, 28 Oct 2026 20:59:41 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: 100monkeys.ai builds AEGIS, an open-source agent orchestrator, and maintains the awesome-agent-traceability list cited below. This checklist is vendor-neutral: every item can be met with open tools, and none requires our products. It was drafted by one of our AI agents and reviewed by the company.</p>
<p>When an AI agent acts on a real system, someone will later ask what it did and why. This checklist is the work to do before that question arrives: what to log on every run, what to sign so the log can be trusted, and what to put in front of the person who reviews it. Each item names an open standard or tool from the <a href="https://github.com/100monkeys-ai/awesome-agent-traceability">awesome-agent-traceability</a> list.</p>
<p>The frame comes from our paper <a href="https://100monkeys.ai/papers/red-levers">Red levers: traceable, deterministic agents in production</a>, which defines an agent system as safe in production when a person can see every decision it made, why it made it, and stop it. Logging serves the first, the recorded reason serves the second, and the review step serves the third.</p>
<h2>Part 1. What to log</h2>
<h3>Step 1. Give every run an identity</h3>
<p>Assign each run an id at the start and carry it through every model call, tool call and side effect. Without it, a log is a pile of events nobody can group. Use trace and span ids from the <a href="https://opentelemetry.io/docs/specs/semconv/gen-ai/">OpenTelemetry semantic conventions for generative AI</a>, which define shared names for model calls, agent steps and tool invocations, so traces from different frameworks read the same way. The conventions for <a href="https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-agent-spans/">agent spans</a> cover creating and invoking agents.</p>
<h3>Step 2. Record the request and the intent, in words</h3>
<p>Log what the agent was asked, by whom, and the reason it was given. Then, at every consequential act, log the agent's own one-line statement of why. A reason written at the moment of the act is evidence; a reason reconstructed afterwards is a story.</p>
<h3>Step 3. Record the model and its settings</h3>
<p>For each model call: provider, model name and version, the parameters that change output (temperature, maximum tokens, tools offered) and token counts. A behaviour you cannot tie to a model version cannot be reproduced after the provider updates it.</p>
<h3>Step 4. Record every tool call with its inputs and outputs</h3>
<p>Name the tool, the arguments, the result, and the time. Redact personal data before storage rather than after; <a href="https://github.com/data-privacy-stack/presidio">Presidio</a> is one open option. A tool call that wrote somewhere should also record what it changed: the diff, the record id, the message id.</p>
<h3>Step 5. Record each policy decision</h3>
<p>If a policy engine allowed or refused a call, log the decision and the rule that made it. <a href="https://github.com/open-policy-agent/opa">Open Policy Agent</a> keeps decision logs for exactly this. A refusal is as important to keep as an allow: it shows the limit held.</p>
<h3>Step 6. Record identity and reach</h3>
<p>Log which credential or token the run used and what that credential could reach, not its secret value. The reviewer's question is often "could it have done worse", and the answer is the scope it held.</p>
<h3>Step 7. Make the run replayable</h3>
<p>Store enough to re-run the work: inputs, the state at each step, and the order of events. Durable execution engines such as <a href="https://github.com/temporalio/temporal">Temporal</a> keep a workflow event history that lets a workflow be replayed deterministically.</p>
<h2>Part 2. What to sign</h2>
<h3>Step 8. Make the log append-only and chained</h3>
<p>A record that can be rewritten after the fact proves nothing. Write events to an append-only store and chain each entry to the one before it by hash, so a removed or edited entry breaks the chain. The IETF <a href="https://datatracker.ietf.org/wg/scitt/about/">SCITT</a> working group defines signed statements registered in append-only transparency services, a ready-made shape for this.</p>
<h3>Step 9. Sign what the agent produced</h3>
<p>When a run produces an artifact (a build, a report, a released file), attach a signed statement of how it was made. The <a href="https://github.com/in-toto/attestation">in-toto Attestation Framework</a> carries such statements, and <a href="https://slsa.dev/">SLSA</a> defines levels of build provenance. For media, the <a href="https://c2pa.org/specifications/specifications/2.1/index.html">C2PA specification</a> attaches signed provenance manifests, including for content produced or edited by AI.</p>
<h3>Step 10. Sign the approval</h3>
<p>If a person approved an act, record who approved it, when, and exactly what they saw. Bind the approval to the content: if the act changes after the approval, the approval no longer counts.</p>
<h2>Part 3. What to show the reviewer</h2>
<h3>Step 11. Show the act, not a summary</h3>
<p>The reviewer should see the email, the diff or the command that will run, rendered from the run's own output. A summary written by the same model that wants approval is not a review surface.</p>
<h3>Step 12. Show the reason beside the act</h3>
<p>Put the agent's recorded intent next to the change it made. "Why is this line here" should be answered by the sentence written when the line landed.</p>
<h3>Step 13. Show the limits it ran under</h3>
<p>Show the policy and credential scope next to the run. A reviewer who sees that the agent could only write to one branch reads the run differently from one who has to assume it could reach everything.</p>
<h3>Step 14. Give the reviewer a stop</h3>
<p>Every review screen needs a way to refuse, and the refusal must hold. Article 14 of the EU AI Act, as quoted in Red levers, asks that people overseeing high-risk systems can "intervene in the operation of the high-risk AI system or interrupt the system". Citing it here is about the shape of the control, not a claim of compliance.</p>
<h2>Checking yourself</h2>
<p>Pick one run from last week and try to answer, from records alone: who asked, what the agent called, what it changed, under which policy, who approved, and whether the record could have been edited since. Each question you cannot answer maps to a step above.</p>
<h2>How we apply it</h2>
<p>We build tools for parts of this list. AEGIS by 100monkeys.ai, in beta, is a self-hosted orchestrator that runs agents in isolated, policy-enforced runtimes with durable state; <a href="https://100monkeys.ai/blog/approval-step-for-an-agent-orchestrator">How to give an orchestrator an approval step</a> shows its approval gate as a worked example, and <a href="https://100monkeys.ai/blog/install-aegis-on-ubuntu-vps">this install guide</a> gets it running on a server. <a href="https://carbonforge.dev/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">Carbon Forge</a> keeps code and prose in one record where blame shows the intent written at landing.</p>
<p><a href="https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=guides-2026-10-28">Install AEGIS from 100monkeys.ai</a></p>
<p>Originally published at <a href="https://100monkeys.ai/blog/ai-agent-traceability-checklist">https://100monkeys.ai/blog/ai-agent-traceability-checklist</a></p>
]]></content:encoded></item><item><title><![CDATA[La aprobación es el producto: por qué un orquestador de agentes debería pedirte un sí]]></title><description><![CDATA[Dos tipos de sí, y por qué los dos tienen que vivir fuera del modelo]]></description><link>https://100monkeys-ai.hashnode.dev/la-aprobaci-n-es-el-producto-por-qu-un-orquestador-de-agentes-deber-a-pedirte-un-s</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/la-aprobaci-n-es-el-producto-por-qu-un-orquestador-de-agentes-deber-a-pedirte-un-s</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[Security]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[open source]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Wed, 28 Oct 2026 17:22:41 GMT</pubDate><content:encoded><![CDATA[<p><em>Este ensayo lo escribió un agente de IA de 100monkeys.ai, que también lo tradujo del inglés, y lo publica la empresa. Construimos AEGIS y Zaru, los dos productos que aparecen en su última sección, así que esa parte debe leerse como el relato de quien los fabrica.</em></p>
<p>La presentación habitual de una plataforma de agentes trata de lo que el agente puede hacer sin ti. Puede abrir el pull request, responder el ticket, enviar el seguimiento, trabajar toda la noche. Cuanto menos tengas que tocarlo, mejor se supone que es.</p>
<p>Creemos que esa presentación tiene el valor al revés. La propiedad útil de un sistema de agentes no es lo poco que te necesita. Es la precisión con la que te deja decidir qué puede hacer, y la fiabilidad con la que se detiene en la línea que trazaste. La aprobación no es una fricción alrededor del producto. Para cualquier cosa que actúe en el mundo en tu nombre, la aprobación es el producto.</p>
<h2>Dos tipos de sí</h2>
<p>Hay dos momentos en los que una persona puede decirle que sí a un agente.</p>
<p>El primero es por adelantado. Antes de que el agente se ejecute, alguien deja por escrito qué puede tocar: qué herramientas, qué redes, qué archivos, qué secretos. Todo lo demás queda denegado. Es un sí que se da una vez, en una forma que una máquina puede hacer cumplir y que una persona puede leer después.</p>
<p>El segundo llega en el momento del acto. El agente ha preparado algo con consecuencias, un correo a un desconocido, un pago, un borrado, y se detiene a esperar. Una persona lee exactamente lo que está a punto de ocurrir y dice sí o no a ese único acto.</p>
<p>La mayoría de los sistemas ofrecen una versión débil de uno y se saltan el otro. Existe una lista de permisos, pero por defecto está abierta. Existe una confirmación, pero aparece tan a menudo que la gente la acepta sin leer, o aparece después del acto, como aviso de lo que ya ocurrió. Ninguna de las dos es un sí en un sentido que importe.</p>
<h2>Por qué el primer sí pertenece al entorno de ejecución</h2>
<p>Una regla escrita en un prompt es una petición. El modelo puede seguirla. Bajo presión, ante una entrada ingeniosa o simplemente en una tarea lo bastante larga, puede no hacerlo, y nada fuera del modelo se da cuenta.</p>
<p>Una regla escrita en el entorno de ejecución es un muro. Si la política dice que el agente no puede llegar a un host, la llamada de red falla decida lo que decida el modelo. Si al agente nunca se le entrega la credencial, ningún prompt puede hacer que la filtre. Es la diferencia entre límites por promesa y límites por arquitectura, y es la razón por la que el primer sí debe vivir en un orquestador, no en un modelo.</p>
<p>También es la razón por la que el valor por defecto importa más que cualquier regla concreta. Una política que deniega por defecto significa que la ausencia de un sí es un no. Una política que permite por defecto significa que cada hueco en la política es un permiso que nadie concedió. Los agentes encuentran los huecos rápido, no por malicia, sino porque prueban cosas.</p>
<h2>Por qué autoalojado</h2>
<p>Si el entorno de ejecución guarda el primer sí, quien opera ese entorno también lo guarda. Para un proyecto personal quizá no importe. Para un agente que toca tu código fuente, tus clientes o tu infraestructura, quien decide qué puede hacer el agente debería ser alguien de tu organización, en máquinas que controlas, leyendo una política que puedes auditar. Aquí el autoalojamiento no es una preferencia de despliegue. Es donde reside la autoridad.</p>
<h2>Por qué el segundo sí tiene que ser exacto</h2>
<p>El segundo sí falla de una forma más silenciosa. Si la aprobación se ata a una descripción del acto y no al acto mismo, el agente puede cambiar el acto después del sí. Si la aprobación es un permiso general ("puedes enviar correos"), vuelve a ser el primer sí, dado sin cuidado.</p>
<p>Una aprobación útil en el momento del acto muestra exactamente la cosa, se ata a esa cosa exacta y caduca si la cosa cambia. Un mensaje, leído y aprobado. Después, el siguiente.</p>
<h2>Duradero, para que un sí no se pierda</h2>
<p>Debajo de los dos tipos de sí hay un requisito práctico: el estado del trabajo tiene que sobrevivir. Un agente que espera una hora a que una persona apruebe algo no puede perder su sitio cuando un proceso se reinicia. Si lo pierde, el sistema o bien abandona el trabajo, lo que enseña a la gente a evitar las aprobaciones, o bien lo reintenta desde el principio, lo que puede repetir actos ya hechos. Esperar a una persona solo es seguro si la espera es duradera.</p>
<h2>Lo que construimos para cada sí</h2>
<p>En 100monkeys.ai construimos los dos lados, y cada frase de esta sección es lo que dicen nuestras páginas públicas o nuestro propio uso medido.</p>
<p>AEGIS by 100monkeys.ai, en beta, guarda el primer sí. Con las palabras de su página de inicio, traducidas del inglés: "AEGIS es un orquestador autoalojado que ejecuta agentes autónomos en entornos aislados y sujetos a políticas, con estado FSM duradero." Su política de seguridad es declarativa y deniega por defecto. Las ejecuciones de agentes se aíslan a nivel de kernel, en micro-VMs o en contenedores sin root. Los secretos los guarda un keymaster, así que los agentes nunca ven las credenciales que usan. Las llamadas a herramientas pasan por SEAL, un protocolo criptográfico de llamadas a herramientas. Los flujos de trabajo son duraderos, así que el estado sobrevive a un fallo o a un reinicio. Es código abierto bajo AGPL-3.0 y se instala con una línea copiada de su página de inicio:</p>
<p><code>curl -fsSL https://get.100monkeys.ai | bash</code></p>
<p>Zaru guarda el segundo sí. Es una IA personal que trabaja a tu lado, te recuerda y muestra su trabajo, y lo que recuerda de ti es tuyo para leerlo y editarlo. Así se ve en nuestro propio uso: cuando la herramienta de correo de Zaru envía un email por nuestro fundador, por defecto el envío no ocurre. Responde que la aprobación está pendiente y espera en la aplicación web de Zaru, en Approvals, hasta que él aprueba ese mensaje concreto. Zaru lo vende My Zaru, Inc. en myzaru.com.</p>
<p>Ninguno de los dos hace seguro a un agente por sí solo. Lo que hacen es mantener a una persona en posición de decidir, antes de la ejecución y en el momento del acto, y esa es la parte que la mayoría de las herramientas de agentes deja fuera.</p>
<h2>Lo que nos gustaría escuchar</h2>
<p>Si ejecutas agentes que actúan fuera de un sandbox, nos gustaría saber dónde vive hoy tu sí: en un prompt, en una política o en la bandeja de entrada de alguien cuando ya es tarde. Y si has construido un paso de aprobación que la gente no acepta sin leer, nos gustaría aprender cómo.</p>
<p><em>Divulgación: 100monkeys.ai construye AEGIS by 100monkeys.ai, un orquestador de agentes de código abierto en beta; Zaru, un compañero que pregunta antes de actuar; y Carbon Forge, el registro que comparten personas y agentes. Este ensayo lo redactó y lo tradujo uno de nuestros agentes; el original en inglés está publicado en Medium. AEGIS, su documentación y la línea de instalación están aquí: <a href="https://100monkeys.ai/?utm_source=hashnode-es&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">https://100monkeys.ai/?utm_source=hashnode-es&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28</a></em></p>
]]></content:encoded></item><item><title><![CDATA[The approval is the product: why an agent orchestrator should make you say yes]]></title><description><![CDATA[This essay was written by an AI agent of 100monkeys.ai and is published by the company. We build AEGIS and Zaru, the two products named in its last…]]></description><link>https://100monkeys-ai.hashnode.dev/the-approval-is-the-product-why-an-agent-orchestrator-should-make-you-say-yes</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/the-approval-is-the-product-why-an-agent-orchestrator-should-make-you-say-yes</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[Security]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[open source]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Wed, 28 Oct 2026 16:02:04 GMT</pubDate><content:encoded><![CDATA[<p><em>This essay was written by an AI agent of 100monkeys.ai and is published by the company. We build AEGIS and Zaru, the two products named in its last section, so read that part as a maker's account.</em></p>
<p>The usual pitch for an agent platform is about what the agent can do without you. It can open the pull request, answer the ticket, send the follow-up, run overnight. The less you have to touch it, the better it is supposed to be.</p>
<p>We think that pitch has the value backwards. The useful property of an agent system is not how little it needs you. It is how precisely it lets you decide what it may do, and how reliably it stops at the line you drew. The approval is not friction around the product. For anything that acts in the world on your behalf, the approval is the product.</p>
<h2>Two kinds of yes</h2>
<p>There are two moments at which a person can say yes to an agent.</p>
<p>The first is in advance. Before the agent runs, someone writes down what it is allowed to touch: which tools, which networks, which files, which secrets. Everything else is refused. This is a yes given once, in a form a machine can enforce and a person can read later.</p>
<p>The second is at the moment of the act. The agent has prepared something consequential, an email to a stranger, a payment, a deletion, and it stops and waits. A person reads the exact thing about to happen and says yes or no to that one act.</p>
<p>Most systems offer a weak version of one and skip the other. An allow-list exists but defaults to open. A confirmation exists but appears so often that people click through it, or it appears after the act, as a notification of what already happened. Neither is a yes in any meaningful sense.</p>
<h2>Why the first yes belongs in the runtime</h2>
<p>A rule written in a prompt is a request. The model may follow it. Under pressure, under a clever input, or simply under a long enough task, it may not, and nothing outside the model notices.</p>
<p>A rule written in the runtime is a wall. If the policy says the agent cannot reach a host, the network call fails no matter what the model decides. If the agent is never handed the credential, no prompt can make it leak the credential. This is the difference between limits by promise and limits by architecture, and it is the reason an orchestrator, not a model, is where the first yes should live.</p>
<p>It is also why the default matters more than any single rule. A deny-by-default policy means the absence of a yes is a no. An allow-by-default policy means every gap in the policy is a permission nobody granted. Agents find gaps quickly, not out of malice but because they try things.</p>
<h2>Why self-hosted</h2>
<p>If the runtime holds the first yes, then whoever runs the runtime holds it too. For a hobby project that may not matter. For an agent that touches your source code, your customers or your infrastructure, the person who decides what the agent may do should be someone in your organisation, on machines you control, reading a policy you can audit. Self-hosting is not a deployment preference here. It is where the authority sits.</p>
<h2>Why the second yes must be exact</h2>
<p>The second yes fails in a quieter way. If the approval attaches to a description of the act rather than the act itself, the agent can change the act after the yes. If the approval is a general permission ("you may send emails"), it is the first yes again, given carelessly.</p>
<p>A useful approval at the moment of the act shows the exact thing, binds to that exact thing, and expires if the thing changes. One message, read and approved. Then the next one.</p>
<h2>Durable, so a yes is not lost</h2>
<p>There is a practical requirement under both kinds of yes: the state of the work has to survive. An agent waiting an hour for a person to approve something cannot lose its place when a process restarts. If it does, the system either drops the work, which teaches people to avoid approvals, or retries it from the start, which can repeat acts already done. Waiting for a person is only safe if the waiting is durable.</p>
<h2>What we build for each yes</h2>
<p>At 100monkeys.ai we build both sides, and each sentence below is what our public pages or our own measured use states.</p>
<p>AEGIS by 100monkeys.ai, in beta, holds the first yes. In the words of its home page, "AEGIS is a self-hosted orchestrator that runs autonomous agents in isolated, policy-enforced runtimes with durable FSM state." Its security policy is declarative and deny-by-default. Agent runs are isolated at the kernel level, in micro-VMs or rootless containers. Secrets are held by a keymaster, so agents never see the credentials they use. Tool calls go through SEAL, a cryptographic tool-call protocol. Workflows are durable, so state survives a crash or a restart. It is open source under AGPL-3.0, and it installs with one line copied from its home page:</p>
<p><code>curl -fsSL https://get.100monkeys.ai | bash</code></p>
<p>Zaru holds the second yes. It is a personal AI that works alongside its user, remembers them and shows its work, and its memory of the person is theirs to read and edit. Here is what that looks like in our own use: when Zaru's mail tool sends an email for our founder, by default the send does not happen. It answers that approval is pending and waits in Zaru's web app under Approvals until he approves that one message. Zaru is sold by My Zaru, Inc. at myzaru.com.</p>
<p>Neither of these makes an agent safe on its own. What they do is keep a person in a position to decide, before the run and at the act, and that is the part most agent tooling leaves out.</p>
<h2>What we would like to hear</h2>
<p>If you run agents that act outside a sandbox, we would like to know where your yes lives today: in a prompt, in a policy, or in a person's inbox after the fact. And if you have built an approval step that people do not click through, we would like to learn how.</p>
<p><em>Disclosure: 100monkeys.ai builds AEGIS by 100monkeys.ai, an open-source agent orchestrator in beta; Zaru, a companion that asks before it acts; and Carbon Forge, the record people and agents share. This essay was drafted by one of our agents. AEGIS, its docs and the install line are here: <a href="https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28</a></em></p>
]]></content:encoded></item><item><title><![CDATA[When agents share a codebase: lanes, changesets and blame that remembers why]]></title><description><![CDATA[We build Carbon Forge at 100monkeys.ai. This article was written with the assistance of an AI writing program: one of our agents drafted it from our public…]]></description><link>https://100monkeys-ai.hashnode.dev/when-agents-share-a-codebase-lanes-changesets-and-blame-that-remembers-why</link><guid isPermaLink="true">https://100monkeys-ai.hashnode.dev/when-agents-share-a-codebase-lanes-changesets-and-blame-that-remembers-why</guid><category><![CDATA[AI]]></category><category><![CDATA[ai agents]]></category><category><![CDATA[Git]]></category><category><![CDATA[mcp]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[100monkeys.ai]]></dc:creator><pubDate>Wed, 28 Oct 2026 10:10:07 GMT</pubDate><content:encoded><![CDATA[<p><em>We build Carbon Forge at 100monkeys.ai. This article was written with the assistance of an AI writing program: one of our agents drafted it from our public docs, and every claim about the product was checked against those docs before publishing.</em></p>
<p>A single engineer in a git repository has a loop that fits: clone, branch, commit locally, push, open a pull request, merge. Put ten coding agents in the same repository at the same time and every step of that loop starts to cost something.</p>
<p>Each agent needs a working copy before it can read a line. Each branch starts going stale the moment it is cut, because nine other agents are landing work on main while it runs. Merges are computed by a tool that knows the text on both sides and nothing about what either side meant. And weeks later, when someone asks why a line exists, the answer in the log is whatever the agent typed into a commit message at the end of a long run, which is often "update file".</p>
<h2>The scale version of the problem</h2>
<p>Anthropic's write-up on Scion, published October 13, 2026, describes merges to its monorepo going from about 2,500 a day in May to over 30,000 a day in September. The article sets out three principles for the system they built in response:</p>
<ul>
<li>Clients are always online.</li>
<li>Commits must be cheap, incremental, and lock-free.</li>
<li>The working copy is optional, and sparse by design.</li>
</ul>
<p>Most teams will never see 30,000 merges a day, but the shape of the problem arrives the first afternoon you let three agents work on the same service in parallel and spend the evening untangling what they did to each other.</p>
<p>Carbon Forge was built to the three principles that article lists, and it differs where its docs say so: it serves many workspaces rather than one monorepo, and it takes a row lock per entity it writes. The rest of this article walks through the mechanisms that matter when several agents share one codebase. We have no affiliation with Anthropic; their article is the clearest statement of the problem we have read.</p>
<h2>One record, on the server</h2>
<p>Carbon Forge keeps code, files and prose in one record on the server, and people and agents read and write it through the same tools.</p>
<p>There is no local repository to keep in sync, so there is no "my copy is behind" state for an agent to get into. Agents reach the record over MCP with the same tools the editor uses, so an agent is not a second-class client talking to a side API.</p>
<p>Blame, grep, diff and history run on the server, so an agent that needs to know where a function is called asks the question instead of first pulling down a copy of the repository.</p>
<h2>Lanes instead of branches</h2>
<p>An agent opens a lane instead of cloning: a lane is a set of patches over the trunk, and every read on it composes the trunk as it stands now with those patches.</p>
<p>The useful word there is <em>now</em>. A git branch is a snapshot of main at the moment it was cut, plus your commits. The longer an agent works, the further that snapshot drifts from reality, and the bigger the merge at the end. A lane has no snapshot to drift. When another agent lands work on the trunk, your next read on your lane already sees it, with your patches applied on top.</p>
<p>So the question "does my change still apply?" is asked continuously, on every read, rather than once at the end when the answer is most expensive.</p>
<h2>No automatic merge, on purpose</h2>
<p>Carbon Forge never merges text by itself. A patch that no longer applies is reported as a named conflict, and the caller answers it against the trunk it saw.</p>
<p>A textual three-way merge is a guess: it is usually right, and when it is wrong it is silently wrong, producing code that compiles and does the wrong thing. A person reviewing a pull request might catch that. An agent landing its fortieth change of the afternoon will not.</p>
<p>When a patch stops applying, Carbon Forge does not guess. It names the conflict and hands it back to the caller, which is the one party that knows what the patch was for. The resolution is made against the trunk as the caller saw it, so it is a decision about real code rather than about a merge base from an hour ago.</p>
<h2>Changesets: all of it or none of it</h2>
<p>A landing is one changeset: every page, atom, code tree and file it names is written in one transaction, or nothing is.</p>
<p>An agent can time out, lose its connection or be stopped halfway through a change that touches six files. In a system where each file write stands alone, that leaves the codebase in a state nobody intended. With a changeset, the half-finished change does not exist: either the whole landing is on the trunk or none of it is.</p>
<p>The same transaction covers prose. A code change and the page that documents it land in the same changeset, together or not at all. The page that explains a function can move in the same landing as the function.</p>
<h2>Blame that answers "why"</h2>
<p>Every landing is sealed with an intent: the sentence the agent wrote, at the moment it landed the change, saying what the change is for. Blame shows next to each line the intent the agent wrote when it landed it.</p>
<p>When a reviewer, human or agent, asks why a line is there, the answer is not reconstructed from a diff and a guess. It is the sentence written by the author at the moment of the change, attached to the line.</p>
<p>History is kept the same way. Every revision and every changeset is hash-chained, and a revert is a new landing, so history only moves forward. A cut names one sealed snapshot of the workspace and never moves, so a release has one answer for as long as the workspace exists.</p>
<h2>Review and permissions for agents</h2>
<p>On a protected trunk, a <code>.landing-rules</code> page names the approvers each path needs, and an approval binds to the lane's exact state, so a later patch voids it. When the author is an agent that can add a patch at any moment, an approval that survived later patches would not mean much.</p>
<p>Agents also do not all need the same reach. A token can be held to a preset such as SCM reader, which writes nothing. An agent whose job is to read code and report gets a token that cannot change anything.</p>
<h2>Git keeps working</h2>
<p>None of this asks a team to give up its git tooling. Git is a projection: every code tree renders to a git history and pushes to GitHub fast-forward only, so git tooling keeps working.</p>
<h2>The orchestrator: AEGIS</h2>
<p>Where code lives is half of running agents in parallel; running the agents is the other half. Our open-source project for that is AEGIS by 100monkeys.ai, in beta. In the words of its home page: "AEGIS is a self-hosted orchestrator that runs autonomous agents in isolated, policy-enforced runtimes with durable FSM state." It is open source under AGPL-3.0. The site gives a one-line install, <code>curl -fsSL https://get.100monkeys.ai | bash</code>, and the details are at <a href="https://100monkeys.ai/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">100monkeys.ai</a>.</p>
<h2>The companion: Your Zaru</h2>
<p>The third thing we build is for the person rather than the codebase. Your Zaru is a personal AI companion that works alongside you, remembers you and shows its work: it handles messages, planning, follow-ups and scheduling, and keeps a memory of you that you can read and edit. It runs on AEGIS, it has a free plan, and it is sold by My Zaru, Inc. at <a href="https://myzaru.com/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">myzaru.com</a>.</p>
<h2>Trying Carbon Forge</h2>
<p>Public workspaces are free, and every account includes one free private workspace; the plans beyond that are on the pricing page at carbonforge.dev/pricing. The engineering docs are public, starting at carbonforge.dev/docs, including the full source-control design.</p>
<p>We would like to hear from anyone running more than one agent against the same codebase: what broke first, and what you did about it. You can sign up at <a href="https://carbonforge.dev/?utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=push-2026-10-28">carbonforge.dev</a>.</p>
]]></content:encoded></item></channel></rss>