Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ Format: [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), [Semantic Vers

### Hinzugefügt / Added

- Getypte Schreibaktion `pr.review` für formale Reviews am exakten PR-Head mit Bot-Identitätsprüfung,
`publish_reviews`-Gate und unabhängigem Readback. Issue-Labels/-Kommentare binden MULTI-BOT-
Schreibvorgänge an das konfigurierte Konto und lesen Änderungen zurück. /
Added exact-head formal PR reviews with configured bot identity, a `publish_reviews` gate and
readback; MULTI-BOT issue writes now verify the configured account and read changes back.
- Selector und Rollen um Issue-Triage erweitert; Operator bearbeitet einzelne Kandidaten mit
frischer Auswahl weiter, bis der Umfang erledigt oder konkret blockiert ist. /
Selector and roles now include issue triage; operator continues across selected candidates with
refreshed state until the requested scope is complete or concretely blocked.
- Getypte Schreibaktionen `pr.merge`, `pr.ready`, `actions.dispatch`, `actions.rerun`, `pr.create`
und `git.push_branch` mit frischem Lesen, exakter Head-Bindung und Rücklesen; in der
Standard-Obergrenze, aber nie standardmäßig aktiv. Jede braucht zusätzlich ihren
Expand All @@ -26,6 +35,13 @@ Format: [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), [Semantic Vers
- README (EN/DE) mit Banner (`assets/banner.png`, Quelle `assets/banner.svg`); Testkommentar
neutral formuliert / README banner added; a test comment worded neutrally.

- `pr.review` liest nach dem Dublettencheck den PR-Zustand erneut und verweigert einen
zwischenzeitlich geänderten Head oder eine inzwischen als Draft markierte PR vor dem POST. Bestehende Reviews desselben Kontos
am selben Head, auch `DISMISSED`, verhindern ein erneutes POST. / After the duplicate
lookup, `pr.review` re-reads the PR and denies an observed head or draft change before
POST. Existing reviews by the same account for the same head, including `DISMISSED`,
prevent reposting.

## [0.2.1] - 2026-10-11

### Geändert / Changed
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pull-request summaries, read-only health/traffic/star reports, a preview/apply c
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;
> Status: alpha (0.2.2). The CLI, the JSON result envelope and SPI version 1 are the contract;
> everything else may still change.

## Features
Expand Down Expand Up @@ -110,16 +110,17 @@ not a silent override. `permissions.enabled` must stay inside the ceiling.
| `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.review` | disabled | verifies bot identity, open non-draft PR and exact head; `POST …/pulls/{n}/reviews` with `commit_id` and review event, then reads the formal review back; also requires `publish_reviews` and a configured enabled organization in `<runtime-root>/config/orgs.json` (`multi_bot.root`, default: current directory); global and organization `exclude_writes` are enforced, and a missing or invalid policy denies the review |
| `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:
The seven typed actions sit in the default ceiling but are never enabled by default. Each one also
needs its `multi_bot` switch (`merge_enabled`, `policy.publish_reviews`, `policy.draft_*`,
`policy.trigger_missing_ci`, `policy.open_fix_prs`); a permission alone opens nothing. One action at a time:

```bash
githubbot-core --config instance.json act pr.merge --params '{"repo": "o/r", "number": 7, "sha": "<40-hex>"}'
Expand Down Expand Up @@ -200,7 +201,7 @@ No third-party code is included; see [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICEN
## Optional MULTI-BOT role

`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
optional TASKPLAN launcher. The visible menu is **1 operator** (default), **2 bot-triage** (PR and Issue triage, independent PR reviews), and **3 github-maintain** (fixes and maintenance). Operator handles fresh PRs, then Issues, then fixes, policies/gates/privacy and care. A selector call chooses one candidate; the agent continues through the requested scope using refreshed lists. Preview alone is not completion. Merges remain opt-in through `effective_enabled` and all exact-head review/CI/identity/branch-protection gates. 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
Expand All @@ -220,6 +221,6 @@ 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.
`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`, `issues`, `fixes`, `policies`, `care`), and optional boolean `urgent`. Operator prioritizes PRs, Issues, then fixes; `bot-triage` handles PRs and Issues, while `github-maintain` handles fixes and maintenance. 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 until new evidence; 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.
13 changes: 7 additions & 6 deletions README_de.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Duplikaterkennung, Pull-Request-Zusammenfassungen, lesende Berichte zu Gesundhei
Sternen, ein Vorschau-/Ausführungsvertrag für jede Schreibaktion, eine Plugin-Schnittstelle (SPI)
und signierte Exact-SHA-Review-Belege. Reine Python-Standardbibliothek, keine Laufzeitabhängigkeiten.

> Status: Alpha (0.2.1). Verbindlich sind CLI, JSON-Ergebnishülle und SPI-Version 1; alles andere
> Status: Alpha (0.2.2). Verbindlich sind CLI, JSON-Ergebnishülle und SPI-Version 1; alles andere
> kann sich noch ändern.

## Funktionen
Expand Down Expand Up @@ -112,16 +112,17 @@ stille Überschreibung. `permissions.enabled` muss innerhalb der Obergrenze blei
| `issue.add_labels` | aktiv | `POST /repos/{repo}/issues/{n}/labels` |
| `issue.comment` | aktiv | `POST /repos/{repo}/issues/{n}/comments` |
| `api.request` | aus | beliebige Schreibmethode auf einem Endpunkt, der mit einem Eintrag aus `permissions.api_write_prefixes` beginnt |
| `pr.review` | aus | prüft Bot-Identität, offenen Nicht-Draft-PR und exakten Head; `POST …/pulls/{n}/reviews` mit `commit_id`/Review-Ereignis, danach unabhängiger Review-Readback; zusätzlich `publish_reviews` und eine konfigurierte aktivierte Organisation in `<runtime-root>/config/orgs.json` (`multi_bot.root`, Standard: aktuelles Verzeichnis); globale und organisationsbezogene `exclude_writes` werden durchgesetzt, eine fehlende oder ungültige Policy verweigert das Review |
| `pr.merge` | aus | liest den PR frisch (offen, exakter `sha`, Default-Base, kein Draft, `mergeable_state` clean, konfiguriertes Merge-Konto), `PUT …/pulls/{n}/merge` mit `sha`, liest `merged` zurück |
| `pr.ready` | aus | liest den Draft am exakten `sha` frisch, GraphQL `markPullRequestReadyForReview`, liest zurück |
| `actions.dispatch` | aus | `POST …/actions/workflows/{workflow}/dispatches` für einen aktiven Workflow |
| `actions.rerun` | aus | `POST …/actions/runs/{id}/rerun` für einen abgeschlossenen Lauf des exakten `sha`, nie aus Forks |
| `pr.create` | aus | `POST …/pulls` von einem Branch mit Bot-Präfix auf den Default-Branch |
| `git.push_branch` | aus | `git push origin <sha>:refs/heads/<branch>` ohne Force, nur Bot-Präfix (`typed_actions.push_branch_prefix`, Standard `bot/`), nie der Default-Branch, Prüfung per `ls-remote` |

Die sechs getypten Aktionen stehen in der Standard-Obergrenze, sind aber nie standardmäßig aktiv.
Jede braucht zusätzlich ihren `multi_bot`-Schalter (`merge_enabled`, `policy.draft_*`,
`policy.trigger_missing_ci`, `policy.open_fix_prs`); eine Berechtigung allein öffnet nichts.
Die sieben getypten Aktionen stehen in der Standard-Obergrenze, sind aber nie standardmäßig aktiv.
Jede braucht zusätzlich ihren `multi_bot`-Schalter (`merge_enabled`, `policy.publish_reviews`,
`policy.draft_*`, `policy.trigger_missing_ci`, `policy.open_fix_prs`); eine Berechtigung allein öffnet nichts.
Eine Aktion je Aufruf:

```bash
Expand Down Expand Up @@ -203,7 +204,7 @@ Historie aufgebaut. Es ist kein Fremdcode enthalten; siehe

## MULTI-BOT als optionale Agentenrolle

`python -m githubbot_core multi-bot` startet die paketierte Rolle über TASKPLAN. Das sichtbare Menü enthält **1 operator** (Standard), **2 bot-triage** (nur PR-Triage/Reviews) und **3 github-maintain** (Fixes und Pflege). Operator prüft vor jeder neuen Einheit frisch PRs, dann konkrete Fixes, dann Policies/Gates/Privacy und Care. Die 3a/3b-Heuristik bevorzugt anfangs Policies und wechselt nach belegten Abschlüssen; dringende Policies gehen vor normaler Care. Das Startcenter verwendet denselben CLI-Aufruf.
`python -m githubbot_core multi-bot` startet die paketierte Rolle über TASKPLAN. Das sichtbare Menü enthält **1 operator** (Standard), **2 bot-triage** (PR- und Issue-Triage, unabhängige PR-Reviews) und **3 github-maintain** (Fixes und Pflege). Operator bearbeitet frische PRs, dann Issues, dann konkrete Fixes, danach Policies/Gates/Privacy und Care. Ein Selector-Durchlauf wählt einen Kandidaten; der Agent setzt den angeforderten Umfang mit frischen Listen fort. Vorschau allein gilt nicht als Abschluss. Merges sind im neutralen Paketstandard aus und nur über `effective_enabled` plus alle exakten Review-/CI-/Identitäts-/Branchschutz-Gates möglich. Die 3a/3b-Heuristik bevorzugt anfangs Policies und wechselt nach belegten Abschlüssen; dringende Policies gehen vor normaler Care. Das Startcenter verwendet denselben CLI-Aufruf.
`--provider`, `--model`, `--effort` und `--mode` wählen ausdrücklich; die Provider-Ausführung
bleibt in TASKPLAN. Fehlt dieses optionale Modul, erscheint ein Installationshinweis und
kein Anbieter startet. `--dry-run` aktiviert TASKPLANs Trockenlauf ohne Sonde.
Expand Down Expand Up @@ -233,6 +234,6 @@ bleiben eigenständige, getrennte Konsumenten.

Die alten benannten Flags `triage`, `review-merge`, `aftercare` bleiben mit ihrem bisherigen begrenzten Umfang verfügbar, erscheinen aber nicht im neuen Dreiermenü. Eine Rollenwahl aktiviert keine Merges und erweitert keine Permission-Decke.

`githubbot-core --json multi-bot-select --input SNAPSHOT.json --mode operator` wählt deterministisch und ausschließlich lesend aus vorhandenen Kandidaten. Keine Queue, Auftragsanlage, Persistierung oder Agentenstarts. Der Snapshot enthält `candidates`, optional `processed` und `lastMaintenance`: Kandidaten brauchen `id`, exakte 40-stellige lowercase Commit-`revision`, `status` (`ready`, `blocked`, `done`), `category` (`prs`, `fixes`, `policies`, `care`) und optional `urgent` (bool). Ein `processed`-Eintrag bindet dieselben Felder an `blocked`/`done` und eine nichtleere `evidence`-Referenz; die tatsächliche Belegprüfung liegt beim Aufrufer. `lastMaintenance` ist ein `{id, revision}`-Verweis auf einen solchen erfolgreichen Policies-/Care-Abschluss. Auswahl und zwei leere Prüfungen verändern nichts. Unbekannte Werte werden abgewiesen. Neue PR-Heads kommen wieder vor Fixes/Pflege; erledigte oder blockierte gleiche Heads bleiben übersprungen, bis der zuständige Workflow neue Belege liefert. Gleichrangige Kandidaten werden nach ID und SHA sortiert.
`githubbot-core --json multi-bot-select --input SNAPSHOT.json --mode operator` wählt deterministisch und ausschließlich lesend aus vorhandenen Kandidaten. Keine Queue, Auftragsanlage, Persistierung oder Agentenstarts. Der Snapshot enthält `candidates`, optional `processed` und `lastMaintenance`: Kandidaten brauchen `id`, exakte 40-stellige lowercase Commit-`revision`, `status` (`ready`, `blocked`, `done`), `category` (`prs`, `issues`, `fixes`, `policies`, `care`) und optional `urgent` (bool). Operator priorisiert PRs, Issues und Fixes vor Pflege; `bot-triage` nimmt PRs und Issues, `github-maintain` Fixes und Pflege. Ein `processed`-Eintrag bindet dieselben Felder an `blocked`/`done` und eine nichtleere `evidence`-Referenz; die tatsächliche Belegprüfung liegt beim Aufrufer. `lastMaintenance` ist ein `{id, revision}`-Verweis auf einen solchen erfolgreichen Policies-/Care-Abschluss. Auswahl und zwei leere Prüfungen verändern nichts. Unbekannte Werte werden abgewiesen. Exakt erledigte/blockierte Heads bleiben übersprungen, bis neue Belege den Zustand ändern. Gleichrangige Kandidaten werden nach ID und SHA sortiert.

Der öffentliche ASCII-Windows-Starter trägt den Titel MULTI-BOT COMPANION, zeigt den Vordergrundbetrieb und wartet nach Erfolg, Fehler oder STOP auf eine Taste. Ausnahmen: explizites `--dry-run`, `TASKPLAN_STARTER_DRY_RUN=1` oder `MULTIBOT_NO_PAUSE=1`. Er installiert nichts und öffnet kein zusätzliches Fenster.
2 changes: 1 addition & 1 deletion src/githubbot_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
a plugin SPI and signed exact-SHA review receipts. Standard library only.
"""

__version__ = "0.2.1"
__version__ = "0.2.2"
Loading
Loading