Skip to content

gramatico-loop: approved issues become pull requests, as pirsig-2nd-brain - #3

Merged
h0ffmann merged 3 commits into
mainfrom
feat/gramatico-loop
Nov 1, 2026
Merged

h0ffmann merged 3 commits into
mainfrom
feat/gramatico-loop

Conversation

@h0ffmann

@h0ffmann h0ffmann commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

What

agent gramatico-loop runs one step of a loop on piabrota/gramatico: a code owner labels an issue, the model edits a copy, the harness checks the diff, gramatico's CI is the checker, and a person merges. A failed check gets a repair on the same branch. At the attempt cap, it stops and asks a person.

It acts as a new GitHub App, pirsig-2nd-brain, that a maintainer still has to create. Until then it logs that it is off and exits 0, so this is safe to merge first. The README has the full design and the setup steps.

Design

  • What starts work: loop/pronto, added by someone in LOOP_APPROVERS, on an issue by a trusted author. The author matters because anyone can edit their own issue after the label.
  • Hard limits: 2 attempts per issue, 3 per day, 1 open pull request, 8 files, 300 lines. A setting can tighten a limit but not pass its ceiling, and a bad value fails before anything is spent.
  • Fail-closed budget: an attempt is a comment posted before the model runs. A crash still counts, and no memory store can open the budget.
  • Protected paths and a shrink guard: CI, quality gates, AGENTS.md, locks, dependency manifests and the plugin's binaries and hooks stay with people. Also rejected: deleted files, symlinks, binaries, fewer tests, fewer ⚠, and a document without its mirror.
  • Kill switch: the label loop/pare on any open issue.
  • Never merges: no merge call, and no auto-merge, because gramatico's main has no required review. The App has no workflows or administration permission.

Security: .git is out of the model's reach

The model has file tools. A hook or core.fsmonitor written into repo/.git would run as code when the harness calls git add, in a pod that holds the App's key. So the git directory moves outside the model's directory, and every git call names it. A test plants both. With the protection removed (a mutation run), exactly that test fails.

⚠ deploy-doctor and mirror-keeper still run git add inside a .git the model's Edit tool may reach. They have no Write, but .git/config already exists. Whether Claude Code's own protections block this was not checked, and this PR does not change them. It needs a look.

What came from ouroboric

The README has the table. Taken: hard gates no config can switch off, attempts capped against the "flaky test all night" failure, a checker that is not the agent grading itself, protected paths and the shrink guard, a bot with no merge rights, and never arming auto-merge without a required approval. lib/github-app.sh already minted tokens the way as-bot.sh does.

Not taken: the graph engine, a sandboxed implementer that can run the build, and a separate reviewer model. Nothing can be built in this pod, so a wrong change only meets CI and a person.

Other changes

  • lib/common.sh, lib/github-app.sh: two error messages now name the App in use, not piabrota-ops.
  • test/fake_github.py: issue events, labels, runs by commit, closed pull requests.

Tested

  • test/run.sh: 123 checks pass, in ubuntu:24.04 on arm64.
  • shellcheck, shfmt, ruff and radon pass.
  • ⚠ Everything ran against the fake GitHub and the fake claude. The loop has never run against the real Claude Code or real GitHub.
  • ⚠ claude --help at 2.1.316 shows no turn limit, so the only limit inside a run is LOOP_TIMEOUT (1200 s).

Before the first label

  1. Create the App from apps/pirsig-2nd-brain.json and install it on gramatico only.
  2. Add PIRSIG_APP_ID and PIRSIG_APP_PRIVATE_KEY_B64 to agents.env.
  3. Add loop/pronto and loop/pare to gramatico's ISSUE_LABELS.md.
  4. Add the rax task in nix-os.
  5. Protect gramatico's main: today it has no branch protection, and the App will have contents write.

🤖 Generated with Claude Code

h0ffmann and others added 3 commits November 1, 2026 03:14
…rain

One step at a time: wait on the open pull request, repair it, or start the
next issue. A code owner's label starts work, the harness checks the diff,
the repository's CI is the checker, and a person merges. Attempts are
comments posted before the model runs, capped per issue and per day, and a
setting cannot raise a limit past its ceiling. Off without the App's
credentials, so it can ship before the App exists.

The model edits a copy with file tools only, and its git directory lives
outside the model's reach: a hook or core.fsmonitor in repo/.git would run
as code in a pod that holds the App's key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fake GitHub gains issue events, labels and runs by commit, and each
gate, rejection and repair has a scenario. 123 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@h0ffmann
h0ffmann merged commit 9647cf0 into main Nov 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant