Commit Graph

153 Commits

Author SHA1 Message Date
gitea a802b90617 conjurer: pin the model Ollama actually has, and raise the AI timeout
Probing the real server (192.168.1.72:11434) after it was opened to the LAN:
/v1/models returns exactly one model, gemma4:e2b. Without pinning it the
bot would request the built-in default llama3.1:8b and every reply would
fail with "model not found", so set it explicitly on both bots.

Also raise CONJURER_AI_TIMEOUT_SECONDS to 240. Self-hosted generation is far
slower than a hosted API, particularly the first request after the model is
evicted from VRAM. It applies to every backend, so it is deliberately not
set higher than needed.

Caveat recorded honestly: at the time of writing, generation on that server
does not complete. /v1/models answers instantly, but both /v1/chat/
completions (180s) and native /api/generate with num_predict=5 (60s) return
nothing, and /api/ps shows no model ever becomes resident - so the model
never finishes loading. Ollama is 0.32.14 and gemma4:e2b is 5.1B Q4_K_M
(~3.5GB) despite the "e2b" name. That is a server-side problem, not a
configuration one; these values are correct and take effect once it loads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-24 14:54:32 +02:00
gitea aeb9bb5940 conjurer: point both bots at the Ollama server (192.168.1.72:11434)
Wires CONJURER_OLLAMA_URL into the test bot and the deploy bot so the
self-hosted backend from conjurer#25 is selectable. No API key exists for
Ollama - the endpoint is the whole configuration - and until it is set the
backend refuses to be selected, so this is what turns it on.

NOTE, verified from the LAN before committing: 192.168.1.72 answers ping
(0.4ms) but only port 22 is open - 11434 refuses. Ollama binds to
127.0.0.1:11434 by default, so it is not reachable off-host yet. This env
var is correct but inert until the server listens on the network:

  sudo systemctl edit ollama.service
    [Service]
    Environment="OLLAMA_HOST=0.0.0.0:11434"
  sudo systemctl daemon-reload && sudo systemctl restart ollama

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-24 14:43:01 +02:00
argocd-image-updater f968eb0340 build: automatic update of astrololo
updates image gitea/astrololo-data tag '71bb3b9c' to 'f0d07ee8'
updates image gitea/astrololo-logic tag '71bb3b9c' to 'f0d07ee8'
updates image gitea/astrololo-presentation tag '71bb3b9c' to 'f0d07ee8'
2026-08-21 10:49:32 +00:00
gitea f754831f54 feat(prezentacja): klucz podpisu sesji (LOG-34)
SESSION_SECRET w sekrecie astrololo-auth. Pod bez niego CELOWO nie wstaje:
usługa z kontami, ale bez klucza, nie odróżniłaby ważnej sesji od podrobionej.

W README dopisana rotacja klucza jako awaryjny wyłącznik — podmiana unieważnia
wszystkie sesje naraz, co jest właściwą reakcją na podejrzenie przechwycenia
cudzej sesji.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 10:47:46 +00:00
gitea ff0a1c8256 docs(węzły): klient NFS jako jawny wymóg wdrożenia
Pody przestały wstawać z komunikatem „bad option ... you might need
a /sbin/mount.<type> helper program". To NIE jest problem z udziałem ani
z uprawnieniami — serwer w ogóle nie został zapytany; jądro nie znalazło programu
pomocniczego, bo na węźle brakowało nfs-common.

Wymogu klienta NFS nie było w żadnym runbooku, choć wszystkie trzy warstwy
montują udziały z NAS-a. Luka była uśpiona: wszystko stało na jednym węźle, który
klienta miał, więc braku na pozostałych nie było jak zauważyć. Ujawniło się
dopiero, gdy zejście do zera replik — przy zupełnie innej naprawie —
przeplanowało pody gdzie indziej.

