English | Deutsch
Neutral, installable core for GitHub repository maintenance: issue triage, duplicate detection, pull-request summaries, read-only health/traffic/star reports, a preview/apply contract for every write, a plugin SPI and signed exact-SHA review receipts. Pure Python standard library, no runtime dependencies.
Status: alpha (0.2.1). The CLI, the JSON result envelope and SPI version 1 are the contract; everything else may still change.
- Triage – classifies open issues with configurable keyword criteria and plans labels and auto comments (with an invisible marker so a comment is never posted twice).
- Duplicates – Jaccard similarity on word tokens, offline on a JSON file.
- Pull-request summary – size check and summary; project-specific policy checks come from plugins only.
- Reports – Dependabot / Actions / issues / PRs / code- and secret-scanning health, traffic (14 days) and star rankings. Read-only.
- Preview / apply – nothing is written unless you pass
--apply. Every write is anAction, checked against a permission ceiling, and leaves a receipt. With a receipt store, repeated runs skip actions that were already applied. - Plugin SPI – extensions propose actions or add pull-request checks through an entry point. A missing extension is reported as "not available"; the core keeps working.
- Credential adapter – tokens come from
GH_TOKEN/GITHUB_TOKENorgh auth tokenat runtime. Nothing is stored or bundled. - Review gate – signed (OpenSSH), time-limited receipts bound to repository, PR number and the exact head SHA, verified by a GitHub Actions workflow that never executes pull-request code.
Requirements: Python 3.10+, the GitHub CLI (gh auth login) for
commands that talk to GitHub, OpenSSH ssh-keygen for review-gate signatures.
pip install git+https://github.com/dev-bricks/githubbot-core.git
githubbot-core --version
githubbot-core doctorFrom a checkout: pip install . (development: pip install -e ".[dev]").
# Read-only reports
githubbot-core health --repo owner/repo --repo owner/other
githubbot-core traffic --repo owner/repo
githubbot-core stars --repo owner/repo
# Triage: preview (default) -> apply the very same plan
githubbot-core triage --repo owner/repo
githubbot-core --json triage --repo owner/repo # note plan_sha256
githubbot-core triage --repo owner/repo --apply --expect-plan <plan_sha256> --receipts receipts.jsonl
# Offline helpers (JSON file in gh or REST issue format)
githubbot-core classify --input issues.json
githubbot-core duplicates --input issues.json --threshold 0.8
# Pull-request summary (+ checks from installed plugins)
githubbot-core review-pr --repo owner/repo --pr 12
# Plugins and system agent template
githubbot-core plugins
githubbot-core --json system-agent
githubbot-core run <plugin> [--plugin-arg ...] [--apply]python -m githubbot_core ... works the same way.
With --json every command prints one envelope:
{"schema": "githubbot-core.result/v1", "command": "triage", "ok": true,
"mode": "preview", "data": {"plan_sha256": "…", "actions": [], "writes": 0}, "errors": []}mode is read, preview or apply. Exit codes: 0 ok, 1 runtime error (for example GitHub
not reachable or a write failed), 2 configuration or usage error, 3 plugin not available.
The Python API is the package itself: githubbot_core.triage.IssueTriage,
githubbot_core.actions.preview/apply, githubbot_core.health.RepoHealthCollector,
githubbot_core.plugins, githubbot_core.review_gate, githubbot_core.credentials.
githubbot-core --json system-agent prints the neutral agent template shipped with the package
(schema githubbot-core.system-agent/v1): version (package version), sha256 over the canonical JSON of
{schema, id, blueprint} (sorted keys, compact separators, UTF-8; verifiable from the printed output), capability, the effective permissions and a blueprint with the field names of the
agent-studio blueprint payload (persona, role, contractus, governance, skills). The template
exists only where the package is installed. Consumers bind an agent to version + sha256 and must
not overwrite an existing agent configuration when a newer template appears.
The packaged defaults (githubbot_core/default_config.json) are extended with --config file.json
layers, applied in order (for example a profile, then a host-local file). Ordinary keys are merged,
later layers win. Permission ceilings are different: a later layer may only narrow
permissions.ceiling and permissions.api_write_prefixes; an attempt to widen them is an error,
not a silent override. permissions.enabled must stay inside the ceiling.
| Action kind | Default | Executes |
|---|---|---|
issue.add_labels |
enabled | POST /repos/{repo}/issues/{n}/labels |
issue.comment |
enabled | POST /repos/{repo}/issues/{n}/comments |
api.request |
disabled | any write method on an endpoint that starts with one of permissions.api_write_prefixes |
pr.merge |
disabled | re-reads the PR (open, exact sha, default base, not draft, mergeable_state clean, configured merge account), PUT …/pulls/{n}/merge with sha, reads merged back |
pr.ready |
disabled | re-reads the draft at the exact sha, GraphQL markPullRequestReadyForReview, reads back |
actions.dispatch |
disabled | POST …/actions/workflows/{workflow}/dispatches for an active workflow |
actions.rerun |
disabled | POST …/actions/runs/{id}/rerun for a completed, non-fork run of the exact sha |
pr.create |
disabled | POST …/pulls from a bot-prefixed branch onto the default branch |
git.push_branch |
disabled | git push origin <sha>:refs/heads/<branch> without force, bot prefix only (typed_actions.push_branch_prefix, default bot/), never the default branch, verified with ls-remote |
The six typed actions sit in the default ceiling but are never enabled by default. Each one also
needs its multi_bot switch (merge_enabled, policy.draft_*, policy.trigger_missing_ci,
policy.open_fix_prs); a permission alone opens nothing. One action at a time:
githubbot-core --config instance.json act pr.merge --params '{"repo": "o/r", "number": 7, "sha": "<40-hex>"}'
githubbot-core --config instance.json act pr.merge --params '…' --apply --expect-plan <plan_sha256>{"permissions": {"enabled": ["issue.add_labels", "issue.comment", "api.request"],
"api_write_prefixes": ["user/starred/"]}}Declare an entry point in the group githubbot_core.plugins that points to a zero-argument
factory:
[project.entry-points."githubbot_core.plugins"]
my-extension = "my_extension:create"from githubbot_core.actions import Action
from githubbot_core.plugins import SPI_VERSION
class MyExtension:
name = "my-extension"
spi_version = SPI_VERSION
def describe(self):
return {"version": "1.0.0", "capabilities": ["plan"]}
def plan(self, ctx): # ctx.config, ctx.transport (read-only), ctx.args
data, error = ctx.transport.get("repos/owner/repo")
return [Action("api.request", {"method": "PUT", "endpoint": "user/starred/owner/repo"}, reason="example")]
def pr_policy_checks(self, pr, files, diff): # optional
return [("no_large_binaries", True, "OK")]
def create():
return MyExtension()Plugins never write themselves: the core previews or applies their plan under the configured permissions. During planning they only get a read-only transport.
githubbot-core gate-scaffold --dest <checkout> [--namespace name] previews, and with --apply
writes, .github/workflows/review-gate.yml plus the standalone verifier
.github/review-gate/review_gate.py into a target repository. Receipts are created, signed,
verified and dispatched with githubbot-core review-gate create|sign|verify|dispatch. Details,
trust boundaries and rollback: docs/REVIEW_GATE.md.
pip install -e ".[dev]"
python -m pytest # unit and contract tests
ruff check .
ruff format --check .
GITHUBBOT_CORE_CONSUMER_TEST=1 python -m pytest tests/test_consumer_install.py # fresh-venv install testWritten by Lukas Geiger with AI assistance (code generation and review by large language models), extracted from a private maintenance tool and rebuilt as a new tree without that tool's history. No third-party code is included; see THIRD_PARTY_LICENSES.md.
python -m githubbot_core multi-bot delegates mode/provider/model/effort selection to the
optional TASKPLAN launcher. The visible menu is 1 operator (default), 2 bot-triage (PR triage/reviews only), and 3 github-maintain (fixes and maintenance). Operator checks fresh PR work before every unit, then fixes, then policies/gates/privacy and care. Initial policy preference and evidenced policy/care alternation are a documented heuristic; urgent policies precede routine care. Missing TASKPLAN produces an installation hint
and starts no provider. --dry-run enables TASKPLAN's no-probe dry run.
Wheels and sdists ship githubbot_core/prompts/MULTI-BOT.de.md, neutral starters under
githubbot_core/starters/windows and starters/posix, and the care/probe helper modules.
githubbot-core --json multi-bot-role --mode operator exports one
role using the existing strict descriptor schema. system-agent remains unchanged;
role definitions live in the separate packaged multibot_roles.json resource. Runtime root defaults to the current directory. Merge is
disabled and full access is not forced by public defaults. Explicit --config layers may
set multi_bot.root, instance_prompt, merge_account, merge_enabled, and
trusted_automation. The configured action permission ceiling remains binding.
The starter never searches hidden credential paths. Accounts, authentication, slots and
host roots belong to private instance configuration. multi-bot-care --root PATH next
and multi-bot-probe --root PATH require explicit registry/org/host-log data and fail
closed when absent. Private runtime/extensions remain separate consumers; no background
service or executable automatic merge is installed.
Named legacy flags triage, review-merge, and aftercare retain their original limited behavior and are absent from the new three-choice menu. Choosing a role never enables merges or widens permissions.
githubbot-core --json multi-bot-select --input SNAPSHOT.json --mode operator makes a deterministic read-only decision from an existing snapshot. It creates no queue, work item, persistent state, or agent. The snapshot contains candidates, optional processed and lastMaintenance. Candidates require id, an exact lowercase 40-character commit revision, status (ready, blocked, done), category (prs, fixes, policies, care), and optional boolean urgent. Processed records carry the same identity/category, blocked/done status and a nonempty evidence reference; the caller verifies the actual evidence. lastMaintenance points via {id, revision} to an evidenced successful policy/care completion. Selection and repeated empty checks never advance it. Unknown values are rejected. Exact processed heads are skipped; changed PR heads can preempt fixes and maintenance. Equal-priority candidates sort by ID and SHA.
The neutral ASCII Windows starter is titled MULTI-BOT COMPANION, explains foreground operation and pauses after success, failure or STOP. Only explicit --dry-run, TASKPLAN_STARTER_DRY_RUN=1 or MULTIBOT_NO_PAUSE=1 skips the pause. It installs nothing and opens no extra window.
