Skip to content
omkar-dhakanePublic

About

Autonomous, safety-first GitHub repository maintainer. Triages issues, writes code, runs tests, opens PRs - and can never merge, force-push, or touch protected branches.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Keeper

An autonomous, safety-first GitHub repository maintainer.

Keeper watches a repository like a tireless, paranoid maintainer: it triages issues, answers questions, writes code, runs the full test suite, and opens clean pull requests — while it is physically unable to merge a PR, force-push, rewrite history, or touch a protected branch.

Observe → Propose → Gate (safety kernel) → Act → Verify → Log → Checkpoint

License: MIT Python Tests


Why Keeper exists

Maintaining an open-source repo is a 24/7 job nobody can do 24/7. Issues pile up, questions repeat, small fixes wait weeks. Keeper runs as a long-lived agent that handles the steady stream — and documents every decision it makes in a public, append-only DECISION_LOG.md so you can audit everything after the fact.

Hard safety guarantees (in code, not in prompts)

Guarantee How it's enforced
Never pushes to main/protected branches All writes go to keeper/* branches; anything else is refused before execution
Never force-pushes or rewrites history Force/rebase/amend/delete commands are unrepresentable in the git layer
Never merges a PR No merge operation exists in the codebase at all
Tests before PRs, always A PR handler refuses without fresh, passing test evidence matching the pushed SHA
High-risk changes need a human Auth/payments/migrations/large changes escalate to a local approval file
Hard rate limits & budgets Token bucket + daily caps block requests before they're sent
Crash-safe Every action lands in an append-only outbox before execution; resume reconciles in-flight work without duplicates
Kill switch state/HALT file stops everything; keeper pause downgrades to read-only

What it does today

  • Triage — classifies new issues (bug/enhancement/question) and labels them
  • Respond — asks for repro details on unlabeled bug reports
  • Implement — creates a worktree, applies the change, runs the full test suite, and only then pushes a branch and opens a PR (Closes #N, test evidence embedded in the PR body)
  • Observe & document — KEEPER_STATUS.md, an HTML dashboard, and the public decision log regenerate every cycle
  • Survive — checkpoint/resume, budget rollovers, episode compaction, and cooldowns keep it stable for multi-day unattended runs

Quickstart

git clone https://github.com/omkar-dhakane/keeper.git
cd keeper
python -m venv .venv
.venv\Scripts\activate        # Windows
# source .venv/bin/activate   # Linux/macOS
pip install -e ".[dev]"

keeper init                   # creates keeper.yaml + state/
# edit keeper.yaml: set target.repo = your-username/your-repo
keeper observe                # one safe, read-only cycle against your repo
keeper status                 # see what Keeper sees

Going live (writes enabled)

  1. Create a GitHub App (Settings → Developer settings → GitHub Apps) with least-privilege repo permissions: Issues RW, Pull Requests RW, Contents RW, Metadata R. Disable webhooks.
  2. Install it on your repo; note the App ID and installation ID, and download the private key.
  3. Put the key at secrets/keeper-app.pem, and fill github.app_id, github.app_installation_id, github.app_private_key_path in keeper.yaml.
  4. Keep mode: observe until you're happy with state/plans/, then switch:
mode: actor   # Keeper may now label, comment, and open PRs within budgets
keeper run    # the continuous loop (Ctrl-C or the HALT file to stop)

High-risk changes park in state/approvals/ — review with keeper status, then keeper approve <id> or keeper deny <id>.

Configuration

Everything lives in keeper.yaml (annotated, validated at startup):

target:  { repo: "you/your-repo", clone_path: "state/target" }
mode:    observe                     # observe | actor
loop:    { poll_interval_seconds: 900, jitter_seconds: 120 }
safety:  { max_actions_per_cycle: 3, protected_branches: [main, master] }
budgets: { daily_comments: 10, daily_prs: 2, daily_api_calls: 800 }
llm:     { provider: mock }          # rules | anthropic | openai | ...
github:  { auth_method: app, app_id: "", app_installation_id: "",
           app_private_key_path: "secrets/keeper-app.pem" }

Project layout

keeper/
├── core/       agent loop, pluggable brain (mock / rules / LLM providers)
├── safety/     kernel: invariants, risk classifier, approval gate
├── github/     rate-limited API client, poller, models  (read+scoped-write only)
├── repo/       guarded git, worktrees, test runner, repo map, janitor
├── actions/    the only verbs Keeper has: comment, label, branch_commit, pr_open
├── memory/     outbox, checkpoints, episodes, decision log
└── observe/    audit trail, status page, dashboard
tests/          156 tests incl. real-git end-to-end and security regressions

Development

pip install -e ".[dev]"
pytest          # full suite: unit + integration + security regressions

Every safety invariant has tests; [critical|high] fixes land with regression tests (see tests/test_security_regressions.py).

Roadmap

  • Real LLM providers behind the Brain interface (anthropic/openai/…)
  • Review-response loop (reply to PR review comments)
  • Containerized test sandbox
  • Hosted dashboard / webhooks mode

Contributing

Issues and PRs welcome. Please keep the safety kernel's invariants intact — PRs that weaken them will be rejected by design.

License

MIT — see LICENSE.

About

Autonomous, safety-first GitHub repository maintainer. Triages issues, writes code, runs tests, opens PRs - and can never merge, force-push, or touch protected branches.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages