Skip to content
AstroloopPro

Indexed at build time — no server, no tracking

자율적이되, 목줄은 채운 채로

당신이 자는 동안 백로그를 닫는 에이전트.

이슈를 읽고, 브랜치를 만들고, 풀 리퀘스트를 열고, 머지 버튼 앞에서 멈춥니다. 중요한 세 가지 결정만 승인하고 나머지 마흔 개는 건너뛰세요.

도입을 승인해야 했던 사람들이 쓰고 있습니다

카드 불필요. 모든 동작이 기록됩니다. 도구를 회수하면 다음 실행부터 반영됩니다.

run · issue #482live
  1. 00:03github.search3 files reference buildCacheKey
  2. 00:18shell.test1 failing — the fixture never renames
  3. 00:34github.openPullRequest#1203 opened as a draft
  4. 00:36github.mergeNot called — requires approval
Waiting for a person@rina-k

Running in production at

How it works

루프를 돌다가, 당신이 신경 쓰는 지점 앞에서 멈춥니다.

모든 실행은 같은 모양입니다. 중요한 건 자율적이라는 사실이 아니라, 그 자율이 어디서 끝나는가입니다.

GOALan outcomePLANinto stepsACTpicks a toolOBSERVEreads resultsHANDOFFwaits for youRESULTTOOL CALLnot done yet

Transcript

Pro only— not included in the free template at https://astroloop.larryxue.dev

One real run, including the part where it got it wrong.

Every step it took on issue #482, in order, with the arguments in full. Step five failed. Step ten was never called.

11 steps · 36.5s wall clock

  1. 00:00.0Goal receivedClose240mssucceeded
    issue:  #482
    repo:   northgate/atlas
    opened: 6 days ago by @rina-k
  2. 00:00.2Planned 4 stepsReproduce, locate the cache key, fix, prove it with a test3.1ssucceeded
    1. reproduce against a scratch index
    2. find where the collection name is baked into the cache key
    3. change the key to include the collection id
    4. add a regression test that renames and re-queries
  3. 00:03.3github.search3 files reference buildCacheKey890mssucceeded
    query: "buildCacheKey" in:file repo:northgate/atlas
    → src/search/cache.ts:41
    → src/search/index.ts:118
    → test/search/cache.test.ts:9
  4. 00:04.2github.readFilesrc/search/cache.ts410mssucceeded
    export function buildCacheKey(collection: Collection) {
      return `idx:${collection.name}:${collection.version}`
    }
    // the name is the problem — it changes on rename, the id does not
  5. 00:04.6shell.test1 failing — the fixture never renames anything14.2sfailed
    $ npm test -- search/cache
    ✗ invalidates on rename
      Expected the key to change, received the same key twice.
      The fixture builds one collection and asserts on it. There is
      nothing here that renames, so the test cannot have been covering
      this path.
  6. 00:18.8github.readFileRe-read the fixture rather than the test2.3schanged approach
    test/fixtures/collection.ts
    → the fixture is frozen at construction, so a rename is not expressible
    Adjusting the plan: the fixture has to change before the test can.
  7. 00:21.1shell.test214 passing, including the new rename case11.8ssucceeded
    $ npm test -- search
    ✓ invalidates on rename
    ✓ keeps the key stable across a version bump
    214 passing (11.8s)
  8. 00:32.9github.createBranchfix/482-cache-key-uses-id1.5ssucceeded
    base:   main @ 9f2c1ab
    branch: fix/482-cache-key-uses-id
    3 files changed, 41 insertions, 12 deletions
  9. 00:34.4github.openPullRequest#1203 — Key the search index by collection id2.1ssucceeded
    Opened as a draft, linked to #482, and the failing test from step 5
    is included in the description so the reviewer can see what was
    actually broken.
  10. 00:36.5github.mergeNot called — merge requires approvalnot called — needs approval
    The tool definition lists `merge` under approval, so the call was
    never made. This is a line in the transcript rather than an absence
    of one: an absence looks like a bug.
  11. 00:36.5Waiting for a personAssigned to @rina-kwaiting for a person
    The run stays open until someone approves or declines. Declining
    closes it unbilled.

01

Scoped at the call site

Permissions are enforced where the tool is invoked, not asked for politely in a system prompt. A revoked tool is gone on the next run, mid-task included.

02

Every run leaves a trace

Each step records the tool, the arguments, the result and the elapsed time. When something goes wrong you get a transcript, not a shrug.

03

Priced by work, not by seat

You pay for completed runs. A run that stalls, loops, or gets rejected at handoff does not bill.

Permissions

Everything it can reach, and everything it has to ask about first.

Scoped per tool, enforced at the call site rather than in the prompt. The blanks below are real: where there is no cell, there is no access.

ToolReadsWritesNeeds approvalAudited
GitHubrepos, issues, pull requestscomments, branchesWaits for approval on: merge, force-pushaudited
Slackchannels it is invited tomessages in those channelsno accessaudited
Postgresanalytics.* (read replica)no accessno accessaudited
Emailno accesssend as agent@yourdomainWaits for approval on: any external recipientaudited
Filesystem/workspace/workspaceWaits for approval on: delete, chmodaudited
Shellno accessno accessWaits for approval on: every commandaudited

Rows come from src/content/tools/tools.yaml. Leave a field empty and the cell stays empty — that is the honest version, and it is the one that gets believed.

And this is the whole of it.

One definition per tool. The four fields in the table above are the four fields here — there is no second place where permissions are configured, and no prompt that can widen them at runtime.

Delete a line and the capability is gone on the next run, mid-task included.

tools/github.ts
import { defineTool } from '@astroloop/sdk'

export const github = defineTool({
  name: 'github',

  reads:  ['repos', 'issues', 'pulls'],
  writes: ['comments', 'branches'],

  // Anything listed here stops the run and waits for a person.
  // Checked at the call site, so the agent cannot talk its way
  // past it the way it can with an instruction in the prompt.
  approval: ['merge', 'force-push'],

  audit: true,
})

Results

Pro only— not included in the free template at https://astroloop.larryxue.dev

Measured against a person doing the same 412 issues.

Including the row where we lose. Methodology is below the table, not behind a form.

TaskAstroloopBaselinenNote
Issue to merged pull request68%41%412Human review still required; measures reaching an approvable PR.
Correct on the first attempt44%39%412Retries are free, so this is a cost metric rather than a quality one.
Escalated to a person31%12%412Deliberately high. Every escalation is a run we chose not to guess on.
Actions taken without approval07412Enforced in the tool layer, so this is a property rather than a result.
Median wall clock per run214s96s412We are slower. Planning and re-reading cost time we choose to spend.

In production

1.24M

runs completed

last 30 days

3.1%

escalated to a person

and none of them silently

0

unapproved merges

since the check moved out of the prompt

11s

median time to first tool call

p95 is 34s

Logs and control

Pro only— not included in the free template at https://astroloop.larryxue.dev

What is written down, and who can read it back.

Every step, in full

Tool, arguments, result and elapsed time for each step. Arguments are never truncated — truncation is always where the interesting part was.

Approval is a person

Named actions suspend the run and wait. There is no timeout that approves for you, and no configuration that removes the gate.

Exportable audit log

Every permission change, approval and refusal, as NDJSON, with the actor attached. Ships to your SIEM or sits in object storage.

Your runner, optionally

Run the executor inside your own network. The control plane never sees the repository, only the run metadata.

Retention you set

Ninety days by default, anything from seven upward on Enterprise. Deletion is a hard delete, including from backups within thirty days.

Bring your own keys

Point it at your own model provider accounts. The permission layer does not change with the model.

Models

Pro only— not included in the free template at https://astroloop.larryxue.dev

Which model sees what, and where it goes.

Named per stage rather than described in the aggregate. Bring your own keys and none of it changes.

StageModelProviderYour keysRetentionSees
PlanningClaude Opus 5AnthropicsupportedZero retentionSees the issue text and the file tree, not file contents.
EditingClaude Sonnet 5AnthropicsupportedZero retentionSees only the files the plan named.
ClassificationLocal rule setRuns in your runnernot applicableNever leavesRegex and heuristics. No model involved.
Embeddingstext-embedding-3-largeOpenAIsupported30 days at providerOptional. Disabled by default.

What people say

The people who had to sign off on it.

I approved it for a two-week trial expecting to revoke it. What changed my mind was not the output, it was that every refusal showed up in the log with the reason attached.

Priya Raghunathan

Staff Security Engineer, Basalt

It closed forty-one issues in its first month and asked me eleven questions. The eleven were the right eleven, which is the part I did not expect.

Tom Íñigo

Engineering Manager, Northgate

We had already written the policy doc for what an agent would be allowed to do. Configuring it here took an afternoon because the fields were the same fields.

Wen Xiaoqing

Platform Lead, Quorum Labs

Pricing

You pay for work finished, not for people logged in.

A run that stalls, loops, or gets rejected at handoff does not bill.

Free

$0forever

20 runs a month

  • All tools, same permissions
  • Full run transcripts
  • Community support
Start free

Team

Most teams

$29per month

then $0.40 per run

  • Unlimited approvers
  • 90-day transcript retention
  • Slack and email handoff
  • Priority queue
Start free trial

Enterprise

Talk to us

volume pricing

  • Self-hosted runners
  • SSO and audit export
  • Custom tool allowlists
  • A person who answers
Contact sales

What it costs

Pro only— not included in the free template at https://astroloop.larryxue.dev

Move the slider. That is the whole pricing page.

Runs that stall or get declined at handoff are deducted rather than hidden, because they are the ones you would otherwise find on the invoice.

400
7%
Plan

Estimated monthly

$148

Plan
$29
Billable runs
312
Not billed
28
Per run after included
$0.40

At this volume the Team plan is the cheaper of the two. Scale pays off above about 590 billable runs.

Questions

The ones we get asked before the trial, not after.

What counts as a run?
One goal, from the first plan to either a result or a rejected handoff. Retries inside a run are not billed separately.
Can it act without asking?
Only for actions you have not listed under approval. Everything on that list suspends the run and waits, and the list is enforced in the tool layer rather than the prompt.
What happens when it stalls?
The run is cancelled at the step budget and not billed. You get the transcript either way.
Where does my code go?
Into the runner for the length of the run, and nowhere else. Self-hosted runners are available if that is still one place too many.
Which models does it use?
Whichever you configure, including your own keys. The permission layer does not change with the model.
Can I revoke a tool mid-task?
Yes. Permissions are read at the call site, so the next call fails closed even in the middle of a run.

저장소 하나를 맡기고 무엇이 돌아오는지 보세요.

월 스무 번, 무료. 권한과 실행 기록은 어떤 유료 플랜과도 동일합니다.

Astroloop ProSee what it addsBuy · $79