Dopisana tabela odróżniająca trzy komunikaty, które łatwo pomylić, bo wszystkie
kończą się niewstającym podem: brak klienta na węźle, odmowa serwera i brak praw
do zapisu. Każdy ma inną przyczynę i inne miejsce naprawy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 12:40:24 +02:00
argocd-image-updater ffeb639d62 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'ee3c515d' to '71bb3b9c'
updates image gitea/astrololo-logic tag 'ee3c515d' to '71bb3b9c'
updates image gitea/astrololo-presentation tag 'ee3c515d' to '71bb3b9c'
2026-08-20 23:56:37 +00:00
argocd-image-updater 3ea509b13a build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'c2e6b8e6' to 'd0c7ab61'
updates image gitea/conjurer-bot tag 'c2e6b8e6' to 'd0c7ab61'
2026-08-12 15:46:05 +00:00
argocd-image-updater 70f4d298ff build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'ae1bd677' to 'c2e6b8e6'
updates image gitea/conjurer-bot tag 'fbd1ec9f' to 'c2e6b8e6'
2026-08-12 15:16:03 +00:00
argocd-image-updater 7dd32b1fd4 build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'ae1bd677' to 'c2e6b8e6'
2026-08-12 15:14:02 +00:00
argocd-image-updater 1f9ea03ca6 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'ac8a0e9f' to 'ee3c515d'
updates image gitea/astrololo-logic tag 'e2b50b28' to 'ee3c515d'
updates image gitea/astrololo-presentation tag 'e2b50b28' to 'ee3c515d'
2026-08-11 14:38:44 +00:00
argocd-image-updater 466d3cb8e7 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'b838cf47' to 'ac8a0e9f'
2026-08-11 13:40:38 +00:00
argocd-image-updater bd0948f7a5 build: automatic update of astrololo
updates image gitea/astrololo-data tag '003deb94' to 'b838cf47'
updates image gitea/astrololo-logic tag '003deb94' to 'e2b50b28'
updates image gitea/astrololo-presentation tag '003deb94' to 'e2b50b28'
2026-08-11 09:18:11 +00:00
argocd-image-updater ba6e3bc9ee build: automatic update of astrololo
updates image gitea/astrololo-data tag 'baf4e0e3' to '003deb94'
updates image gitea/astrololo-logic tag 'baf4e0e3' to '003deb94'
updates image gitea/astrololo-presentation tag 'a8339659' to '003deb94'
2026-08-09 15:54:27 +00:00
argocd-image-updater 02ab25e39e build: automatic update of astrololo
updates image gitea/astrololo-data tag 'baf4e0e3' to '003deb94'
updates image gitea/astrololo-logic tag 'baf4e0e3' to '003deb94'
2026-08-09 15:51:02 +00:00
gitea 94f059d090 docs(pliki): runbook otwarcia udziału z bazami na zapis (zgubiony przy merge'u)
Treść powstała jako commit na gałęzi feat/pliki-zapis JUŻ PO zmergowaniu jej
PR-a, więc nigdy nie trafiła na master — został tam wyłącznie manifest.
Sam manifest jest w porządku (readOnly zdjęte), brakowało tylko opisu, co z tym
zrobić po stronie NAS-a.

Runbook zawiera: komendy midclt otwierające udział z bazami na zapis, sprawdzenie
przez exportfs (bo konfiguracja udziału i stan eksportu to dwie różne rzeczy),
ostrzeżenie, że przeładowanie musi iść przez zero replik zamiast rollout restart,
oraz listę kontrolną po wdrożeniu — z wyszukiwaniem jako punktem NAJWAŻNIEJSZYM,
bo to jedyne miejsce, w którym ta zmiana mogłaby przejść niezauważona.

Osobno wyliczone, co świadomie tracimy: DAN-25 dawał gwarancję, że baz nie da się
zmienić przez NFS, i tych dwóch rzeczy nie da się mieć naraz.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 12:22:49 +02:00
gitea 99b9a0426f feat(astrololo): Postgres jako lustro baz w SQL + runbook (DAN-28)
Manifest, wpięcie w kustomization i runbook krok po kroku.

DECYZJE ZAPISANE W MANIFEŚCIE, ŻEBY NIE TRZEBA ICH BYŁO ODTWARZAĆ Z GŁOWY:

local-path, NIE NFS. Postgres zakłada semantykę blokad i fsync, której NFS nie
gwarantuje — to klasyczne źródło uszkodzenia bazy przy nagłym restarcie. Ceną
jest przywiązanie do węzła; przy luście odtwarzalnym z Excela to akceptowalne.

strategy: Recreate. Wolumen jest ReadWriteOnce, a dwa procesy Postgresa na jednym
katalogu danych to uszkodzona baza — rolling próbowałby wstać z nowym podem,
zanim stary zejdzie.

PGDATA w PODKATALOGU wolumenu: katalog główny potrafi zawierać wpisy systemu
plików, a initdb odmawia pracy w niepustym katalogu.

Wersja PRZYPIĘTA i poza image-updaterem: podbicie majora wymaga migracji katalogu
danych, więc nie może się zdarzyć samo, w nocy, przy okazji builda aplikacji.

C.UTF-8 zamiast pl_PL.UTF-8: dopasowanie tekstu robimy przez unaccent i pg_trgm,
nie przez collation, a pl_PL wymagałby obrazu z wygenerowanymi lokalizacjami.

DATA_PROVIDER zostaje na `excel`. Postgres można wdrożyć i obejrzeć BEZ ryzyka
dla działającego wyszukiwania; przełączenie to osobna, późniejsza decyzja.

SPRAWDZONE PRZED ODDANIEM: `kubectl kustomize astrololo` składa komplet 21
zasobów bez błędu, YAML parsuje się poprawnie, audyt odwołań potwierdza, że
jedynym brakującym sekretem jest astrololo-postgres (oba klucze), a DSN
postgresql+psycopg:// jest rozpoznawany przez SQLAlchemy z psycopg 3.

NIE SPRAWDZONE: skrypt inicjalizujący nie biegł przeciwko prawdziwemu Postgresowi
— na maszynie, na której to powstawało, nie ma Dockera. Zapisane wprost
w runbooku; krok 4 jest tam prawdziwym testem.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 12:06:10 +02:00
gitea 9d44c8f93a feat(dane): udział z bazami zapisywalny — ekran zarządzania plikami (DAN-27)
Ekran „Pliki" pozwala wgrywać bazy, archiwizować je i (dla administratora)
kasować, a stan użycia jest klikany, więc musi przetrwać restart poda. Warstwa
danych musi zatem móc pisać na udziale — dotąd był montowany read-only.

ŚWIADOMY KOSZT: znika jedna warstwa obrony w głąb. Przejęcie warstwy danych
pozwala teraz nie tylko odczytać bazy, ale i je zmienić. Zostaje reszta: token
międzywarstwowy, szyfrowane łącze, ograniczenie eksportu NFS do konkretnych
hostów (DAN-25) oraz to, że kasować może wyłącznie konto administracyjne (PRE-27).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 09:46:28 +00:00
argocd-image-updater 0fa09c8fe6 build: automatic update of astrololo
updates image gitea/astrololo-render tag 'aec3f843' to 'latest'
2026-08-09 09:36:15 +00:00
gitea aff4de4e49 fix(prezentacja): osobny udział na stan zamiast subPath na udziale z bazami
Pod presentation nie wstawał: CreateContainerConfigError, „failed to create
subPath directory for volumeMount state".

MÓJ BŁĄD, NIE ZAGADKA. Udział z bazami jest wyeksportowany `ro: true`
z `root_squash` — ustawiłem to runbookiem DAN-25 i sam tam napisałem ostrzeżenie,
że po tej zmianie nikt nic nie wgra. Dokładając wolumen na konta zmieniłem
`readOnly` przy MONTOWANIU w podzie i uznałem sprawę za załatwioną, nie sprawdzając
eksportu po stronie serwera.

Przyczyna była zresztą podwójna i za każdym razem ta sama:
  1. kubelet nie mógł utworzyć podkatalogu, bo udział jest tylko do odczytu,
  2. a gdyby nawet mógł — kontenery działają jako root, a root_squash mapuje
     roota na nobody, więc aplikacja i tak nie zapisałaby tam pliku kont.

ROZWIĄZANIE BEZ RUSZANIA DAN-25: osobny, mały udział /mnt/Tank1/astrololo-state,
zapisywalny, zawężony do tych samych trzech węzłów, z mapall_user na
nieuprzywilejowanego użytkownika (bezpieczniejsze niż no_root_squash, bo nie
oddaje roota). Udział z bazami ZOSTAJE tylko do odczytu.

Przy okazji znika subPath, czyli znika potrzeba, żeby kubelet cokolwiek zakładał —
katalog istnieje, bo jest korzeniem udziału.

Runbook README-stan-prezentacji.md zawiera test zapisu Z WĘZŁA do wykonania PRZED
wdrożeniem — dokładnie ten, którego zabrakło za pierwszym razem.

UWAGA: DAN-27 (zarządzanie plikami baz) uderzy w tę samą ścianę, bo wymaga zapisu
do udziału z BAZAMI. Ten commit tego nie rozwiązuje i celowo nie rusza DAN-25 —
to osobna decyzja, opisana na końcu runbooka.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 17:46:12 +02:00
argocd-image-updater ef837146af build: automatic update of astrololo
updates image gitea/astrololo-presentation tag 'baf4e0e3' to 'a8339659'
2026-08-07 13:55:15 +00:00
gitea 2e0fe2a9be feat(prezentacja): wolumen na konta zakładane z aplikacji (PRE-27)
Ekran „Konta" zapisuje konta do pliku, więc prezentacja potrzebuje trwałego
miejsca — inaczej wszystkie konta znikałyby przy restarcie poda.

subPath, NIE cały udział: prezentacja dostaje wyłącznie własny podkatalog
`presentation-state` i nie widzi baz interpretacyjnych. Zamontowanie tu całego
/mnt/Tank1/astrololo dałoby jej wgląd w bazy i obeszłoby bokiem zamknięcie
dostępu z DAN-25.

Konto administracyjne zostaje w APP_USER/APP_PASSWORD z sekretu — celowo poza
plikiem, żeby nie dało się go skasować ani ograniczyć z aplikacji.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 12:17:39 +00:00
argocd-image-updater 2ea4b70d27 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'aec3f843' to 'baf4e0e3'
updates image gitea/astrololo-logic tag '8b6ecc72' to 'baf4e0e3'
updates image gitea/astrololo-presentation tag '8b6ecc72' to 'baf4e0e3'
2026-08-06 20:46:03 +00:00
argocd-image-updater de1293416f build: automatic update of astrololo
updates image gitea/astrololo-logic tag '21a00b00' to '8b6ecc72'
updates image gitea/astrololo-presentation tag '4d1daab3' to '8b6ecc72'
2026-08-06 14:24:09 +00:00
argocd-image-updater 48936ad289 build: automatic update of astrololo
updates image gitea/astrololo-logic tag '4d1daab3' to '21a00b00'
2026-08-06 11:43:28 +00:00
argocd-image-updater e5d5f2cab1 build: automatic update of astrololo
updates image gitea/astrololo-logic tag 'aec3f843' to '4d1daab3'
updates image gitea/astrololo-presentation tag 'aec3f843' to '4d1daab3'
2026-08-06 10:11:05 +00:00
argocd-image-updater ad0abb90e9 build: automatic update of astrololo
updates image gitea/astrololo-data tag '40f5e459' to 'aec3f843'
updates image gitea/astrololo-logic tag '1be57a47' to 'aec3f843'
updates image gitea/astrololo-presentation tag '40f5e459' to 'aec3f843'
updates image gitea/astrololo-render tag 'latest' to 'aec3f843'
2026-08-05 23:01:57 +00:00
argocd-image-updater 38c3cd3c4b build: automatic update of astrololo
updates image gitea/astrololo-data tag '40f5e459' to 'aec3f843'
updates image gitea/astrololo-render tag 'latest' to 'aec3f843'
2026-08-05 22:59:48 +00:00
argocd-image-updater 51f71a1292 build: automatic update of astrololo
updates image gitea/astrololo-logic tag '40f5e459' to '1be57a47'
2026-08-05 17:51:11 +00:00
argocd-image-updater 0ecd3de119 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'e3114f3e' to '40f5e459'
updates image gitea/astrololo-logic tag '86a0f16f' to '40f5e459'
updates image gitea/astrololo-presentation tag 'e3114f3e' to '40f5e459'
2026-08-05 10:13:25 +00:00
argocd-image-updater aaff9d6b3a build: automatic update of astrololo
updates image gitea/astrololo-data tag 'e3114f3e' to '40f5e459'
2026-08-05 10:11:22 +00:00
argocd-image-updater cb5315e4e5 build: automatic update of astrololo
updates image gitea/astrololo-logic tag 'e3114f3e' to '86a0f16f'
2026-08-04 20:30:28 +00:00
argocd-image-updater ef37a3f628 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'bc80745a' to 'e3114f3e'
updates image gitea/astrololo-logic tag 'bc80745a' to 'e3114f3e'
updates image gitea/astrololo-presentation tag 'bc80745a' to 'e3114f3e'
2026-08-04 17:55:48 +00:00
argocd-image-updater 8222129d71 build: automatic update of astrololo
updates image gitea/astrololo-data tag '70c83cfc' to 'bc80745a'
updates image gitea/astrololo-logic tag '70c83cfc' to 'bc80745a'
updates image gitea/astrololo-presentation tag '70c83cfc' to 'bc80745a'
2026-08-04 16:25:17 +00:00
gitea abc0f98034 sec(astrololo): pody bez tokenu konta serwisowego (LOG-33)
Wszystkie cztery usługi biegły na koncie `default` z AUTOMATYCZNIE montowanym
tokenem API Kubernetesa. Żadna z nich nie rozmawia z API klastra — sekrety dostają
przez `secretKeyRef`, który wstrzykuje kubelet, nie pod. Token był więc zbędny,
a leżał w każdym kontenerze jako gotowy punkt wyjścia do klastra dla kogoś, kto
przejmie proces (np. przez lukę w zależności).

`automountServiceAccountToken: false` w szablonie poda data/logic/presentation/
render. Zweryfikowane `kubectl kustomize` — pole trafia do `.spec.template.spec`,
nie do specu Deploymentu (tam byłoby ciche i bez efektu).

Zero wpływu na działanie: nic w kodzie nie woła API Kubernetesa.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 17:08:39 +02:00
argocd-image-updater 71b9fe0842 build: automatic update of conjurer
updates image gitea/conjurer-librarian tag '9f22dbf9' to 'ae1bd677'
2026-08-04 13:18:01 +00:00
argocd-image-updater 261b41240d build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'fbd1ec9f' to '9f22dbf9'
2026-08-04 11:43:36 +00:00
argocd-image-updater de4d41808a build: automatic update of astrololo
updates image gitea/astrololo-data tag '4c1e7f88' to '70c83cfc'
updates image gitea/astrololo-logic tag '4c1e7f88' to '70c83cfc'
updates image gitea/astrololo-presentation tag '4c1e7f88' to '70c83cfc'
2026-08-04 10:59:11 +00:00
argocd-image-updater b9289c4f8c build: automatic update of astrololo
updates image gitea/astrololo-data tag 'dd32f7e8' to '4c1e7f88'
updates image gitea/astrololo-logic tag 'dd32f7e8' to '4c1e7f88'
updates image gitea/astrololo-presentation tag 'd3d9b365' to '4c1e7f88'
2026-08-04 10:29:00 +00:00
argocd-image-updater 536b2bbbbb build: automatic update of astrololo
updates image gitea/astrololo-presentation tag 'dd32f7e8' to 'd3d9b365'
2026-08-03 23:04:28 +00:00
argocd-image-updater e2af5e331e build: automatic update of astrololo
updates image gitea/astrololo-data tag '78af6d47' to 'dd32f7e8'
updates image gitea/astrololo-logic tag '7b435d42' to 'dd32f7e8'
updates image gitea/astrololo-presentation tag '7b435d42' to 'dd32f7e8'
2026-08-03 22:34:20 +00:00
argocd-image-updater 1a02704422 build: automatic update of astrololo
updates image gitea/astrololo-data tag 'b36b3bee' to '78af6d47'
2026-08-03 20:33:52 +00:00
argocd-image-updater 91890b701e build: automatic update of astrololo
updates image gitea/astrololo-logic tag 'b36b3bee' to '7b435d42'
updates image gitea/astrololo-presentation tag 'a9f2a038' to '7b435d42'
2026-08-03 19:38:53 +00:00
gitea 597cbd40f8 conjurer: deploy bot on its own [deploy]-gated image channel
The production bot now tracks conjurer-bot-deploy instead of conjurer-bot,
so it updates only when the conjurer CI promotes a build (commit message
contains [deploy]). Adds the image-updater 'deploy-bot' alias and the
kustomization images entry for it; DEPLOY-BOT.md documents the channel and
the one-time bootstrap. Test bot + librarian keep tracking every build.

Pairs with conjurer#20 (the CI promotion step).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 21:11:36 +02:00
argocd-image-updater 6983814a5c build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'f4dea535' to 'fbd1ec9f'
updates image gitea/conjurer-bot tag 'f4dea535' to 'fbd1ec9f'
2026-08-03 18:46:40 +00:00
argocd-image-updater cc3c2b512d build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'd4c6d78c' to 'f4dea535'
updates image gitea/conjurer-bot tag 'd4c6d78c' to 'f4dea535'
2026-08-03 18:38:32 +00:00
argocd-image-updater 4d8ca6f4fd build: automatic update of conjurer
updates image gitea/conjurer-bot tag 'ac16b77f' to 'd4c6d78c'
2026-08-03 17:50:23 +00:00
argocd-image-updater 311d5ae071 build: automatic update of conjurer
updates image gitea/conjurer-librarian tag 'ac16b77f' to 'd4c6d78c'
2026-08-03 17:48:20 +00:00
gitea 5b6040c60d conjurer: add CONJURER_SELF_CALLBACK to both bots (per-origin librarian answers)
Pairs with conjurer#18: each bot advertises its own callback so the shared
librarian answers results/pongs back to the bot that asked - test bot
http://192.168.1.73:32442, deploy bot :32443. No CONJURER_MAIN_BOT
repointing needed for the librarian anymore; DEPLOY-BOT.md updated (only
the musician stays single-target).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 17:47:32 +00:00
gitea 358356a1b1 conjurer: add production ('deploy') bot + data seeding/backup
A second Conjurer bot alongside the test one, sharing librarian/musician/
radio and the API key, differing only in:
 * Discord token from the deploy-conjurer-netrc secret,
 * distinct names/labels (deploy-bot) and NodePort 32443,
 * /data on an NFS export (RWX) instead of a block PVC - so config/state
   can be uploaded while it runs (copy onto the share) and backed up
   concurrently.

deploy-bot-backup: a daily CronJob that mirrors /data and keeps 30 days of
dated snapshots of the critical small state (both memories, settings,
accident log, transcripts) on NFS. Production only - the test bot's
amnesia is fine. DEPLOY-BOT.md documents seeding, backup/restore, and the
librarian/musician callback routing (they push to one bot; repoint
CONJURER_MAIN_BOT to :32443 to feed this one).

kubectl kustomize builds cleanly (10 objects).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 17:47:32 +00:00
argocd-image-updater 71133be104 build: automatic update of astrololo
updates image gitea/astrololo-presentation tag 'b36b3bee' to 'a9f2a038'
2026-08-03 16:52:05 +00:00