Wie SupaCloud sich in ein spec-getriebenes Projekt einfügt
Ein spec-getriebenes Projekt hält sein Verhalten in versionierten Specs und seine Arbeit in
kleinen Verträgen, die sich an Spec-Klauseln binden. Menschen entscheiden vor der Arbeit, Gates
entscheiden danach, und ein Orchestrator treibt die Schleife dazwischen. SupaCloud soll dieser
Orchestrator sein. Diese Seite erklärt, wo es andockt, was jeder Integrationspunkt im Code auf
main heute tut und was noch zu bauen ist. Die Entscheidung dahinter ist
ADR 0075;
die Dateien stehen im Delivery-Spec-Format, die Work-Item-Seite
und die Labels im Spec-Bereitschaftsvertrag.
Die Schleife
Abschnitt betitelt „Die Schleife“Anforderungskatalog was das Produkt bieten muss │ eine Klausel zitiert, was sie erfülltDomänen-Spec (specs/<dom>/) wie es sich verhält: Klauseln, Parameter, Szenarien, Entscheidungen │ G1-Entscheidungen beantwortet ──► Status design-approvedWork Items (WI-*.yaml) welcher Ausschnitt als Nächstes kommt: spec_refs, decision_refs, verifies │ Bereitschaft ──► Tracker-Labels ready / blocked / spec-ready [1 Aufnahme]Agentenlauf nach Tier geroutet, auf einem freigegebenen Ausschnitt [2 Dispatch] │ eine Lücke ──► Rückfrage ──► Antwort ──► Entscheidung ──► Spec-Patch [3 Rückfrage, 4 Briefs]Pull Request + Evidence CI, Spec-Gate, Audit, unabhängiges Review │ jeder Pflicht-Check grün auf demselben Head-SHA ──► Merge [5 Merge]Spec-Vertrag validiert, nachverfolgt, angezeigt [6 Vertrag]Eine untere Ebene ändert nie still eine obere. Eine Lücke, die bei der Umsetzung auffällt, wird eine Rückfrage in der Spec, keine Annahme im Code, und die Antwort kommt als Entscheidung zurück, die wie jede andere Änderung gemergt wird.
1. Aufnahme und Bereitschaft
Abschnitt betitelt „1. Aufnahme und Bereitschaft“Was die Schleife braucht. Bereitschaft ist eine Tatsache, die aus dem Repository berechnet
wird: Abhängigkeiten geschlossen, referenzierte Entscheidungen freigegeben, referenzierte Specs
design-approved oder weiter. SupaCloud berechnet sie, schreibt als einziger Tracker-Schreiber
des Projekts die Labels ready, blocked, spec-ready und human-gate und dispatcht genau die
spec-ready-Items.
Heute. SupaCloud liest und schreibt keine Issue-Labels.
- Das Forgejo-Issue, das es deserialisiert, trägt
id,number,title,state,body,html_urlundcreated_at— keine Labels, keinen Meilenstein (server/crates/sc-forge/src/git/forgejo.rs:77-85);sc-forgehat überhaupt keinen Aufruf, der Labels liest oder schreibt. - Die Aufnahme ist ein Poll alle 300 Sekunden
(
server/crates/sc-svc-orchestration/src/backlog/mod.rs:27) über höchstens 100 offene Issues (server/crates/sc-forge/src/git/forgejo_issues.rs:30,56). - Die Bereitschaft kommt vom Klassifikator:
readywirdqueued,needs_infowirdneeds_info(server/crates/sc-svc-orchestration/src/backlog/classify.rs:5-6), mit dem LLM-Klassifikator als Standard. - Die Backlog-Lane wertet keinen Gate-Filter aus
(
server/crates/sc-svc-orchestration/src/auto_developer_lane_filters.rs:102-112).
Geplant (SC-2, mit SC-20). Labels, Meilenstein, Zuständige und Zustand bei jedem Scan und bei
Issue-Webhooks lesen; zum Dispatch-Zeitpunkt einen Label-Regelsatz auswerten (require_all,
forbid_any, …); ein Item zurückhalten, dessen Labels nicht passen, und es abbrechen, wenn sein
Issue geschlossen wird; ein Label das Profil und das Tier wählen lassen. Darüber hinaus macht die
Owner-Entscheidung vom 22.09.2026 SupaCloud zum einzigen Schreiber: Es leitet die Bereitschaft
selbst aus den Work-Item-Verträgen und Specs ab — die Referenzimplementierung ist bw-fm27
tools/workitems/sync.py (compute_ready, compute_spec_ready, load_spec_state) — und pflegt
die Labels über die bestehende Forge-Verbindung des Projekts (resolve_forge_for_project,
server/crates/sc-svc-projects/src/projects/credentials.rs:307, ist der Credential-Pfad, den der
Merge schon nutzt). Kein Bot-Account, kein CI-Secret.
2. Dispatch nach Fähigkeitsstufe
Abschnitt betitelt „2. Dispatch nach Fähigkeitsstufe“Was die Schleife braucht. Work Items und Routing nennen eine Fähigkeitsstufe (Tier), nie ein Modell. Der Kalibrator entscheidet anhand gemessener Belege, welches Modell hinter jedem Tier steht.
Heute. Die Tiers gibt es — flagship, balanced, fast, independent_review
(server/crates/sc-kernel/src/model_tier.rs:27-34), die Schreibweise independent-review wird
akzeptiert —, und der Kalibrator schreibt geordnete Tier-Ketten und wendet sie automatisch an
(ADR 0068; server/crates/sc-svc-orchestration/src/calibration/auto_apply.rs). Aber kein
Arbeitsstart kann „nimm Tier X” sagen: Die Modell-Policy eines Agent-Profils ist manual,
fixed oder auto (server/crates/sc-persistence/src/models/agent_profile.rs:28-32), und das
Tier eines Tasks wird aus seinem festgelegten Modell abgeleitet.
Geplant (SC-3). model_policy = tier für Profile und ein tier pro Pipeline-Stufe, beim
Start auf den ersten erreichbaren Eintrag der kalibrierten Kette aufgelöst; ein per Label
geroutetes Item trägt sein Tier; ein unerreichbares Tier stellt das Item zurück, statt still den
Runner-Standard zu nehmen. Das unabhängige zweite Review eines anderen Anbieters (SC-4) baut auf
dem Tier independent_review auf; heute hat die Pipeline genau einen Review-Slot
(server/crates/sc-svc-orchestration/src/auto_developer_pipeline.rs:100-110). Der Owner hat am
22.09.2026 entschieden, zusätzlich einen automatisierten Security-Reviewer einzuführen: eine
Kalibrator-Lane security_review mit eigenen Belegen und eigener Akzeptanz-Telemetrie und einen
Security-Slot in SC-4, der bei Security-Review-Gate-Klassen greift (neue Abhängigkeitsnamen,
CI-Workflows, Security-Werkzeuge, Secrets, Auth- und Vertrauensgrenzen-Code). Seine Freigabe gibt
diese Klassen frei; eine Änderungsanforderung eskaliert an den Owner. Der Build-Brief #1448 enthält das
als stehende Entscheidung 6 des Owners, mit dem Design in blueprints/SC-3.md,
blueprints/SC-4.md und blueprints/SC-16.md seines Pakets.
3. Das Question-Gate und das Rückschreiben in decisions.yaml
Abschnitt betitelt „3. Das Question-Gate und das Rückschreiben in decisions.yaml“Was die Schleife braucht. Ein Agent, der auf eine echte Lücke stößt, fragt, statt zu raten.
Das Item parkt, ohne einen Slot zu halten, der Owner antwortet auf irgendeiner Oberfläche, das
Item läuft mit der Antwort weiter, und die Antwort wird über einen Pull Request ein Eintrag in
decisions.yaml.
Heute. question.ask funktioniert: eine Frage von bis zu 4.096 Bytes mit bis zu 8 Optionen
(server/crates/sc-svc-exec/src/question_ask.rs:40,44), ein Warten von bis zu 600 Sekunden
(:36), beantwortet im Web-Eingang, auf der Telegram- oder Discord-Karte oder durch den
Koordinator, der den Task delegiert hat. Eine deferred-Frage kehrt sofort zurück und hält die
Antwort als dauerhafte Mailbox-Nachricht fest (server/crates/sc-svc-exec/src/mailbox/question.rs),
die eingereiht wird und nie einen beendeten Task wiederbelebt (ADR 0074 D6). Was für die Schleife
fehlt: Der Backlog hat keinen Wartezustand — seine sieben Zustände sind classified, queued,
in_progress, in_review, done, blocked und needs_info
(server/crates/sc-persistence/src/models/backlog.rs:93) —, eine geparkte Frage hält also ihren
Nebenläufigkeits-Slot; ein Question-Gate hat keine Frist (timeout_policy: Hold,
server/src/app_d1_tail_ports.rs:174); und nichts schreibt eine Antwort ins Issue oder ins
Repository.
Geplant (SC-10, mit SC-20 Anforderung 7). Ein Park-Modus, der das Item nach
awaiting_answer verschiebt, den Lauf nach einer Übergabenotiz beendet und den Slot freigibt; die
Antwort stellt das Item mit Frage, Antwort und Branch als Wiederaufnahme-Kontext wieder ein —
durch den normalen Gate-Stapel des Dispatchers, die Antwort selbst startet also weiterhin nichts.
Eine Frist pro Projekt mit einer Standardaktion. Hat das Projekt eine Spec-Quelle, erzeugt die
Antwort einen decisions:-Eintrag, der auf die Frage verweist, geliefert entweder im nächsten
Implement-Pull-Request des Items oder als eigener Koordinator-Pull-Request — nie direkt auf den
Standard-Branch gepusht.
4. Decision Briefs
Abschnitt betitelt „4. Decision Briefs“Was die Schleife braucht. Designentscheidungen werden gebündelt vor der Arbeit beantwortet:
ein Brief pro Domäne, jedes Element mit seinen Optionen, einer empfohlenen Option, der Begründung
und Entwürfen (Tabellen, Diagramme, Vorher-nachher-Screenshots, Prototypen). Die Empfehlung ist
der Bequemlichkeit halber vorausgewählt, aber eine vorausgewählte Option zählt erst als
Antwort, wenn der Owner sie bestätigt — pro Element oder mit „alle offenen Empfehlungen
übernehmen”. Die Übergabe wird verweigert, solange ein blockierendes Element offen ist. Antworten
werden per Pull Request in decisions.yaml geschrieben.
Heute. Nichts. question.ask ist der einzige strukturierte Eingabekanal für Menschen, eine
Frage nach der anderen. Der erste Spec-Pilot (bw-fm27, Clubfinanzen, 26 Entscheidungen) wurde
auf einer Fragebogenseite außerhalb von SupaCloud beantwortet und von Hand ins Repository
übertragen.
Geplant (SC-29 v2; sein Brief ist blueprints/SC-29.md im Paket von
Issue #1448).
Eine Brief-Seite mit Fortschritt, Zustand pro Element (open, as recommended, changed), elf
Elementtypen von single_choice bis visual_signoff, ein Katalog von Entwurfsarten, Erzeuger
(ein MCP-Werkzeug zum Veröffentlichen, Capture-Integration, automatische Briefs für einen
Spec-Pull-Request, der proposed-Entscheidungen hinzufügt) und Senken — repo_file für
decisions.yaml, issue, memory, run (geparkte Läufe freigeben) und webhook.
5. Der CI-bewusste Merge
Abschnitt betitelt „5. Der CI-bewusste Merge“Was die Schleife braucht. Nichts wird gemergt, bevor nicht jeder Pflicht-Check des
Ziel-Repositorys auf demselben Head-SHA grün ist — die CI des Projekts, sein Spec-Gate und der
Status gate-class, den nur eine Owner-Freigabe grün macht — plus das Audit und die
erforderlichen Review-Slots.
Heute. „Grün” heißt, dass der Task des unabhängigen Auditors fertig ist und das visuelle Gate
bestanden oder übersprungen wurde: approve_and_complete dokumentiert gates_green als genau
dieses Urteil und berechnet es nie neu
(server/crates/sc-svc-orchestration/src/backlog/complete.rs:202-213). Kein Commit-Status wird je
gelesen — server/crates/sc-forge/src/git/ci.rs ist ein Platzhalter. Unter full_auto hat die
Merge-Entscheidung keinen Rückfall für sensible Pfade (complete.rs:161), und bei Autonomiestufe
100 ist die Merge-Obergrenze full_auto
(server/crates/sc-svc-tenancy/src/autonomy/policy.rs:180-181), also entscheidet die eigene
Merge-Policy des Projekts. Der Merge selbst ist ein Merge-Commit
(server/crates/sc-forge/src/git/forgejo_pulls.rs:174); ein Repository, das nur Squash-Merges
erlaubt, lehnt ihn ab, und ein geschützter Branch mit Pflicht-Checks lehnt einen Merge ab, dessen
Checks nicht grün sind — in beiden Fällen bleibt das Item im Review, und nichts versucht es erneut.
Geplant (SC-1, mit SC-24 für den Merge-Stil). Pflicht-Status aus dem Branch-Schutz oder einer
Projekt-Überschreibung sind eine zwingende Gate-Eingabe für jede Merge-Policy und jede
Autonomiestufe; ein Merge-Gate-Ledger mit dem Schlüssel Item, Runde, Gate, Slot und Head-SHA; ein
Watch-Tick, der bei Grün mergt und einen roten Check mit dem fehlschlagenden Kontext an den
Umsetzer zurückgibt; menschliche Kontexte wie gate-class, die den Owner einmal benachrichtigen
und ohne Frist warten — ein ausstehender Gate-Status heißt Warten auf Freigabe, nie ein CI-Fehler
zum Nacharbeiten (SC-5); der Merge auf den auditierten SHA festgelegt; klassifizierte
Wiederholungen.
6. Der Spec-Vertrag
Abschnitt betitelt „6. Der Spec-Vertrag“Was die Schleife braucht. Das Spec-Format ist ein Produktvertrag: ausgeliefert, versioniert und drift-geschützt wie die anderen Verträge von SupaCloud, serverseitig als zweite Prüfung validiert, von der Anforderung bis zur Evidence nachverfolgt und in der Web-Oberfläche lesbar.
Heute. spec.get liefert genau vier Plattformverträge — openapi_public,
workflow_schema, mcp_catalog und command_catalog
(server/crates/sc-svc-mcp/src/mcp/spec_corpus.rs:24-29). Es gibt keinen Code für Anforderungen
oder EARS. Das Crate sc-spec ist die Workflow-Spec (der WorkflowSpec-DTO-Baum), ein Crate
für Anforderungs-Specs braucht also einen anderen Namen.
Geplant (SC-20). Das Format der Referenzimplementierung unverändert als
Delivery-Spec-Format übernehmen — Version 0.2, deren
Projektprofil es erst möglich macht, dass ein ausgelieferter Vertrag zu Projekten mit
unterschiedlichen Katalogen, ID-Formen und Einheiten passt; es über spec.get
veröffentlichen, generiert und in einem Drift-Test byteweise verglichen; ein Blatt-Crate
sc-reqspec mit dem typisierten Format und seinen Strukturprüfungen; spec_sources, ein
spec-Gate (off, advisory, required) und ein decision_mode pro Projekt; ein
Traceability-Bericht von der Anforderung bis zur Evidence; Drift-Markierung abhängiger Items,
wenn eine gemergte Änderung eine Klausel bearbeitet; eine nur lesende Spec-Ansicht. Ein
OpenSpec-Import/-Export-Adapter folgt später; keine Laufzeit hängt von OpenSpec-Werkzeugen ab.
Was im Repository bleibt
Abschnitt betitelt „Was im Repository bleibt“Manche Regeln hängen bewusst nicht von SupaCloud ab:
- Die Gate-Klassen werden durch einen Pflicht-Status im Repository des Projekts durchgesetzt,
weil der Autonomieregler die Merge-Obergrenze von SupaCloud auf
full_autoheben kann. Die Merge-Policy von SupaCloud darf nur einschränken, was dieser Status erlaubt. In der Referenzimplementierung ist das gebaut und in Betrieb (gate-class, WI-SPEC-007, gemergt am 22.09.2026); der Abschnitt darunter beschreibt es, wie es läuft. - Das Spec-Gate und die Work-Item-Gates laufen in der eigenen CI des Projekts. Das
spec-Gate von SupaCloud ist eine zweite Prüfung, kein Ersatz. - Die Verträge und Specs sind die Quelle der Bereitschaftsregel. SupaCloud liest sie; es hält keine zweite Kopie des Arbeitsstands.
Der Status gate-class, wie er in der Referenzimplementierung läuft
Abschnitt betitelt „Der Status gate-class, wie er in der Referenzimplementierung läuft“Die Regeln liegen in einer Datendatei (tools/qa/gate_classes.yaml, selbst Klasse G2) und einem
Prüfer (tools/qa/check_gate_classes.py), Pfad für Pfad dokumentiert auf der Gate-Klassen-Seite des
Repositorys. Jede Klasse nennt ihren Freigebenden: owner für G1 Spieldesign, G2 Architektur
und Verträge, G3 Art Direction und ersten Eindruck, G4 sensible Themen und G5 Release und Recht;
security_review für S1 neue Abhängigkeiten, S2 CI-Workflows und S3 Security-Werkzeuge,
Policies und Gate-Konfiguration.
Was er setzt. Einen Commit-Status mit dem Kontext gate-class auf dem Head-Commit des Pull
Requests: success, wenn keine Klasse greift oder jede greifende Klasse für genau diesen
Head-Commit freigegeben ist (die Beschreibung nennt, wer welche Klasse freigegeben hat), pending,
wenn eine Klasse wartet — mit jeder Klasse, ihrem ersten Pfad oder ihren neuen Paketnamen und dem,
auf den gewartet wird —, und error, wenn kein ehrliches Urteil möglich war, was wie pending
blockiert. Es ist ein erforderlicher Status auf dem main der Referenzimplementierung, neben
ihren drei core-ci-Kontexten (core-ci / python (pull_request), core-ci / format (pull_request),
core-ci / dotnet (pull_request)); ein
wartender Pull Request kann also weder von einer autonomen Schleife noch über die API von einem
Konto ohne Adminrechte gemergt werden.
Wann er läuft. pull_request_target (opened, synchronize, reopened, edited), also bei jedem
neuen Head und jedem Umhängen; pull_request_review (submitted, edited); und issue_comment
(created, edited, deleted) an einem Pull Request, aber nur, wenn der Kommentar ein
/approve-gates-Befehl ist oder war. Andere Kommentare starten nichts. Klassenkarte und Prüfer
kommen immer vom Basis-Branch — bei einem Kommentar vom Default-Branch —, ein Pull Request kann
die Regeln, nach denen er beurteilt wird, also nicht lockern; der Head wird nur als Daten geholt.
Wie eine Klasse freigegeben wird.
- Eine Owner-Klasse wird durch ein zustimmendes Review des Head-Commits durch das Owner-Konto
freigegeben oder durch den Pull-Request-Kommentar
/approve-gates <sha>des Owners, der genau diesen Head-Commit nennt (vollständige SHA oder ein Prefix aus mindestens 12 Hex-Zeichen; die wartende Beschreibung nennt das zu verwendende Prefix). - Ein bearbeiteter Kommentar zählt nicht, was auch immer danach darin steht — jedes Konto mit Schreibrecht kann jeden Kommentar bearbeiten, ein bearbeiteter Text lässt sich also nicht als der des Owners belegen. Stattdessen einen neuen Kommentar schreiben. Einen Kommentar zu bearbeiten oder zu löschen bewertet den Pull Request neu und zieht damit eine Freigabe zurück, die nicht mehr da ist.
- Eine Security-Review-Klasse wird durch ein zustimmendes Review des Head-Commits von einer gelisteten Reviewer-Identität — der automatisierten Security-Review-Bahn — oder durch den Owner freigegeben, der immer freigeben kann. Ein Änderungswunsch dieses Reviewers eskaliert jede Security-Review-Klasse des Pull Requests an den Owner, der sie dann allein freigibt.
- Eine Freigabe gilt nur für den Commit, den sie nennt. Ein neuer Push wird von vorn klassifiziert, verworfene und als veraltet markierte Reviews zählen nicht, und ein späterer Änderungswunsch des Owners hält jede Klasse wieder — auch die, die ein Reviewer freigegeben hatte.
Zwei ehrliche Grenzen. Forgejo lehnt die Freigabe durch den Autor eines Pull Requests ab; genau
deshalb gibt der Owner eigene Pull Requests per Kommentar frei und nicht per Review — der
Kommentarweg ist ein Ausweg um eine Forge-Regel herum, kein zusätzliches Privileg. Und ein
Instanz-Admin kann weiterhin am Branch-Schutz vorbei force-mergen, was die Regel auch sagt; das
ist die Notausstiegsluke des Owners und ein Grund, Instanz-Admin-Zugänge von Agenten fernzuhalten.
Im selben Sinn: Jedes Konto und jeder Workflow mit Schreibrecht kann einen Commit-Status mit
beliebigem Kontext setzen. Das Gate hält den autonomen Merge-Weg zuverlässig auf — es ist keine
Verteidigung gegen einen Schreiber, der gate-class absichtlich fälscht.