- git-deploy.md Abschnitt G: Rotieren, Sichern, Umschreiben, Prüfen,
Hash-Zuordnung, Push, Server, Forgejo/NAS, lokales Aufräumen
- Protokoll: Speicherbereinigung in Forgejo und auf dem NAS erledigt,
keine weiteren Klone, Live-Schlüssel bereits rotiert
- Agenten-Regel: keine personenbezogenen Daten oder Schlüssel ins Repository
- Roadmap: 1.1 und 1.2 erledigt, Context7 und lokales MySQL-Root unter 1.3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Zuordnung alter zu neuen Commit-Hashes in dev/archive/commit-map-2026-10-09.txt
- Git-Deploy-Protokoll: Eintrag und einmaliger Server-Abgleich (Tags mit
--force holen, gc), Speicherbereinigung in Forgejo und auf dem NAS
- README und Roadmap 1.1/1.4 nachgeführt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- dev/roadmap.md neu: alle offenen Punkte aus Plänen, Audits und Protokollen,
gegen Code und Git abgeglichen (Stand v1.7.0)
- Abgeschlossenes ins Archiv: 2026-09-01 → archive/2026-09-nutzergewinnung,
2026-09-11-audit → archive/2026-09-audit, lagacy-rechnungen →
archive/legacy-rechnungen, Deploy-Protokoll v1.1.0, Umami-Snippets,
Go-Live-Roadmap vom 20.07.
- Aktiv bleiben eigene Ordner bildrechte/ (Plan Fassung 2, Decision-Update)
und changelog/ (Decision-Update Changelog)
- dev/README.md als Ordnerkarte neu, Verweise und zwei Code-Kommentare auf
die neuen Pfade
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auf Live meldete memberships:resync-auto nach v1.4.0 „vorher 19607, nachher 9":
syncMembershipsForEmail() entzog Konten ohne email_verified_at alle
automatischen Rechte, und 19.597 davon gehören Bestandskonten aus dem
Altsystem. Jetzt wird nur entzogen, was keine E-Mail-Grundlage mehr hat —
unabhängig vom Kontostatus (S-03 bleibt wirksam); neue Rechte weiterhin nur
für aktive, verifizierte Konten (F01).
memberships:resync-auto läuft in einer Transaktion, kennt --dry-run und rollt
zurück, wenn mehr als 5 % (mindestens 50) der Rechte wegfallen würden
(--force zum Erzwingen). Probelauf gegen die Live-Kopie: 19.607 → 19.316.
Wiederherstellung: storage/app/private/restore-company-user-auto-2026-10-07.sql
(nicht versioniert, INSERT IGNORE, idempotent).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Audit: dev/sicherheit/SICHERHEITSAUDIT-2026-10-07.md, Plan und Entscheidungen:
dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md.
- S-01 Legacy-Rechnungen fremder Kunden nur mit billing:manage (auch Kundenroute).
- S-02 Kontaktzuordnung auf der Firmenanzeige verlangt companies:write, $id gesperrt.
- S-03 CompanyMembershipObserver: automatische Firmenrechte werden bei jeder
Adress-/Zuordnungsänderung sofort neu bewertet; memberships:resync-auto.
- S-04 Passwortwechsel beendet alle anderen Sessions (PasswordChanger), Reset
alle Sessions und offene Login-Links; Fortify PUT /user/password abgeschaltet.
API-Tokens bleiben bestehen.
- S-05 Google: email_verified Pflicht, feste Bindung über die Provider-ID;
Erstverknüpfung bestehender Konten außerhalb gmail/hd nur per Bestätigungslink
in derselben Browser-Session.
- S-06 Frischer Identitätsnachweis (Passwort, App-Code, E-Mail-Code oder
Passkey) vor E-Mail-Wechsel, erster 2FA-Einrichtung und Token-Erzeugung;
Hinweis-Mails an die (bisherige) Kontoadresse.
- Entscheidung 5: Passkeys (Fortify, @laravel/passkeys) für alle; Super-Admins
und Admins bestätigen die Session für den Admin-Bereich per Passkey oder
App-Code (EnsureStrongAdminAuthentication, Notfallschalter
AUTH_REQUIRE_STRONG_ADMIN); Reset des zweiten Faktors durch Super-Admins.
Neue Migration: create_passkeys_table. Suite 2.403 grün (1 übersprungen),
Larastan ohne Meldung.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Am 07.10.2026 hat das RefreshDatabase eines frischen Demo-Projekts (Test der
Vorlagen aus dev/git-deploy-monitoring) die lokale Datenbank `pressekonto` auf
global-mysql vollständig geleert (Binärlog binlog.000009, Pos. 566161486).
Ursache: docker-compose.yml setzte DB_* als Container-Umgebungsvariablen, die
in Laravel Vorrang vor jeder .env haben; die phpunit.xml des Demo-Projekts
erzwang kein SQLite. Die eigene Suite war nicht beteiligt (force="true" und
Guard in tests/TestCase.php greifen; Gegenprobe mit MySQL-Variablen grün).
- docker-compose.yml: DB_* entfernt (Werte identisch in .env), wirksam nach
Neuerstellen des Containers.
- Baukasten: „Testdatenbank absichern" (phpunit.xml mit force, Guard,
Gegenprobe) als Pflicht vor RefreshDatabase.
- .ai/rules/general.md und CLAUDE.md: fremde/frische Laravel-Projekte nur mit
SQLite :memory: testen; migrate hier erst nach migrate:status.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vorlagen in einem frischen Laravel 12 eingebaut (30 Tests grün), deploy.sh
gegen ein simuliertes Repository durchgespielt (Deploy, Abbruch bei
Migrationen, Drift, Rollback, fehlender Worker). GlitchTip-Aufbewahrung heißt
seit Version 6 GLITCHTIP_RETENTION_DAYS — in der Projekt-Doku korrigiert.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Anlass 06.10.2026: Nach dem Deploy von v1.3.0 hat queue:restart den Worker
beendet, Supervisor lief nicht, über eine Stunde blieben KI-Prüfungen und
Mails liegen, ohne dass es auffiel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- deploy.sh: bricht ohne Änderung ab bei Abweichung im Checkout oder neuen
Migrationen ohne --migrations; down, Checkout, RELEASE, Composer, Caches,
queue:restart, FPM, up; Rollback = derselbe Aufruf mit dem vorherigen Tag
- git-deploy.md: Forgejo-Zugang, Umwandlung von ~/pressekonto.com in einen
Checkout von v1.1.0 ohne Dateiänderung, Release lokal, Prüfungen, Rollback
- Assets werden lokal gebaut und committet, auf dem Server kein Node
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Die Dateien bleiben in der Historie und im Vault; git rm --cached, nichts
auf der Platte gelöscht.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- UMSETZUNGSAUDIT-2026-09-29.md (Bestandsaufnahme) und -2026-10-02.md
- ENTWICKLUNGSPLAN.md: Block 9 und 10, Entscheidungen E19–E34 vom Betreiber
am 02.10.2026 bestätigt (E25 revidiert), Deploy-Plan A–E, Protokoll
- deploy-runbook.md: vollständige Scheduler-Tabelle, Restore-Schritte mit
--accept-unsigned/--without-export, Zugangsdaten aus Abschnitt 7 entfernt
(stehen weiter in der Historie — Passwort wird rotiert)
- Bildplan-Protokoll mit Korrektur zu „Altbestand geschützt" (A-05)
- dev/README.md und dev/roadmap.md verweisen auf den aktuellen Stand
- .env.example: neue Schlüssel aus Block 9/10
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bilder (N01, N05, N07, N08): gemeinsamer Freigabezustand
PressReleaseImage::isPubliclyDeliverable() für Seiten, OG und Medienroute
(Bestand bleibt sichtbar, v2 nur mit Bestätigung, Admin-Upload bis zum
Kundenklick nicht öffentlich); eigene Ability confirmImageRights nur für den
Kontoinhaber, ohne Super-Admin-Kurzschluss, Identität und ausstehende
Bestätigung auch im Service; Status-Regel unter der PM-Sperre; Cache-Flush
nach dem Commit außerhalb der Dateibereinigung; Snapshot nach Bestätigung an
veröffentlichter PM; Bestätigungstexte an die gezeigte Kennung gebunden.
Beweisarchiv (N02, N10, N11, N12, N13, 5.1): Tombstone unter Zeilensperre mit
erneuter Hold-/Fristprüfung; Dateioperationen ausgewertet, Commands mit
FAILURE; record() über .tmp + move; Marker archive_pending_at mit
archive:retry-pending und archive:sweep-orphans; Anonymisierung entfernt Bilder
über den Remover mit Antragsbezug; Draft-Purge räumt Medien nie
veröffentlichter abgelehnter Einreichungen; App-Kopien fallen mit dem
Archiv-Tombstone; label_corrected nur für veröffentlichte Bilder;
archive_entries.legal_request_id; FileDeletion-Helfer; Systemstatus-Checks.
KI und Hintergrund (N03, N04, N14, N20, N21): Ergebnis-UPDATE und Audit in
einer Transaktion; erwarteter Hash bis in reject()/holdForManualReview();
Ablaufmail per beanspruchtem Marker in einer Transaktion; strikte
Schemaprüfung der Vision-Antwort; Fortschrittsmarke ungecacht.
Berichte und Canonical (N15–N19, 5.2): lückenlose Alterskohorten;
Feed-Identität mit Portal und Sprache; Sitemap-Rolle in der Kundenansicht;
Indexverteilung auf einer Grundgesamtheit; Kopien nach Wegfall der
Erstquelle neu bewertet; Kategorie-Admin leert Seiten-Caches; Dry-Run
zählt alle Tabellen.
Gesamtsuite: 2.122 Tests grün, einer übersprungen; Larastan und Pint sauber.
Zwei Migrationen (nullable Spalten, INSTANT). N09 offen.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Tests\TestCase prüft die Standardverbindung in setUpTraits(), also vor
RefreshDatabase — bisher erst nach dem Refresh (N22). Eigener Test.
- phpunit.xml pinnt IMAGE_RIGHTS_V2, IMAGE_PRECHECK(_STAGE) und
LEGAL_ACCEPTANCE_GATE auf die Vorgaben aus .env.example; die Suite hing
sonst an der lokalen .env (Audit Abschnitt 6).
- Zustimmungsgate: die Livewire-Komponenten tragen die beim Rendern gezeigten
Fassungen (Trait-Hook rendering); weicht die aktuelle Fassung beim Absenden
ab, wird die Annahme abgelehnt und der neue Wortlaut gezeigt. Ein fehlendes
Pflichtdokument ist bei aktivem Gate ein Konfigurationsfehler (N06).
- Audit vom 25.09., Decision-Update vom 22.09. und Plan Fassung 2 versioniert;
die Antwortkopie „…-211.md" entfernt; U10-Formulierung im Plan präzisiert.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- StorePressReleaseImageRequest: copyright, rights_confirmed, confirm_text_version Pflicht; 422 mit aktueller Kennung; 16 MiB
- PressReleaseImageController über den gemeinsamen Uploader, Löschen über den Remover; Resource mit Portalkennzeichnung, Kundenangabe, Herkunft, Bestätigung und warnings[]
- POST /service/pressreleases/{id}/images antwortet 410 mit Hinweis auf v1 (E-B4)
- API-Seite und Sprachdateien: Felder und Rechtehinweis mit aktiver Textkennung; Paritätsdokument ergänzt
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
view-distribution rechnete das Alter der Kohorten ab dem Enddatum des
Fensters, die Zähler stehen aber immer auf heute — mit einem --to in der
Vergangenheit waren alle Kohorten um die Verzögerung des Laufs zu jung.
Das Alter zählt jetzt ab dem Stichtag der Erhebung (Feld stichtag), junge
Kohorten fallen bei altem Enddatum leer aus.
settle-unpaid meldete beim zweiten Lauf einen Posten, dessen Quelle der
erste Lauf schon per MAN-Rechnung ersetzt hatte (superseded), als
Konflikt. Solche Quellen zählen jetzt als already_reissued.
Basiswerte Block 0: Live-Erhebung vom 21.09.2026 (gleiches Fenster,
Median 126/303 statt 98/200) eingetragen, Kohortenzeile mit Alters-
Versatz erklärt, letzter Schritt für 0.1 benannt (Lauf ohne --to).
Protokoll: Nach-Deploy-Schritte, Lesart von Audit und Rechnungslauf.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Der Nachlauf über den Bestand änderte rel=canonical und die Sitemap-Auswahl,
ließ aber gecachte Meldungsseiten (1 h stale) und Sitemap-Caches (1 h)
stehen. Nach einem Lauf mit Änderungen wird WebCaches::forgetPublicPages()
aufgerufen; der Test prüft das über den vorher gecachten Sitemap-Stand.
Protokoll Teil 11: Nachtrag Live-Deploy (hash-content 179.619,
duplicates-report 9.221 Paare / 1.468 seit 07/2026, assign-canonicals
9.223/9.221, basiswert-0.1.json auf dem Server), Anhang 2 1c.7/1c.8 mit
Live-Zahlen, Basiswerte 0.1 mit Hinweis auf die noch zu holende Datei.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Aufrufe/Teilen je Meldung, Abrufe durch Such-, KI- und Feed-Dienste,
Konversionsschritte: Umfang ohne IP, Zweck, Art. 6 Abs. 1 lit. f, Löschung
nach 395 Tagen in Abschnitt 13. Text vom Betreiber abgenommen (21.09.2026);
gilt für Hub und beide Portale. 0.7 in Roadmap und Protokoll abgehakt.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- feed_fetches: jeder Feed-Abruf mit Art, Schlüssel, Portal, Sprache,
erkanntem Reader (config/feeds.php, FeedReaderIdentifier), vom Dienst
gemeldeter Abonnentenzahl und gekürztem User-Agent — keine IP. Schreiben
per defer() nach der Antwort, auch bei Cache-Treffer.
- Aufbewahrung 395 Tage über press-releases:purge-events;
FEED_FETCHES_RECORDED_SINCE.
- Admin ▸ Reports ▸ Indexierung & Abrufe: Block „Abrufe der RSS-Feeds"
(Summen je Feed-Art, je Reader-Dienst, meistabgerufene Feeds;
FeedFetchReport, Verdichtung in PHP für MySQL und SQLite).
- Panel „Auslieferung": Abrufe je Feed in 30 Tagen; RSS-Seite nennt die
Zählung ohne IP.
- Tests: FeedFetchLogTest (5), IndexStatusCheckTest erweitert.
- dev/2026-09-01: Nachtrag Protokoll Teil 11, Roadmap 3.1; 0.7 gilt auch
für Crawler- und Feed-Log.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>