548d9301f394cf70c92b8b4971b662cd00e5a103
122 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
548d9301f3 |
fix(domy): przepnij build_chart na cusps_for — inaczej nowe systemy dają 500
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 20s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
Rozszerzenie houses.SYSTEMS do ośmiu pozycji odblokowało w chart.py filtr `house_system in H.SYSTEMS`, ale liczenie zostało na H.cusps(), które zna wyłącznie trzy systemy dzielące ekliptykę i dla pozostałych rzuca ValueError. Wybranie campanusa przechodziło więc walidację i dopiero potem wywalało 500. Test parametryzowany po H.SYSTEMS zamyka tę klasę błędu na przyszłość: każdy system ogłoszony na liście musi przejść przez build_chart, więc dopisanie nazwy bez przepięcia liczenia od razu zapali się na czerwono. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1be57a47d8 |
feat(domy): osiem systemów potwierdzonych co do zera wobec wyroczni
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 17s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 18s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
Etap 1: systemy o zamkniętym wzorze. Dochodzą vehlow, morinus, regiomontanus, campanus i alcabitus — każdy zgodny ze Swiss Ephemeris z maksymalnym odchyleniem 0,000000000° na 240 000 porównań (zestaw brzegowy + przemiał 20 000 losowych). Cuspy pośrednie liczone wektorowo: koło domu to przecięcie płaszczyzny (wyznaczonej iloczynem wektorowym normalnych) z ekliptyką. Dwa punkty przecięcia wymagają wyboru gałęzi — rozstrzygany stroną względem MC, przy czym cztery osie bierzemy z dokładnych wzorów, bo przy przesunięciu równym 0° albo 180° test strony jest numerycznie niestabilny. Dwie rzeczy, które wyszły dopiero z porównania z wyrocznią: - swisseph zamienia MC z IC dla systemów opartych na horyzoncie, gdy punkt kulminujący jest pod horyzontem (za kołem podbiegunowym) — stąd _culminating_mc, - morinus wymaga bezpośredniej zamiany współrzędnych, nie rzutu po kole godzinnym. Topocentric (Polich–Page) zaimplementowany, ale świadomie POZA houses.SYSTEMS: rozjeżdża się z wyrocznią przy |φ| ≈ 89,9° i RAMC 90°/270°, gdzie kolejność domów się odwraca. Powód jest rzeczywisty, nie numeryczny — jego „biegun" atan(tan(89,9°)/3) to już 89,7°. Zawężenie dziedziny tylko po to, żeby test przeszedł, byłoby dopasowaniem kryterium do wyniku. Testy regresji w suicie logiki działają bez swissepha: antypodyczność domów przeciwległych, zakotwiczenie kwadrantowych na Ascendencie, niezależność morinusa od szerokości, odrzucanie nieznanej nazwy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
40f5e459e0 |
fix(ci): wyrocznia domów — wbuduj pliki w obraz zamiast montować (-v nie działa)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m28s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 22s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build / build (push) Successful in 2m47s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 3m23s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
Krok padał na `python: can't open file '/oracle/run.py'`. Przyczyna jest tą samą pułapką, którą złapano już wcześniej przy `-p` i localhoście (jest o niej komentarz w tym samym pliku): job Gitea Actions SAM działa w kontenerze, więc `docker run -v $PWD/...` demon rozwiązuje na HOŚCIE, gdzie tej ścieżki nie ma. Docker nie zgłasza wtedy błędu — po cichu tworzy PUSTY katalog, przez co skrypt „znika". Zamiast montowania wbudowujemy pliki w pomocniczy obraz (FROM engine-swisseph:ci + COPY). Kontekst builda jest strumieniowany do demona, więc działa niezależnie od tego, gdzie ten demon stoi. Obraz kasujemy po użyciu. Przy okazji .dockerignore: docker NIE czyta .gitignore, więc do demona poleciałby cały korzeń repo — z lokalnym wirtualenvem (344 MB) i jądrami efemeryd włącznie. Kontekst spada z 382 MB do 5,9 MB, co na runnerze z historią „no space left on device" nie jest kosmetyką. Plik dotyczy tylko buildów z korzenia repo — obrazy usług mają własne konteksty (services/<usługa>) i go nie widzą. Zweryfikowane bez dockera: sprawdzony dokładny tekst, jaki dostanie powłoka po dedentacji YAML (terminator heredoca w kolumnie 0), istnienie ścieżek COPY oraz to, że reguły .dockerignore nie wycinają plików potrzebnych do uruchomienia. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
86a0f16f9e |
test: framework porównania domów z wyrocznią + DWA błędy, które od razu wykrył
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Failing after 14s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 19s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Failing after 13s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Etap 0 planu egzotycznych systemów domów: zanim zaczniemy implementować Placidusa i spółkę, potrzebujemy narzędzia, które powie, czy wynik jest poprawny. Błąd w domach jest CICHY — wykres wygląda dobrze, tylko planety siedzą w złych domach. FRAMEWORK (tests/oracle): liczenie cuspów jako funkcja (RAMC, ε, φ), Swiss Ephemeris jako wyrocznia. Trzy decyzje projektowe, które okazały się kluczowe: - IZOLACJA: obu implementacjom podajemy TE SAME wejścia przez swe_houses_armc. Porównywanie „naszego horoskopu" z „horoskopem swissepha" mieszałoby różnice czasu gwiazdowego i ε z błędami domów — utonęlibyśmy w fałszywych alarmach. Czas gwiazdowy i ε mają własny test. - KRYTERIUM to liczba przypadków powyżej tolerancji (1″), max odchylenie I MIEJSCE, a nie procent zgodności. Procent ukrywa kształt błędu: „97%" nie odróżnia szumu zmiennoprzecinkowego od rogu dziedziny, w którym mylimy się o 30°. - GRANICE PER DATA: koło podbiegunowe nie jest stałą 66,56° — zależy od ε, które zmienia się z datą (23,75° w 370 p.n.e.), więc przesuwa się o ~0,3°. Uruchomiony na kodzie uchodzącym za poprawny, w PIERWSZYM przebiegu znalazł dwa realne błędy: 1. ASCENDENT O 180° ZA KOŁEM PODBIEGUNOWYM. `atan2` wybierał niewłaściwy punkt przecięcia ekliptyki z horyzontem — zwracaliśmy Descendent. Planety lądowały w PRZECIWNYCH domach dla całej północnej Skandynawii (Tromsø, Rovaniemi, Murmańsk), na ~11% przypadków przy tych szerokościach. Rozstrzyga położenie względem MC: punkt wschodzący leży w półkolu (0°,180°) na wschód od MC. 2. NIEDETERMINIZM WHOLE SIGN NA GRANICY ZNAKU. Ascendent o włos od granicy (359,999999999976 vs 1e-10 — ta sama wartość, różne strony) przerzucał dom I o 30°. Ten sam horoskop na innej maszynie dawał inny wynik. Przyciąganie do granicy przy 1e-9° (3,6 mikrosekundy łuku — poniżej realnej dokładności danych). Oba mają testy regresji w zwykłej suicie, więc są łapane też bez swissepha. Po poprawkach: build 0 przekroczeń, sweep 20 000 przypadków = 760 000 porównań, max odchylenie 0.000000000°. Istniejące suity bez regresji (logika 277+3, prez. 249). CI: krok BLOKUJĄCY w jobie swisseph-image, odpalany wewnątrz obrazu silnika B z zamontowaną warstwą logiczną. pyswisseph zostaje wyłącznie wyrocznią testową — nie wchodzi do zależności produktu, izolacja z LOG-27 nienaruszona. Dodane `cusps_for(ramc, eps, lat, system)` — kanoniczne wejście, w które Etap 1 będzie tylko dopisywał kolejne systemy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e3114f3e7c |
docs(bezpieczeństwo): runbook rotacji sekretów + poprawka nieaktualnej treści LOG-33
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 14s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m31s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 12s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Wymaganie mówiło o restarcie „WSZYSTKICH TRZECH usług" przy zmianie INTERNAL_TOKEN. Sprawdzenie żywych deploymentów pokazuje, że token czytają CZTERY: data, logic, presentation ORAZ render (doszedł przy PRE-24, a wymaganie tego nie nadgoniło). Kto zrobiłby rotację literalnie, zostawiłby render ze starym tokenem i usługa po cichu przestałaby się dogadywać — dokładnie ta awaria, przed którą wymaganie ostrzega. Treść w arkuszu poprawiona. docs/log33-sekrety-i-rotacja.md: - MACIERZ zależności wyliczona z deploymentów, nie z założeń. Wniosek praktyczny: klucze łącz rotuje się PARAMI usług (logic+data, presentation+logic, presentation+render), a nie całą czwórką — restartu wszystkiego wymaga tylko INTERNAL_TOKEN. - Procedury per sekret, od najbezpieczniejszej do przećwiczenia (klucze LLM — dotykają tylko logiki, awaria widoczna i nieszkodliwa) po INTERNAL_TOKEN. Wszystkie zachowują pozostałe klucze przez odczyt z istniejącego sekretu — inaczej rotacja jednego skasowałaby resztę. - Weryfikacja: sam „Running" NIE wystarcza (pody wstaną, nawet gdy warstwy się nie dogadują) — trzeba przeliczyć horoskop i wygenerować PDF, żeby dotknąć wszystkich łącz. - Kroki hartowania z jasnym podziałem: co zrobione (automount tokenów — deploy #13), co wymaga węzła (szyfrowanie at-rest), co świadomie odłożone (Sealed Secrets — dziś sekrety NIE są w repo GitOps, więc ta zasada już jest spełniona; Sealed Secrets dodałyby odtwarzalność kosztem nowego pojedynczego punktu awarii). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
bc80745a94 |
docs(wymagania): DAN-25 rozbite na 25a (zrobione) i 25b (Kerberos, nice to have)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m32s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 13s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 10s
build / build (push) Successful in 18s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m32s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 13s
Testy / Kontrola składni wszystkich warstw (push) Successful in 11s
Runbook wykonany na NAS-ie, więc wymaganie rozdziela się na to, co faktycznie osiągnięte, i to, co zostaje jako opcja na przyszłość — mieszanie obu w jednym wierszu kazałoby wybierać między „zrobione" a „niezrobione" dla czegoś, co jest i jednym, i drugim. DAN-25a (Must, ZROBIONE): udział /mnt/Tank1/astrololo wyeksportowany wyłącznie dla trzech węzłów k3s, tylko do odczytu, z root_squash. Zamknięta najkrótsza droga wycieku — wcześniej każdy w LAN mógł zamontować udział i wziąć kompletne bazy z pominięciem logowania, limitów, audytu i canary. Zawężony TYLKO ten udział, bo Tank1 obsługuje cały homelab. Procedura: docs/dan25-zabezpieczenie-nfs.md. DAN-25b (Could, do zrobienia): NFSv4 + Kerberos albo wolumen nieosiągalny poza klastrem. Uzasadnienie w wierszu: lista adresów IP zatrzymuje dostęp przypadkowy i oportunistyczny, ale NIE jest uwierzytelnianiem — adres da się podszyć w tej samej sieci, a przejęcie dowolnego węzła daje udział. Koszt (KDC + keytaby) uzasadniony dopiero, gdy sieć przestanie być zaufana. Bilans: 63 Zrobione · 9 W trakcie · 14 Do zrobienia. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6e7cfcbbd7 |
docs(bezpieczeństwo): runbook zamknięcia dostępu do baz na NFS (DAN-25)
build / build (push) Successful in 19s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 14s
Testy / Kontrola składni wszystkich warstw (push) Successful in 11s
Bazy leżą na udziale osiągalnym z całej sieci — to najkrótsza droga do wycieku, z pominięciem logowania, limitów, audytu i canary. Runbook zawęża udział `astrololo` do trzech węzłów k3s, ustawia tylko odczyt i root_squash. Krok po kroku, komenda po komendzie: rozpoznanie → dowód dziury (montowanie z maszyny spoza klastra) → kopia konfiguracji → zmiana → cztery testy weryfikacyjne → ścieżka wycofania. Dwie zasady wynikające z tego, że Tank1 obsługuje CAŁY homelab (Proxmox, conjurer z zapisem, media, LXC-e, stacja robocza): - ruszamy WYŁĄCZNIE udział astrololo, nigdy globalnych ustawień usługi NFS — inaczej padną VM-y, bot i biblioteka mediów; - w TrueNAS SCALE nie edytuje się /etc/exports ręcznie (middleware nadpisze) — wszystko przez midclt albo GUI. Runbook każe też sprawdzić nazwy pól w API PRZED zapisem, bo middleware zmieniało je między wersjami SCALE (path vs paths). Opisane pułapki: hookscript Proxmoxa czekający na showmount przed startem VM; utrata możliwości wgrywania baz przez NFS po ro=true; lista IP to nie uwierzytelnianie (docelowo NFSv4+Kerberos, jak mówi samo wymaganie). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
70c83cfc0c |
docs(wymagania): statusy po serii iteracji „czysto"
build / build (push) Successful in 19s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m35s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 16s
Testy / Kontrola składni wszystkich warstw (push) Successful in 15s
Aktualizacja kolumny Status wobec stanu faktycznego. Bilans: 62 Zrobione · 9 W trakcie · 14 Do zrobienia (było 52 · 9 · 24). Zrobione (zmergowane i działające): - PRE-03 strefa czasowa z lokalizacji (#43) - DAN-23 + PRE-10 eksport wyników do Excela (#45) - PRE-26 cache-busting statyki (#48) - PRE-06 konfigurowalne aspekty i orby (#49) - PRE-04 techniki relacyjne — synastria (#51) + Returns w kalendarzu (LOG-12) - PRE-17 konta imienne i dziennik audytowy (#54) - PRE-09 + DAN-15 przegląd baz na NFS i ich włączanie/wyłączanie (#55) - PRE-24 raport PDF — obraz render wreszcie się zbudował, PDF powstaje w produkcji Świadomie NIE oznaczone jako zrobione: - LOG-05 / PRE-05 zostają „W trakcie": liczenie kilku systemów domów naraz działa, ale egzotyczne (Placidus/Koch/Regiomontanus/Campanus) wymagają silnika swisseph; - DAN-26 z „Do zrobienia" na „W trakcie": mechanizm rekordów-pułapek jest gotowy i przetestowany, ale wstrzyknięcie pułapek do realnych baz i rejestr wariantów to krok właściciela, nie kodu. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4c1e7f8808 |
feat: przegląd baz na udziale + globalne włączanie/wyłączanie (DAN-15/PRE-09)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 40s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m3s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m35s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 14s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
Wymaganie przedefiniowane pod model serwerowy (#47): nie wybiera się folderu — pliki leżą na stałym NFS. Potrzeba za to WIDZIEĆ, jakie bazy są dostępne i móc zdecydować, które biorą udział w interpretacji. Warstwa danych: `bases.py` (lista plików + metaopis: nazwa, ścieżka, rozmiar, data, stan) i endpoint `/bases`. Wyłączone bazy są ODSIEWANE z kandydatów przy wyszukiwaniu, więc naprawdę nie biorą udziału w interpretacji — nie tylko znikają z listy. Lista wyłączonych wchodzi do klucza cache zapytań: bez tego zmiana ustawień oddawałaby wynik sprzed zmiany, czyli treść bazy uznanej za wyłączoną. `list_bases()` doszło do interfejsu dostawcy jako OPCJONALNE (SQL nie operuje na plikach → pusto, zamiast wywrotki). Przelot logika → prezentacja i ekran „Ustawienia" z tabelą baz. Przez łącze idą SAME METADANE — podgląd listy nie jest kolejną drogą do wyniesienia treści. Stan przełączników jest DEKLARATYWNY (`DISABLED_BASES`), nie klikalny — i to jest świadome: udział z bazami montujemy read-only, a katalog cache to `emptyDir`, więc zapisany przełącznik ginąłby przy restarcie poda i po cichu włączał z powrotem wyłączoną bazę. Ekran mówi wprost, jak wyłączyć bazę i dlaczego nie klikaniem. Tryb klikalny wymagałby dołożenia trwałego wolumenu. Weryfikacja na żywym łańcuchu: `/bases` przechodzi przez SZYFROWANE łącze (logic→data), pokazuje 3 bazy z metaopisem i stanem; wyszukiwanie daje 3 → 2 → 0 wierszy w miarę wyłączania baz. Testy: dane +6, prezentacja +6. Dane 13, logika 277, prezentacja 249. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
d3d9b365fe |
feat(bezpieczeństwo): konta imienne i dziennik audytowy (PRE-17)
build / build (push) Successful in 17s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m25s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Jedno wspólne hasło nie mówiło, KTO sięgał do baz, a odebranie dostępu jednej osobie wymagało zmiany hasła wszystkim. Przy bazach o realnej wartości handlowej to za mało. KONTA IMIENNE: `APP_USERS='alicja:scrypt$…,bartek:scrypt$…'`. Hash liczy scrypt ze STDLIB — zero nowych zależności; hasła nie ma w konfiguracji jawnie. Zakładanie konta: scripts/make_user.py (hasło interaktywnie, nie w historii powłoki). Odebranie dostępu = usunięcie wpisu, reszta nie zmienia haseł. Gdy APP_USERS jest ustawione, wspólne APP_PASSWORD PRZESTAJE działać (ostrzeżenie przy starcie) — działające obok kont byłoby tylnym wejściem bez śladu w dzienniku. Dopóki APP_USERS nie jest ustawione, stary tryb działa jak dotąd (zgodność wstecz). DZIENNIK AUDYTOWY: każde żądanie zostawia wpis „kto, skąd, co, status, ILE rekordów, ile ms". Liczba rekordów jest tu sednem — pojedyncze zapytanie wygląda niewinnie, suma pokazuje powolne wypompowywanie bazy przez osobę uprawnioną. Liczona dla wyszukiwarki sygnifikatorów, raportu i eksportu do Excela (ten wynosi najwięcej naraz). W logach NIE MA treści — ani rekordów, ani promptów. Dwa realne błędy złapane po drodze: - `secrets.compare_digest` rzuca TypeError na znakach spoza ASCII, więc hasło z polskimi literami wywracało logowanie błędem 500 zamiast odmowy (błąd ZASTANY, sprzed tej zmiany) — porównujemy teraz bajty; - dziennik był PUSTY na żywym serwerze: domyślna konfiguracja uvicorna nie obsługuje naszych loggerów. Niewidoczny dziennik jest gorszy niż jego brak, więc audyt dostał własny handler na stdout. Oba przypadki mają testy regresji. Instrukcja wdrożeniowa: docs/konta-i-audyt.md. Testy: +15. Prezentacja 243. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
dd32f7e82f |
ci: odpalaj testy warstwy bazodanowej (dotąd nie były uruchamiane)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 17s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m25s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 7s
Luka wyszła przy DAN-26 (#52): dodałem pierwsze testy w usłudze `data`, ale CI odpalało tylko `logic` i `presentation` — więc testy canary NIGDY by się nie wykonały. Nietestowany kod ochronny jest gorszy niż jego brak, bo daje złudzenie zabezpieczenia; tym bardziej nie może być testowany „na niby". - nowy job `data-tests` w tests.yml (wzorowany na presentation), - `services/data/requirements-dev.txt` (którego usługa nie miała). Sprawdzone lokalnie dokładnie tą komendą co w CI: 7 testów canary przechodzi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
78af6d4755 |
feat(dane): mechanizm rekordów-pułapek (canary) — wykrywanie wycieku baz (DAN-26)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 19s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 7s
Zabezpieczenie DETEKCYJNE (nie prewencyjne): kilka unikalnych, wiarygodnie wyglądających rekordów-pułapek w bazach. Nie zmieniają interpretacji (odsiewamy je z wyników), ale jeśli pojawią się w cudzej kopii — są dowodem pochodzenia, a przy wariancie na kopię — wskazują ŹRÓDŁO wycieku. `canary.py`: pułapkę rozpoznajemy po MARKERZE (unikalny ciąg z ENV, nieobecny w realnych danych). `screen(rows, query_value)`: - ODSIEWA rekordy z markerem z wyników — i to na WYJŚCIU z warstwy danych (`/search`), więc nie dotrą wyżej ani do promptu LLM (LOG-30), niezależnie od dostawcy (Excel/SQL); - TRIPWIRE: gdy zapytanie celuje wprost w marker (enumeracja bazy, nie liczenie horoskopu) → log warning. Bez `CANARY_MARKERS` — przezroczyste, zero kosztu dla normalnego ruchu. Rejestr wariant→kopia (traitor tracing) i wstrzyknięcie do REALNYCH baz to krok właściciela (poza kodem — nie ruszamy kupionych plików automatycznie); instrukcja: docs/canary-registry.md. Mechanizm zbudowany i przetestowany na syntetycznych pułapkach. Testy: +7 (przezroczystość bez markerów, odsiewanie, tripwire, marker w dowolnym polu, endpoint odsiewa przed zwrotem). Pierwsze testy w usłudze `data`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
7b435d4263 |
feat: synastria — aspekty między dwoma horoskopami (PRE-04)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m32s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build / build (push) Successful in 25s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m18s
Testy / Kontrola składni wszystkich warstw (push) Successful in 31s
Testy / Build obrazu silnika B (swisseph) (push) Failing after 13m6s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Failing after 13m25s
Pierwsza technika relacyjna z pełnym UI (Returns były już w kalendarzu od LOG-12). Dwie osoby → aspekty MIĘDZY ich horoskopami (planeta osoby A do planety osoby B). Silnik: `find_cross_aspects(a, b, orb, luminary_bonus, minor)` — każdy obiekt A × każdy obiekt B. `obj1` = osoba A, `obj2` = osoba B. Statyczne (dwa natale, brak wspólnego czasu) → bez applying/separating. Par sztywnych (NN/SN) NIE wycinamy — między dwiema osobami to realny aspekt, nie artefakt definicji. Wspólny matcher `_first_aspect` (z find_aspects), więc orb/bonus/aspekty poboczne działają tak samo. Endpoint `POST /chart/synastry` (dwie osoby + zodiak + ustawienia aspektów) → pozycje obu + siatka aspektów z glifami. Prezentacja: zakładka „Synastria", formularz dwóch osób (pętla po a_/b_), tabela aspektów A · aspekt · B · orb. Weryfikacja na żywym API: 13+13 obiektów, 63 aspekty synastryczne z poprawnymi glifami i bonusem świateł (A.Sun ☌ B.Venus przy orbie 8.67 = 8+2). Testy: logika +4 (cross-aspekty, kolejność A/B, brak filtra par sztywnych, brak applying), prezentacja +7 (trasa, formularz dwóch osób, klient, tabela). Logika 277, prezentacja 228. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a9f2a038fa |
refactor(prezentacja): wspólne partiale formularza — koniec dublowania chart/compile
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m32s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m28s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Spłata długu: bloki opcji i tabele wyniku były kopiowane między „Horoskop" (/) i „Skompiluj" (/compile). Duplikat już raz spowodował regresję (podsumowanie gubiło opcje), a przy każdej nowej opcji rósł (dodawałem je 3× w dwóch miejscach). - `_form_options.html` (NOWY): bloki opcji — stacje/tabele, porównanie domów, ustawienia aspektów. Dołączany przez oba formularze. - `_result_tables.html`: chart.html PRZECHODZI na ten wspólny plik (compile już go używał od #46). Rysunki (koło/aspektarian/deklinacja/antyscja) zgrupowane razem, potem wspólne tabele. Dzięki temu widok główny i podsumowanie NIE MOGĄ się już rozjechać — jedno źródło prawdy. Zero zmian zachowania: oba szablony renderują te same pola i tabele co wcześniej (sprawdzone renderem na bogatym wyniku). Testy strukturalne przełączone na odczyt wspólnych plików. Prezentacja 221. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
b36b3bee19 |
feat: konfigurowalne aspekty i orby (PRE-06)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m47s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m27s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 12s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 9s
build / build (push) Successful in 26s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 12s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Dotąd orb (8°) i aspekty były zaszyte w silniku. Astrolodzy pracują na różnych orbach i lubią dokładać aspekty poboczne — teraz da się to ustawić w UI. Silnik (aspects.py): `find_aspects` przyjmuje orb, luminary_bonus i `minor`. Aspekty poboczne = tylko trzy (półsekstyl 30° / półkwadratura 45° / kwinkunks 150°) — bo mają już glify i barwy w prezentacji i w engine/glyphs.py, więc dokładają się bez ruszania czegokolwiek poza silnikiem. Bazy zwykle ich nie opisują (brak tokenu), więc trafiają na kosmogram i do tabeli, ale NIE tworzą faset — most sygnifikatorów po cichu je pomija (skip przy braku tokenu). Plumbing przez wszystkie warstwy: request logiki, build_chart, klient prezentacji, oba handlery (/, /compile) ORAZ PDF (/compile/pdf). Ustawienia wędrują między zakładkami (formsync) i lecą do PDF-a (compile.js) — żeby podsumowanie liczyło aspekty tym samym orbem co horoskop (ta sama zasada co fix podsumowania #46). UI: orb, bonus dla świateł, checkbox „aspekty poboczne" na obu formularzach. Weryfikacja na żywym /chart/positions: domyślnie 24 aspekty (główne); minor → 52 (dochodzą quincunx/semisextile/semisquare); orb 3 → 13, orb 12 → 32. Testy: logika +3 (minor/orb/bonus), prezentacja +6 (obecność pól, przekazanie przez warstwy, sync, PDF). Logika 273, prezentacja 220. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a0d1135db1 |
feat(prezentacja): cache-busting plików statycznych (PRE-26)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 11s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 50s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m51s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 11s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Po deployu przeglądarka trzymała stare styles.css / *.js — ten sam URL, więc serwowała z cache mimo nowej wersji. Doklejamy do URL-a krótki HASH TREŚCI pliku: zmienił się plik → zmienił się URL → przeglądarka pobiera nowy; bez zmian URL zostaje ten sam i cache dalej działa (bustujemy tylko to, co się zmieniło). - `static_url(name)` + globalny helper Jinja `static()`: `/static/x?v=<md5[:8]>`. Hash liczony raz na proces (lru_cache) — nowy pod po deployu = świeży hash; brak pliku → `?v=0`, nie wywala strony. - Wszystkie odwołania w szablonach (styles.css, nasze *.js, vendor Leaflet) idą teraz przez helper zamiast surowego `/static/...`. Testy: +5 (hash w URL, zależny od treści, brak-pliku-bezpieczny, żaden szablon nie serwuje surowej ścieżki, base używa helpera). Test kolejności skryptów zaktualizowany pod nowy format. Prezentacja 214. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
81e09aa6df |
docs(wymagania): PRE-09/DAN-15 przedefiniowane pod model serwerowy
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m39s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m32s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 19s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 12s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m42s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m27s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 15s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
build / build (push) Successful in 17s
Redefinicja uzgodniona z użytkownikiem (2026-07-28), ale do tej pory żyła tylko w notatkach — w arkuszu wciąż było desktopowe „wskazanie folderu baz + pamięć 3 ścieżek", bezcelowe w modelu serwerowym (bazy na stałym udziale NFS, nie w folderze wybieranym przez użytkownika). Nowe brzmienie obu wymagań: - DAN-15 (dane): warstwa danych wystawia listę baz dostępnych na NFS (nazwa + metaopis: rozmiar / liczba rekordów / data) i honoruje globalne włącz/wyłącz każdej bazy przy wyszukiwaniu interpretacji. - PRE-09 (prezentacja): ekran ustawień pokazuje te bazy i pozwala globalnie włączać/wyłączać każdą; wyłączona nie jest brana pod uwagę przy interpretacji. Priorytet/status bez zmian (PRE-09 Must, DAN-15 Should, oba Do zrobienia). Zmiana tylko tekstu wymagań — plik poza dwoma wierszami nietknięty, bilans statusów ten sam. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8ebce816cd |
feat(prezentacja): eksport wyników do Excela — tabela robocza (DAN-23/PRE-10)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m29s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m32s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 16s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 11s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Has been cancelled
Testy / Build obrazu silnika B (swisseph) (push) Has been cancelled
Testy / Kontrola składni wszystkich warstw (push) Has been cancelled
Testy / Testy warstwy logicznej (silnik) (push) Has been cancelled
build / build (push) Successful in 53s
Astrolog chce PRACOWAĆ z dopasowaniami: filtrować, sortować, zaznaczać, usuwać — najwygodniej w Excelu. Raport z logiki jest zagnieżdżony (obiekt → fasety → próbki), więc spłaszczamy go do JEDNEJ płaskiej tabeli: wiersz = jedno dopasowanie z bazy. Kolumny: Obiekt · Faseta · Typ · Token · Sygnifikator · Rozwinięcie · Opis/efekt. - `report_export.py`: `report_to_xlsx(report)` (openpyxl). Auto-filtr + zamrożony nagłówek = filtrowanie/sortowanie od razu; „Opis" zawijany. Bez ozdób — materiał roboczy. Plik składamy TU, w prezentacji (jak PDF idzie przez render): logika liczy, prezentacja formatuje wyjście. - `/interpret` dostaje akcję `export` → pobranie `.xlsx` (nie strona). Przycisk „Pobierz Excel" obok „Szukaj interpretacji". - Zależność: openpyxl (czysty Python). Zero swissepha, zero walidacji krzyżowej, zero danych od użytkownika — pierwsza z iteracji „czysto". Testy: +7 (round-trip pliku: nagłówek, spłaszczenie, auto- filtr/zamrożenie, pusty-bezpieczny, %, wpięcie w UI). Prezentacja 180. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
52b7c20c2a |
fix(prezentacja): podsumowanie bierze WSZYSTKIE policzone opcje (stacje, tabele, domy)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 15s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 10s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m5s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m31s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 15s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
build / build (push) Successful in 2m49s
Regresja: „Skompiluj" przeliczało horoskop od nowa z OKROJONYM zestawem opcji (tylko system domów + zodiak), więc jeśli przy horoskopie policzyłeś stacje, tabele (żywioły, faza Księżyca…) albo porównanie domów — w podsumowaniu ich NIE było. Zamiast pokazać to, co policzono, liczyło uboższą wersję. Zostaje czysty przelicz (bez trzymania dużego wyniku w przeglądarce), ale z TYMI SAMYMI opcjami co przy horoskopie: - `formsync`: synchronizuje między zakładkami też opcje — checkboxy (stacje, tabele) i wielo-checkbox (porównanie domów). Wcześniej umiał tylko `.value`. - „Skompiluj" (formularz): dostaje te same opcje; `compile_build` i `compile_pdf` przekazują je do logiki (stations/tables/house_systems). `compile.js` wysyła je w payloadzie PDF-a. - Wspólny plik `_result_tables.html`: podsumowanie renderuje DOKŁADNIE te same tabele co „Horoskop" (porównanie domów, stacje, aspekty, paralele, antyscja, żywioły/faza/godziny, Lots…). Każda sekcja pokazuje się tylko, gdy jej dane są w wyniku — opcja niepoliczona → sekcji nie ma (zgodnie z prośbą). (TODO: przełączyć też chart.html na ten include, by widoki nie mogły się rozjechać — na razie zgodność pilnowana ręcznie, jest komentarz w pliku.) Weryfikacja: render wspólnego pliku na bogatym wyniku pokazuje wszystkie sekcje. Testy: +8 (opcje niesione w /compile i /compile/pdf, sync checkboxów/multi, wspólny include). Prezentacja 202. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
9b1e4dbb20 |
feat: wiele systemów domów naraz — porównanie obok siebie (PRE-05/LOG-05, A2a)
build / build (push) Successful in 1m3s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m7s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 36s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Astrolodzy spierają się o systemy domów; teraz można policzyć kilka na raz i zobaczyć, jak różny podział przesuwa planety między domami. Domy to geometria z Asc/MC — osie są WSPÓLNE, różni się tylko podział. Prymarny system zostaje w `cusps`/`house_system`/`positions[].house` (pod kosmogram i wstecznie — nic się nie zmienia dla dotychczasowych ścieżek). Nowość: - logika: `build_chart(..., house_systems=[...])` → `result["house_systems"]` = pełen zestaw (prymarny pierwszy, bez duplikatów), a `positions[].houses[system]` mówi, w którym domu obiekt siedzi wg każdego systemu. Doklejane tylko gdy > 1. Nieznany system (np. placidus — dojdzie przez swisseph osobno, A2b) pomijany, nie wywala horoskopu. - endpoint `/chart/positions`: pole `house_systems`; klient prezentacji przekazuje. - UI: checkboxy „Porównaj systemy domów" (whole sign / equal / porphyry) + tabela kusp obok siebie (12 domów × systemy), stan zaznaczeń przeżywa submit. Na razie 3 systemy z czystej matmy (`houses.py`) — zero zależności, zero walidacji krzyżowej. Egzotyczne (Placidus/Koch/Regiomontanus/Campanus) dojdą przez endpoint `/houses` w silniku B (swisseph) jako A2b — maszyneria „naraz" jest już gotowa, egzotyczne tylko dopiszą kolejne wpisy. Weryfikacja: żywy /chart/positions — prymarny whole_sign, house_systems [whole_sign, equal, porphyry], 12 kusp/system, dom per system per obiekt. Testy: logika +5, prezentacja +6. Logika 270, prezentacja 179. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4bdfb673cc |
feat(prezentacja): strefa czasowa z lokalizacji — DST-świadomy offset (PRE-03)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m2s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m56s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 34s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 23s
build / build (push) Successful in 1m40s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m12s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m52s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 32s
Testy / Kontrola składni wszystkich warstw (push) Successful in 19s
„Logika dwóch lokalizacji": dotąd offset GMT był ręcznym polem (PRE-19) — trzeba
było go znać i samemu pamiętać o czasie letnim. Teraz liczymy go z lokalizacji.
Sedno wymagania: strefę ustalamy RAZ i trzymamy jako stałą liczbę, żeby drobna
zmiana współrzędnych nie przerzuciła DST i nie „przeskoczyła" Ascendenta na
sąsiedni znak. „Większa miejscowość z bazy" okazuje się zbędna — strefa IANA jest
i tak regionalna, więc wioska daje tę samą strefę co pobliskie miasto.
Jak:
- `timezone.py`: współrzędne → strefa IANA (tzfpy, OFFLINE — bez sieci), a z niej
offset DLA DATY URODZENIA. `zoneinfo`/`tzdata` znają reguły historyczne i DST:
Kraków 1984 to +1h zimą, +2h latem; Katmandu +5:45. Degraduje się do None (brak
biblioteki / punkt bez strefy / zła data) — wtedy zostaje ręczny offset.
- Endpoint `GET /timezone?lat&lon&date&time` → {tz, offset, dst, label}. 404, gdy
nie da się ustalić.
- `geo.js`: po wyborze miejsca (mapa / wyszukiwarka / „Tu i teraz") oraz przy
zmianie DATY (bo DST zależy od pory roku) pobiera offset i wypełnia pole
tz_offset, pokazując wykrytą strefę („Wykryto: Europe/Warsaw · +2:00 (czas
letni)"). Pole zostaje edytowalne. Na wejściu podpowiada tylko gdy offset
wygląda na nieustawiony — nie nadpisuje wartości ręcznie wpisanej i wysłanej.
Zależności (lekkie, offline): tzfpy (wheel Rust) + tzdata (dla zoneinfo w slim-obrazie).
Weryfikacja: żywy serwer — Kraków 1984-06 → +2:00 (czas letni), 1984-01 → +1:00,
Katmandu → +5:45. Testy: +12 strefa (moduł + endpoint), +5 JS. Prezentacja 187.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
9a5d61b5eb |
docs(wymagania): PRE-18 → Zrobione (aspektarian + wizualizacje pochodne)
build / build (push) Successful in 43s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m14s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m0s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 35s
Testy / Kontrola składni wszystkich warstw (push) Successful in 22s
Audyt kolumny Status wobec kodu. Jedyna realna rozbieżność od ostatniego przeglądu (PR #24): PRE-18 „Grafika aspektów (aspectarian) i wizualizacje pochodne" wisiało na „Do zrobienia", a jest dowiezione i zmergowane: - aspektarian (trójkątna siatka aspektów) — PR #38, - wizualizacje pochodne: wykres deklinacji z paralelami + oś antyscji — PR #40, - wpięte też w raport „Skompiluj" i PDF — PR #41. Bilans: Zrobione 52 · W trakcie 9 · Do zrobienia 24. Reszta pozostaje bez zmian — zweryfikowane, że statusy są aktualne (m.in. LOG-05/PRE-05 wiele domów naraz, LOG-17 asp+/-, DAN-08 jako zasób danych wciąż częściowe). PRE-24 (PDF) celowo zostaje „W trakcie": kod kompletny i przetestowany, ale usługa render nie składa jeszcze PDF-ów w produkcji (blokada = dysk runnera). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
bb64758fa0 |
stacks
build / build (push) Successful in 48s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m14s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m56s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 37s
Testy / Kontrola składni wszystkich warstw (push) Successful in 22s
|
||
|
|
91c4f918dc |
stacks
build / build (push) Successful in 43s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m10s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 34s
Testy / Kontrola składni wszystkich warstw (push) Successful in 23s
|
||
|
|
f5dec15e4d |
feat: aspektarian, deklinacja i antyscja trafiają do raportu i PDF-a
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m13s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m49s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 29s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 20s
build-render / build (push) Successful in 44s
build / build (push) Successful in 54s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m19s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m59s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 34s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Zasada: co składamy, dodajemy i wyświetlamy, MA trafiać do finalnego raportu
(«Skompiluj») i do PDF-a — nie tylko na stronę /chart. Do tej pory do raportu i
druku szło samo koło; aspektarian (etap 5) i deklinacja/antyscja (etap 6) były
tylko w podglądzie horoskopu.
RAPORT «Skompiluj» (podgląd): handler /compile liczy teraz wszystkie cztery
rysunki, a szablon je pokazuje (koło, aspektarian, deklinacja, antyscja).
PDF (usługa render) — uogólnienie z jednego rysunku na LISTĘ:
- Kontrakt raportu: `figures = [{svg, caption}]` (uporządkowana). `wheel_svg`
zostaje dla zgodności wstecznej jako pojedynczy rysunek.
- `compile.py`: każdy SVG osobno przez rsvg-convert → PDF (fig0…figN); braki/
błędy pomijane (rysunek nie może wywalić raportu, tekst ważniejszy).
- `latex.py build()`: rysunki w sekcji 3 (po danych, przed natalną) w PODANEJ
kolejności, każdy z podpisem. Jedna reguła składania: keepaspectratio z limitem
szerokości i wysokości — kwadratowe (koło, aspektarian) ogranicza wysokość,
szerokie (deklinacja, antyscja) szerokość, bez zniekształceń.
- `compile_pdf` (prezentacja): renderuje komplet w motywie DRUKU i wysyła jako
`figures`.
Testy: render +5 (kolejność, podpisy, zgodność wsteczna, pomijanie pustych),
prezentacja +3 (raport pokazuje komplet, PDF składa komplet). Render 32,
prezentacja 173.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
495f3734c5 |
Stacks
build / build (push) Successful in 1m18s
Testy / Testy warstwy logicznej (silnik) (push) Failing after 12s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m0s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 31s
Testy / Kontrola składni wszystkich warstw (push) Successful in 22s
|
||
|
|
adce568729 |
feat(prezentacja): wykres deklinacji i oś antyscji (LOG-07, kosmogram etap 6)
Ostatni etap rysowania kosmogramu: wizualizacje pochodne z aspektów pozazodiakalnych (LOG-07). Do tej pory paralele i antyscja były tylko w tabelach — teraz widać je na rzut oka. WYKRES DEKLINACJI (`render_declination`): - Pionowa skala deklinacji z równikiem (0°) i zwrotnikami (±ε, kreskowane) — ε bierzemy z `obliquity` w wyniku, więc granica jest dokładna dla daty. - Obiekty na osi X ułożone wg POSORTOWANEJ deklinacji, więc paralele (ta sama wysokość) lądują obok siebie. Łączniki: paralela zielona (jak koniunkcja), kontrparalela czerwona (jak opozycja) — te same barwy co linie na kole, grubość wg orbu. Dymek z nazwą zjawiska i orbem. - Strefa poza zwrotnikami cieniowana; obiekt OOB (out-of-bounds) w kolorze wyróżnienia + „OOB" w dymku. Od razu widać ciała o skrajnej deklinacji. OŚ ANTYSCJI (`render_antiscia`): - Ekliptyka rozwinięta w poziomą oś ze znakami; pionowo zaznaczona oś przesileń (0° Raka/Koziorożca) — lustro antyscji — i oś równonocy (0° Barana/Wagi) dla kontrantyscji. Pary połączone łukiem (zielony antyscja / czerwony kontrantyscja), z dymkiem. Bez par oś i obiekty i tak coś mówią. Oba w obu motywach (screen + print), więc gotowe też do PDF-a. Pokazują się na /chart pod odpowiednimi tabelami LOG-07. Testy: +13 (etap 6). Prezentacja: 170. Domyka etapy kosmogramu (PRE-12): 1 szkielet, 2 obiekty, 3 aspekty, 4 dopracowanie, 5 aspektarian, 6 deklinacja/antyscja. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
998c83b26e |
fix(render): potrójne gwiazdki i kratki bez spacji nie wyciekają do PDF
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m9s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m59s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 39s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 18s
build-render / build (push) Successful in 8m52s
build / build (push) Successful in 7m9s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 13m40s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m3s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 36s
Testy / Kontrola składni wszystkich warstw (push) Successful in 28s
Dwie realne dziury w markdown→LaTeX, obie WIDOCZNE w gotowym PDF:
1. `***mocne***` (pogrubienie+kursywa) łapało się jako `**` + zgubiona gwiazdka →
`\textbf{*mocne}*`, czyli w druku zostawał wisior `*`. Dokładam alternatywę
`\*\*\*…\*\*\*` PRZED `**` i `*` (kolejność od najdłuższego znacznika) →
`\textbf{\textit{…}}`.
2. Nagłówek bez spacji po kratkach (`##Tytuł`), zamknięty ATX (`## Tytuł ##`)
i 7+ kratek trafiały do akapitu i były eskejpowane jako `\#\#…`. Pułapka: w
LaTeXu `\#` renderuje się jako `#`, więc w PDF WIDAĆ było `##`, choć w źródle
`.tex` jest `\#\#`. Dlatego stary test (`"##" not in out`) tego nie łapał —
podłańcuch `##` nie występuje w `\#\#`. Nagłówki traktujemy teraz pobłażliwie:
dowolna liczba kratek na starcie, spacja nieobowiązkowa, końcowe kratki
ucinane, gołe kratki bez treści pomijane. Żaden znacznik nagłówka nie ostaje.
Nowa asercja w testach patrzy pod kątem RENDERU: brak `\#` i brak wiszącej
gwiazdki (poza gwiazdką poleceń `\section*` itd.). +7 testów regresji, render 34.
UWAGA DEPLOY: obraz render w rejestrze to wciąż
|
||
|
|
4b17f2dd67 |
feat(prezentacja): aspektarian — siatka aspektów (PRE-18, kosmogram etap 5)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m37s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m32s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 25s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 19s
build / build (push) Successful in 48s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m34s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m2s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 1m7s
Testy / Kontrola składni wszystkich warstw (push) Successful in 41s
Trójkątna siatka aspektów obiekt×obiekt obok koła. Koło pokazuje GEOMETRIĘ aspektów (linie w środku), aspektarian domyka temat od drugiej strony — TABELĘ na jeden rzut oka: kto z kim i jak. Klasyczny „schodkowy" układ: glify obiektów biegną po przekątnej, a każda komórka pod nią to aspekt między obiektem ze swojego wiersza a obiektem ze swojej kolumny. Pusta komórka też niesie informację — że pary NIC nie łączy. Spójność z kołem trzymana świadomie: - te same barwy aspektów (niebieski harmonijny / czerwony napięty / zielony koniunkcja) — oko łapie ten sam kod na kole i w siatce; - ciasny aspekt (orb <1°) pogrubiony, tak jak grubsza linia na kole; - natywne dymki <title> (bez JS): „Słońce trygon Mars · orb 0.20° · aplikacyjny", polskie nazwy tylko w dymku — obliczenia trzymają angielskie; - oba motywy: „screen" (zmienne CSS aplikacji) i „print" (konkretne kolory + font glifów wprost), więc siatka jest gotowa też do PDF-a. Glify aspektów (☌ ☍ △ □ ⚹ ⚺ ⚻ ∠) trzymamy lokalnie w prezentacji — tam gdzie już są kolory i polskie nazwy — więc aspektarian jest samowystarczalny i nie zależy od tego, czy pojedynczy rekord aspektu niesie glif. Renderer degraduje się do pustego przy mniej niż dwóch obiektach; niekompletny obiekt (bez glifu) go nie wywala. Aspektarian pokazuje się na /chart i /compile pod kołem. Testy: +12 (etap 5). Całość prezentacji: 157. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
623603b157 |
feat: Markdown→LaTeX w PDF + dopracowanie kosmogramu (PRE-24, PRE-12 etap 4)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m34s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m35s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 35s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 19s
build-render / build (push) Successful in 45s
build / build (push) Successful in 50s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m46s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m33s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 28s
Testy / Kontrola składni wszystkich warstw (push) Successful in 21s
Dwie rzeczy w jednym PR (na prośbę).
1) MARKDOWN → LATEX w raporcie PDF (usługa render). Tekst od AI to markdown —
świetny w przeglądarce, ale w PDF `**gwiazdki**` i `## kratki` to dosłowny szum.
Nowy markdown_to_latex zamienia je na PRAWDZIWE formatowanie: nagłówki (degradowane
o poziom, żeby wpadły pod nasz \section „Interpretacja natalna", nie obok),
pogrubienia, kursywy, kod, listy punktowe i numerowane, linki (zostaje sam tekst,
URL bezużyteczny w druku).
Skaner liniowy, nie regex na całości — listy i akapity są wielolinijkowe.
Ucieczka znaków LaTeXa działa TAKŻE wewnątrz formatowania: `**wzrost 50%**` daje
`\textbf{wzrost 50\%}`, a nie zakomentowaną resztę linii. Sprawdzone na wrogim
tekście — `\end{document}` i `\input{}` w treści nie wyrywają się z dokumentu
nawet zawinięte w pogrubienie.
2) KOSMOGRAM — etap 4 (dopracowanie):
- Lots na kole: Fortuna ⊗ (jedyny Lot ze standardowym glifem) na promieniu POD
pierścieniem planet i w akcencie — od razu widać, że to punkt wyliczony, nie
ciało. Loty bez glifu (Spirit, Eros…) pomijamy, żeby nie zaśmiecać.
- Tooltipy: natywny <title> w SVG (bez JS-a). Obiekt → nazwa, pozycja, dom,
retrogradacja. Linia aspektu → „Słońce trygon Mars · orb 0.20°" (polskie nazwy
tylko do dymka; obliczenia trzymają angielskie). Fortuna → nazwa i pozycja.
- Stopnie cuspów przy szprychach. W whole sign cuspy są na 0° znaku — wtedy
pomijamy dwanaście zbędnych zer; w systemach kwadratowych (porphyry) stopień
realnie coś mówi, więc go pokazujemy.
Wszystko działa też w motywie druku (PDF): sprawdzone, że mimo Lotów, dymków
i cuspów SVG nadal nie ma zmiennych CSS.
Weryfikacja wizualna (porphyry): Fortuna przy AC, 12 stopni cuspów, 38 dymków
(24 aspekty + 13 obiektów + Fortuna). Testy: +12 markdown (render), +7 etap 4
(prezentacja). Całość: prezentacja 145, render 27.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
171deff2d1 |
feat(prezentacja): linie aspektów na kosmogramie (PRE-12, etap 3)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m36s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m35s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 28s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 21s
build / build (push) Successful in 48s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m34s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 31s
Testy / Kontrola składni wszystkich warstw (push) Successful in 17s
Trzeci etap rysowania koła: linie aspektów w środku. Domyka rdzeń PRE-12 — kosmogram ma teraz znaki, domy, osie, obiekty i aspekty. Linie łączą PRAWDZIWE pozycje obiektów (nie rozsunięte glify — aspekt dotyczy tego, gdzie planeta faktycznie stoi) na okręgu piasty, w środku koła. Kodowanie jak w klasycznych programach: - KOLOR = charakter aspektu: niebieski harmonijny (trygon, sekstyl), czerwony napięty (kwadratura, opozycja), zielony koniunkcja. Dwa kolory na środku od razu mówią „gdzie łatwo, gdzie tarcie". - GRUBOŚĆ i JASNOŚĆ = orb: im ciaśniej, tym mocniej. Poniżej 1° wyraźne pogrubienie (wprost z wymagania) — najściślejsze aspekty rzucają się w oczy, a szerokie ledwo majaczą, żeby nie robić ze środka plątaniny. Rysowane jako pierwsze, pod resztą: obiekty siedzą na R_PLANET=150, daleko od piasty (R_HUB=48), więc glify i linie się nie stykają, a osie i szprychy lądują na wierzchu. Motyw druku (PDF, PRE-24) dostaje własne, ciemniejsze kolory aspektów bez zmiennych CSS — samodzielny konwerter SVG arkusza nie widzi. Weryfikacja na horoskopie referencyjnym: 24 aspekty, 5 ciasnych (<1°) faktycznie pogrubionych; kolory zgodne z typem (9 czerwonych napiętych, 10 niebieskich harmonijnych, 5 zielonych koniunkcji); print bez zmiennych CSS. Sprawdzone wizualnie — pełny aspektarian, czytelny. Testy: 8 nowych (linie obecne, kolor wg typu, pogrubienie <1°, prawdziwa pozycja nie rozsunięta, pominięcie aspektu do obiektu bez pozycji, brak aspektów, motyw druku). Całość: prezentacja 138 passed. PRE-12 -> Zrobione. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
15964dd0df |
chore: wymuszenie nowego obrazu data/logic/presentation po incydencie z :latest
build / build (push) Successful in 1m16s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m11s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m40s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 30s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 20s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m38s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m38s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 26s
Testy / Kontrola składni wszystkich warstw (push) Successful in 21s
Komentarz-marker w main.py każdej z trzech usług — zmienia zawartość obrazu, więc build.yaml wyprodukuje NOWE SHA-tagi z nowszym `created`. To odblokowuje image-updatera (strategia newest-build), który utknął: wszystkie trzy usługi mają w deployu tag `:latest`, którego build.yaml nigdy nie pcha (tylko SHA), więc nowe pody wpadły w ImagePullBackOff. Nowy build z realnym SHA da updaterowi co promować i przykryje `:latest` w kustomization — bez ręcznej zmiany w repo deploy. UWAGA: samo to NIE wystarczy. W namespace astrololo zniknął pull-secret `gitea-registry`, więc nawet z poprawnym tagiem nowe pody nie pobiorą obrazu. Trzeba go odtworzyć (kopia działającego `gitea-registry-creds` z ns argocd) — osobna, ręczna operacja, poza tym commitem. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
9ddcdea5e2 |
cleanup
build / build (push) Successful in 48s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m34s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m37s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 28s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 17s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m39s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 30s
Testy / Kontrola składni wszystkich warstw (push) Successful in 17s
|
||
|
|
56131b209a |
ci: workflow budujacy obraz uslugi render (PRE-24)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m59s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m52s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 32s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 28s
build-render / build (push) Successful in 10m15s
build / build (push) Successful in 1m6s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m27s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m52s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 24s
Luka: usluga render (services/render) weszla w #32, ale zaden workflow nie budowal jej obrazu — wiec astrololo-render:latest nie istnial w rejestrze, a pod zawislby na ImagePullBackOff po wdrozeniu manifestow. Osobny pipeline (jak build-swisseph), nie dopisanie do build.yaml: obraz dzwiga TeX Live (setki MB), a build.yaml chodzi przy KAZDYM pushu do mastera. Budowanie renderu za kazdym razem spowalnialoby kazdy deploy — a to wlasnie ta izolacja miala usunac. Wyzwalany tylko zmiana w services/render/**; workflow_dispatch do bootstrapu. Merge tego PR zbuduje pierwszy obraz (push dotyka pliku workflow, wiec trigger sie odpali) i wypchnie :latest — dopiero potem ma sens merge deploy#5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f24616d342 |
feat(render): raport PDF przez LaTeX jako osobna usluga (PRE-24)
build / build (push) Successful in 1m27s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m25s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m1s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 33s
Testy / Kontrola składni wszystkich warstw (push) Successful in 27s
Ostatnia z osmiu wskazowek partnerow. Nowa usluga services/render sklada raport:
generuje plik posredni .tex i kompiluje go XeLaTeX-em do PDF.
OSOBNY komponent, nie czesc prezentacji — ta sama zasada co przy izolacji
swissepha (LOG-27). TeX Live wazy setki megabajtow; w obrazie produktu
spowalnialby kazdy build, a tak aktualizuje sie niezaleznie i jego awaria nie
kladzie aplikacji, tylko przycisk „Pobierz PDF".
SZYFROWANIE, o ktore prosiles: lacze prezentacja↔render idzie tak samo jak
pozostale, ale z WLASNYM, TRZECIM kluczem (LINK_KEY_PRESENTATION_RENDER). Osobny,
bo tym laczem plynie CALY raport — dane urodzeniowe i opisy z baz — wiec przejecie
go nie moze otwierac lacza do logiki ani do danych. Fail-closed: bez klucza pod
nie wstaje. Test kopii link_crypto obejmuje teraz cztery uslugi.
Uklad PDF wg prosby: imie i nazwisko -> wprowadzone dane -> RYSUNEK kosmogramu
-> interpretacja natalna -> predykcje okresowe. Test pilnuje kolejnosci.
Dwie rzeczy, ktore wyszly dopiero przy skladaniu tego kawalka:
1. KOSMOGRAM NIE NADAWAL SIE DO PDF. Uzywa zmiennych CSS (var(--line)) i klasy
.glyph, ktorej font podaje styles.css — a samodzielny konwerter SVG→PDF nie zna
naszego arkusza. Wyszlyby czarne kreski BEZ SYMBOLI. Stad wariant „print":
konkretne kolory na bialym tle i font glifow wpisany wprost w rysunek. Przy
okazji zalatwia to etap 4 planu kola (wariant do druku).
2. UCIECZKA ZNAKOW LATEXA byla zepsuta — i zlapal to moj wlasny test. Zamiana
„\” na \textbackslash{} szla w tej samej petli co nawiasy, wiec kolejne
podmiany ucieklyby nawiasy dopiero co wstawione: wychodzilo
\textbackslash\{\}. Poprawka: ukosnik chowany pod znacznik zastepczy i
rozwijany na koncu. To nie kosmetyka — niezauwazony „%” komentuje RESZTE LINII,
wiec zdanie od modelu urywaloby sie w polowie, a PDF powstawalby normalnie,
tylko krotszy. Test na wrogim tekscie sprawdza tez, ze \end{document} ani
\input{} nie wyrwa sie z dokumentu.
Usluga nie zapisuje nic poza katalogiem tymczasowym, ktory sprzata po sobie;
w manifescie readOnlyRootFilesystem + emptyDir na /tmp. /health raportuje
obecnosc xelatex i rsvg-convert, zeby zepsuty obraz bylo widac od razu.
Zweryfikowane na zywo (TestClient uslugi render): zadanie bez szyfrowania
z POPRAWNYM tokenem -> 400; obcy klucz -> 400 i tajny opis nie wraca; wlasciwy
klucz -> zadanie dochodzi do aplikacji, tresci baz NIE MA na kablu, odpowiedz
zaszyfrowana. Manifesty przechodza kubectl apply --dry-run=server na zywym
klastrze.
CZEGO NIE SPRAWDZILEM: samej kompilacji PDF. W tym srodowisku nie ma ani TeX
Live, ani dzialajacego runtime'u kontenerow (docker CLI jest, daemon nie) —
probowalem zbudowac obraz i sie nie dalo. Sprawdzone jest wszystko dookola:
generowanie .tex, ucieczka znakow, szyfrowanie, kontrakt API, samowystarczalnosc
SVG. Pierwsze uruchomienie na klastrze trzeba obejrzec — dlatego PRE-24 zostaje
jako „W trakcie", nie „Zrobione".
Instrukcja wdrozenia: docs/wdrozenie-render-pdf.md (klucz, obraz, merge,
weryfikacja, znane ograniczenia).
Testy: 15 nowych (render) + 14 (lacze i wariant druku w prezentacji).
Calosc: prezentacja 131, logika 265/1 skip, render 15.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
6c9029c496 |
feat(prezentacja): zakladka „Skompiluj" — zbiorczy raport (PRE-23)
build / build (push) Successful in 52s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m16s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m57s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 32s
Testy / Kontrola składni wszystkich warstw (push) Failing after 8s
Czwarta wskazowka partnerow. Nowa zakladka sklada w jedno trzy kawalki liczone w roznych miejscach: policzony horoskop, interpretacje natalna z AI i wszystkie zapamietane predykcje okresowe. Uklad sekcji dokladnie wg prosby: imie i nazwisko -> wprowadzone dane -> RYSUNEK kosmogramu -> interpretacja natalna -> predykcje okresowe. Test pilnuje tej kolejnosci, bo to jedyna rzecz, ktora latwo przestawic przy refaktorze, a partnerzy podali ja wprost. Skad material: - HOROSKOP liczymy TU NA NOWO z danych formularza, zamiast go zapamietywac. To czysta funkcja wejscia — tanio powtorzyc, a odpada trzymanie w przegladarce duzego wyniku, ktory moglby sie rozjechac z aktualnym formularzem. - INTERPRETACJA NATALNA — nowy natal.js, odpowiednik predictions.js. Natalna jest JEDNA (dotyczy momentu urodzenia, nie okresu), wiec ponowne wygenerowanie podmienia slot zamiast dokladac wpis. - PREDYKCJE — z magazynu z PRE-22. compile.js czyta magazyny przez ICH API (window.astrololoNatal / astrololoPredictions), a nie siegajac wprost do localStorage — format danych ma jednego wlasciciela: modul, ktory je zapisuje. Test tego pilnuje. Zakladka MOWI, CZEGO BRAKUJE: panel gotowosci z trzema pozycjami i podpowiedzia, na ktorej zakladce uzupelnic. Bez tego uzytkownik zlozylby niekompletny raport i dowiedzialby sie o tym dopiero po otwarciu PDF-a. Tresc od modelu jest ESKEJPOWANA przed wstawieniem do DOM — to tekst z zewnatrz, wiec bez tego mielibysmy wektor wstrzykniecia. Weryfikacja na zywej aplikacji: dwie predykcje zapisane w Kalendarzu, natalna w Interpretacjach, obie odczytane na Skompiluj (panel: brak horoskopu na zolto, dwa pozostale na zielono). Po zlozeniu wszystkie trzy zielone, a raport zaczyna sie od „Jan Kowalski" i danych wejsciowych. Kolejnosc sekcji sprawdzona na wyrenderowanym HTML: naglowek 2931 < dane 3033 < kosmogram 3158 < natalna 26544 < predykcje 26575. Testy: 16 nowych. Poprawione tez trzy wlasne testy, ktore lapaly nazwy plikow w KOMENTARZACH zamiast w tagach skryptow. Calosc: prezentacja 117 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8cc329ab17 |
feat(prezentacja): zapamiętane predykcje okresowe (PRE-22) + wymaganie o cache-bustingu
build / build (push) Successful in 1m4s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 12m9s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 20s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m42s
Piata wskazowka partnerow: Kalendarz ma pozwalac liczyc predykcje dla KILKU okresow i je zachowywac, zeby wszystkie trafily potem do raportu („Skompiluj", PRE-23/24). Nowy predictions.js — magazyn w localStorage, tak jak wspolne dane formularza (PRE-21): serwer zostaje bezstanowy, zadne dane urodzeniowe ani tresci z baz nie laduja po stronie uslugi. Zakladka „Skompiluj" odczyta to samo miejsce przez window.astrololoPredictions (jedno zrodlo prawdy). Decyzje projektowe: - KLUCZEM TOZSAMOSCI JEST OKRES. Ponowne policzenie tego samego zakresu podmienia wpis zamiast dokladac duplikat — inaczej lista puchlaby przy kazdej probie z innym modelem albo budzetem. Dzieki temu zapis jest idempotentny, wiec dziala tez wariant bez strumienia (zapis przy wczytaniu strony z gotowym wynikiem) i odswiezenie niczego nie mnozy. - progress.js OGLASZA gotowy horoskop zdarzeniem `astrololo:horoscope` z profilem, zamiast sam zapisywac. To okno postepu, a nie magazyn — zapisywanie zostaje odpowiedzialnoscia predictions.js. Filtr po profilu pilnuje, zeby interpretacja natalna nie trafila na liste predykcji okresowych. - Przepelniony magazyn (horoskopy bywaja dlugie) jest ZGLASZANY uzytkownikowi, a nie polykany — inaczej wynik znikalby po cichu. UI: lista zapamietanych predykcji na Kalendarzu — okres, data zapisu, objetosc i przycisk usuwania. Skrypt podpiety w timeline.html (nie w base.html), zeby nie kolidowac z rownolegle otwartym #29. PRE-26 — dopisane wymaganie o wersjonowaniu plikow statycznych. Przy PRE-25 przegladarka podala STARY styles.css i powiekszanie kosmogramu „nie dzialalo", mimo ze klasa byla nakladana. Objaw jest zdradliwy: szablony sa nowe, wiec strona wyglada na zaktualizowana, a funkcja po prostu milczy. Po wdrozeniu moze to spotkac uzytkownikow. Weryfikacja na zywej aplikacji: dwa okresy zapisane; powtorzenie tego samego zakresu podmienilo wpis (dalej 2, tekst zaktualizowany); lista posortowana po dacie; predykcje przetrwaly przejscie na inna zakladke i powrot; interpretacja natalna NIE wpadla na liste; usuwanie zmniejszylo licznik 2 -> 1 i przerysowalo liste. Testy: 14 nowych. Calosc: prezentacja 101 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
76fbdefeaa |
feat(prezentacja): kliknięcie powiększa kosmogram na pełne okno (PRE-25)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m52s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m57s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 46s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 19s
build / build (push) Successful in 1m10s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m59s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m50s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 42s
Testy / Kontrola składni wszystkich warstw (push) Successful in 19s
Ósma wskazówka partnerów, jako małe QoL przed PRE-22. Koło rysujemy w kolumnie tekstu, więc na mniejszym ekranie glify i stopnie robią się nieczytelne. Kliknięcie rozciąga wykres na całe okno, ponowne wraca do strony. SVG skaluje się bez utraty jakości, więc nie potrzeba drugiej wersji rysunku ani biblioteki. Wyjście z powiększenia na trzy sposoby: klik w wykres, klik w tło, Esc. Dostępne też z klawiatury (Enter/Spacja, focus-visible), bo inaczej obejrzenie szczegółów wymagałoby myszy. Dwie decyzje warte odnotowania: 1. WARSTWA. z-index 1100 CELOWO pomiędzy: ponad kontrolkami Leafleta (1000), ale PONIŻEJ okna postępu (1200). Gdy trwa pisanie horoskopu, log operacji ma zostać na wierzchu. Test pilnuje tej nierówności, bo to jedyna liczba tutaj, którą łatwo zmienić bez zastanowienia i zepsuć coś niewidocznego na oko. 2. ROZMIAR. Koło jest kwadratowe, więc ograniczamy je KRÓTSZYM bokiem okna (min(96vw, 92vh)) — inaczej na szerokim ekranie wystawałoby w pionie. Skrypt podpięty globalnie w base.html i osłonięty sprawdzeniem, czy koło w ogóle jest na stronie — zadziała też na przyszłej zakładce „Skompiluj" bez zmian. Przy powiększeniu blokujemy przewijanie strony pod spodem. Weryfikacja na żywej aplikacji, pomiarami w DOM: po kliknięciu .wheel-fig ma position:fixed, display:flex, z-index:1100; SVG rośnie z 460×460 do 662×653 przy oknie 1280×720, visibility visible; body dostaje overflow:hidden. Ponowne kliknięcie wraca do 460×460 i zdejmuje klasę. Zrzutu ekranu stanu powiększonego NIE mam — panel przeglądarki zaciął się w trakcie (puste klatki, viewport raportowany jako 0×0), więc opieram się na pomiarach i testach. Testy: 10 nowych. Całość: prezentacja 87 passed, logika 265 / 1 skip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f34016a4a5 |
feat(prezentacja): wspolne dane formularza miedzy zakladkami + imie i nazwisko (PRE-21)
build / build (push) Successful in 58s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m4s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m53s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Trzecia wskazowka partnerow. Kazda zakladke (Horoskop / Interpretacje / Kalendarz) wypelnialo sie od nowa — te same imie, data, godzina, strefa i miejsce. Teraz raz wpisane dane wedruja za uzytkownikiem, a zmiana w jednej zakladce przenosi sie na pozostale. Nowy formsync.js trzyma stan w localStorage. Dlaczego nie sesja na serwerze: serwer zostaje BEZSTANOWY — zadnego magazynu sesji, zadnych danych urodzeniowych trzymanych po stronie uslugi (spojne z postawa z LOG-32/PRE-16). Przy okazji dane synchronizuja sie tez miedzy osobnymi kartami przegladarki, bo zdarzenie `storage` daje to za darmo. Dolozone pole „imie i nazwisko" (wszystkie trzy zakladki) — potrzebne do naglowka raportu PDF (PRE-24). Handlery przyjmuja je i oddaja, wiec nie znika po przeliczeniu. Dwie rzeczy, ktore trzeba bylo domknac, zeby to dzialalo naprawde: 1. KOLEJNOSC SKRYPTOW. formsync.js ladowany w <head> z `defer` — skrypty defer wykonuja sie w kolejnosci dokumentu, wiec ten zdazy odtworzyc wspolrzedne, ZANIM geo.js zbuduje mape. Mapa startuje od razu we wlasciwym miejscu, zamiast przeskakiwac po chwili. 2. geo.js ustawia pola z KODU (`.value = ...`), co samo z siebie NIE wywoluje zdarzen — bez tego synchronizacja przegapilaby kazdy wybor z mapy, z wyszukiwarki i z „Tu i teraz". Dolozony setVal(), ktory jawnie zglasza `change`. Zakladka bez danego pola (np. Sygnifikatory) nie kasuje wartosci zapamietanej gdzie indziej; uszkodzony wpis w localStorage nie blokuje formularza. Q-14 rozstrzygniete: lancuch LaTeX->PDF stanie jako OSOBNA USLUGA render — spojne z izolacja swisseph (LOG-27), obraz produktu zostaje maly. Weryfikacja na zywym stacku (data+logika+prezentacja) w przegladarce: dane wpisane w Horoskopie pojawily sie w Interpretacjach; zmiana godziny w Interpretacjach dotarla do Kalendarza; pola nieobecne na zakladce (zodiak, system domow) przetrwaly; po POST imie zostalo, a horoskop policzyl sie normalnie. Testy: 22 nowe strukturalne. Calosc: prezentacja 67 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5c82e8bd9f |
fix(prezentacja): offset wzgledem GMT + nazwa lokalizacji po „Tu i teraz”
Dwie pierwsze wskazowki od partnerow biznesowych; pozostale piec zapisane jako wymagania (PRE-21..PRE-24) do zrobienia w kolejnych krokach. PRE-19 — offset wzgledem GMT. Etykieta mowila „Strefa (offset h)”, czyli nie bylo jasne, wzgledem czego liczymy przesuniecie. Teraz „Offset wzgledem GMT (h)” z podpowiedzia. Krok juz byl 15-minutowy (0,25 h) — dolozony zakres −12…+14, zeby nie dalo sie wpisac strefy, ktora nie istnieje. Zmiana w trzech zakladkach, ktore maja to pole (Horoskop, Interpretacje, Kalendarz). PRE-20 — po „Tu i teraz” wspolrzedne i pineska skakaly na biezace polozenie, ale w polu tekstowym zostawala STARA, wczesniej wpisana nazwa. Formularz pokazywal jedno miejsce, a liczyl dla innego — cicha pomylka, nic sie nie wywalalo. Handler zdarzenia astrololo:coords odswieza teraz nazwe przez reverseName. Przy okazji druga strona tego samego bledu: reverseName czysci pole ZANIM wysle zapytanie. Gdyby /reverse nie odpowiedzialo (brak sieci), zostalaby stara nazwa — lepiej puste pole i poprawne wspolrzedne niz nazwa, ktora klamie. Wymagania: PRE-19/20 (zrobione), PRE-21 wspolne dane miedzy zakladkami wraz z polem imie i nazwisko, PRE-22 wiele predykcji okresowych w pamieci sesji, PRE-23 zakladka „Skompiluj”, PRE-24 raport PDF przez LaTeX. Dolozone pytanie otwarte Q-14 o lancuch LaTeX→PDF (gdzie postawic TeX Live, silnik unicode owy pod glify, konwersja SVG) — decyzja wplywa na deploy i rozmiar obrazow. Testy: 12 nowych, strukturalnych na zrodle (JS-a nie uruchomimy, a obie regresje sa ciche). Sprawdzone sabotazem — po cofnieciu kazdej poprawki czerwienieja. Calosc: prezentacja 45 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
40c9bf7988 |
feat(prezentacja): obiekty na kosmogramie — glify, stopnie, retrogradacja (PRE-12)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m57s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 38s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 27s
build / build (push) Successful in 1m4s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m46s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m54s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 33s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Etap 2 rysowania koła (po szkielecie): obiekty na swoich pozycjach. Każdy obiekt dostaje: kreske na wewnetrznej krawedzi pasa w PRAWDZIWEJ pozycji, glif, stopien w znaku i znacznik retrogradacji ℞ (dodatkowo kolorem, zeby dalo sie ja wylapac nie czytajac znak po znaku). ROZSUWANIE CIASNYCH SKUPISK — sedno tego etapu. W horoskopie referencyjnym Merkury i Wenus dzieli 0,41°, Wenus i Ksiezyc 3,68°: bez rozsuwania glify rysuja sie jeden na drugim. Rozsuwamy tylko GLIFY; kreska zostaje w prawdziwej pozycji, a gdy glif jest odsuniety, laczymy je cienka linia odniesienia — wykres nie moze klamac o tym, gdzie planeta faktycznie stoi. Bledy zlapane przy weryfikacji (oba wyszly z pomiarow, nie z „wyglada dobrze"): 1. PODPISY STOPNI zlewaly sie w skupiskach. O ciasnocie decyduje nie glif, tylko podpis — lezy blizej srodka (r=130), gdzie ten sam kat to mniej pikseli. Stad odstep 8° zamiast 7°, podpis bez „°" (jak w programach astrologicznych) i mniejszy font. Teraz: glify min 20,9 px, podpisy 18,1 px (prog 16). 2. ROZSUWANIE NIE DZIALALO na prawdziwych danych — Wenus ladowala DOKLADNIE na Ksiezycu (0,3 px). Przyczyna: odstep liczony modulo 360. Przesuniecie, ktore przerzucalo obiekt ZA sasiada, dawalo luke ~359,9° zamiast ujemnej, wiec algorytm uznawal, ze jest luzem, i konczyl. Poprawka: rozwijamy katy do osi MONOTONICZNEJ, gdzie ujemna luka zostaje ujemna i zawsze sie ja wylapie. Test regresyjny na dokladnie tych danych; sprawdzony sabotazem (po przywroceniu modulo czerwienieje). Etykiety osi (AC/DC/MC/IC) przeniesione POZA kolo — w srodku wchodzily w pierscien obiektow i zaslanialy glify (Ksiezyc znikal pod linia MC). ViewBox 440→470, kolo bez zmian, margines mieści etykiety. Testy: 11 nowych (regresja rozsuwania, zachowanie kolejnosci, obiekty bez kolizji nieruszone, zawiniecie przez 0°, awaryjny rowny rozklad, stopien w znaku, retrogradacja, niekompletny obiekt nie wywala rysunku). Calosc: prezentacja 44, logika 265 / 1 skip. Potwierdzone wizualnie: cale skupisko Slonce/Ksiezyc/Wenus/ Merkury czytelne i rozdzielone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
1d7f3e2136 |
feat(prezentacja): szkielet kosmogramu — koło horoskopowe SVG (PRE-12)
build / build (push) Successful in 1m26s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m10s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 38s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Pierwszy krok rysowania wykresu (PRE-12): SZKIELET koła — pierścień znaków, podział na domy i osie. Planety i linie aspektów w kolejnych iteracjach. Rysowane po stronie serwera jako czysty string SVG (bez zależności zewnętrznych — spójne z CSP). Ciemny motyw, spójny z paletą aplikacji (kolory z --line, --accent, --muted; glify znaków barwione wg żywiołu w stonowanych kolorach czytelnych na ciemnym tle). Geometria wg konwencji astrologicznej: Ascendent po LEWEJ, długość ekliptyczna rośnie przeciwnie do ruchu wskazówek zegara. Punkt λ → kąt φ = 180° − (λ − Asc); w SVG y rośnie w dół, co formuła uwzględnia. Zakotwiczenie sprawdzone testami liczbowo: Asc po lewej, Dsc po prawej, oś pozioma; Asc+90° (II dom) na dole. Elementy: dwa okręgi + piasta, podziałki co 5°/10°, granice znaków co 30° z glifem w środku sektora, szprychy domów od pasa do piasty, numery domów w środku każdego domu, osie Asc–Dsc i MC–IC wyróżnione akcentem z etykietami AC/DC/MC/IC. Dane bierzemy WYŁĄCZNIE z wyniku /chart/positions — prezentacja nic nie liczy: - `sign_glyphs` (pierścień 12 znaków) i glify — z LOG-22, - `angles` z długością `decimal` — już były, - `cusps` z `decimal` — DOŁOŻONE w tym PR (jedna linia w build_chart). Bez tego domy dało się narysować tylko dla whole sign; z długością cuspu działa dla KAŻDEGO systemu. Zweryfikowane na porphyry: cuspy poza wielokrotnościami 30°, szprychy odchodzą od granic znaków. Degradacja: silnik bez osi/domów albo starszy wynik bez `decimal` w cuspach → brak koła (pusty string), nie wyjątek. Testy: 8 (poprawność XML, 12 glifów, 4 osie, numery domów, Asc po lewej liczbowo, CCW, degradacja). Całość: prezentacja 33 passed, logika 265 / 1 skipped. Render potwierdzony wizualnie na horoskopie referencyjnym (AC=Leo po lewej, MC=Aries u góry, domy CCW). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
ace76183e5 |
feat(logic): glify astrologiczne — konwersja tekst↔symbol (LOG-22)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m55s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m43s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 37s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 21s
build / build (push) Successful in 1m22s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m12s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m39s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 33s
Testy / Kontrola składni wszystkich warstw (push) Successful in 24s
Warunek wstępny pod kosmogram (PRE-12): planety i znaki na kole rysujemy symbolami. Nowy moduł engine/glyphs.py: - forward: nazwa → glif (planety, punkty, Loty, znaki, aspekty, retro ℞), - reverse: glif → nazwa (znosi obecność/brak selektora wariantu), - glyphify(): tokeny [XX z bazy → glify; przyklad z wymagan „[Sa [Pis 26°08' [conj [PF" → „♄ ♓ 26°08' ☌ ⊗" (stopnie nietkniete). DAN-18 „tylko tekst, nigdy emoji" potraktowane serio, TRZEMA warstwami — bo sam selektor NIE wystarcza (potwierdzone wizualnie w przegladarce): 1. w danych: selektor wariantu tekstowego U+FE0E na znakach zodiaku oraz ♀/♂ (maja wariant emoji); ☉ i reszta go nie dostaja (zbedny), 2. CSS font-variant-emoji:text, 3. CSS font-family celujacy w MONOCHROMATYCZNE fonty symboli PRZED emoji. Bez pkt. 3 macOS/Chromium i tak renderowal znaki ♈–♓ jako kolorowe kafelki Apple Color Emoji mimo VS15 — planety wychodzily tekstem, znaki nie. Stack „Apple Symbols / Segoe UI Symbol / Noto Sans Symbols2" naprawia render. NIGDZIE nie emitujemy U+FE0F (emoji) — pilnuje tego test. Wpiete w build_chart: kazda pozycja dostaje glyph (planeta) + sign_glyph (znak, zalezny od zodiaku, wiec po przesunieciu), osie i Loty tak samo (Fortuna ⊗, reszta Lotow bez standardowego symbolu → None), aspekty dostaja glif, result[„sign_glyphs"] to pierscien 12 znakow pod kolo. UI: kolumna „Sym." w tabeli pozycji (planeta + znak) i symbol przy aspekcie. Testy: 14 (kompletnosc — kazdy obiekt/znak/aspekt ma glif; dwukierunkowosc; DAN-18 brak FE0F, znaki maja VS15, ☉ nie; przyklad glyphify z wymagan). Calosc: logika 265 passed / 1 skipped, prezentacja 25. Render znakow potwierdzony wizualnie (czarno-biale symbole, nie emoji). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f1956a08ff |
feat(logic): aspekty pozazodiakalne — antyscja i paralele deklinacji (LOG-07)
build / build (push) Successful in 1m1s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m57s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m33s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 28s
Testy / Kontrola składni wszystkich warstw (push) Successful in 24s
Aspekty głowne (LOG-06) mierzą kąt wzdłuż ekliptyki. LOG-07 dokłada dwa rodzaje powiązań, które klasyczna astrologia liczy naprawdę, nie na oko: - PARALELA/KONTRPARALELA DEKLINACJI — dwa ciała na tej samej („parallel") lub przeciwnej („contraparallel") deklinacji działają jak koniunkcja/opozycja, mimo że wzdłuż ekliptyki mogą stać gdziekolwiek. Deklinacja liczona PEŁNYM wzorem (z szerokością ekliptyczną — istotne dla Księżyca i planet schodzących z ekliptyki), przez to_equatorial z LOG-04. Orb konfigurowalny (domyślnie 1°, ciasno — to kontakty punktowe). - ANTYSCJA/KONTRANTYSCJA — odbicie długości względem osi przesileń (0° Raka – 0° Koziorożca) albo równonocy (0° Barana – 0° Wagi). Liczone na współrzędnych TROPIKALNYCH of-date, bo deklinacja jest fizyczna (równikowa, niezależna od zodiaku), a antyscja z definicji tropikalna — jej oś to kardynalne punkty zodiaku tropikalnego. Dlatego PRZED przesunięciem na zodiak syderyczny/draconiczny. Dodatkowo: flaga „out of bounds" (|deklinacja| > nachylenie ekliptyki — ciało poza zakresem Słońca) i kolumna deklinacji przy każdej pozycji. Integracja z bazą: baza interpretacyjna ZNA paralele pod frazą „P. Dec.", więc generujemy fasetkę paraleli (trafia też do promptu LLM). PUŁAPKA: samo „Dec." w bazie to często DEKANAT („3rd Dec. of [Gem"), więc szukamy dokładnie „P. Dec." — inaczej sypnęłoby fałszywymi trafieniami. Kontrparaleli i antyscji baza nie opisuje osobnym znacznikiem, więc zostają obliczeniem display-only. Pary z RIGID_PAIRS (węzły) odsiane: SN = NN+180° na ekliptyce → deklinacja ZAWSZE przeciwna, czyli definicyjna kontrparalela bez informacji. Walidacja wobec faktów NIEZALEŻNYCH od kodu: - deklinacja Słońca 30.04.1984 = +14.88° wobec ~+14.9° z almanachu, - antyscja to arytmetyka odbicia: inwolucja i pary znaków (Rak↔Bliźnięta, Baran↔Panna) sprawdzone na piechotę, - węzły faktycznie mają przeciwną deklinację i są odsiane, - deklinacja niezależna od zodiaku (tropikalny == syderyczny co do 1e-6°), - realna baza: mechanizm paraleli znajduje wpisy „P. Dec." i odsiewa dekanaty (z 33 wpisów „P. Dec." 5 ma niepusty efekt — głównie „[conj or P. Dec."). UI: kolumna deklinacji (+znacznik OOB), tabela paraleli/kontrparaleli i tabela antyscji na ekranie Horoskop. Testy: 15 nowych (out_of_zodiac) + 2 (fasetka paraleli vs pułapka dekanatu). Całość: logika 251 passed / 1 skipped, prezentacja 25 passed. Render szablonu sprawdzony osobno (bez błędu Jinja, wszystkie sekcje obecne). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e8f868e907 |
docs(wymagania): realne statusy + kosmogram jako feature prezentacji
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m56s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 31s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 22s
build / build (push) Successful in 44s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m59s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m33s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 31s
Testy / Kontrola składni wszystkich warstw (push) Successful in 18s
Kolumna Status stała na „Do przeglądu" dla wszystkiego (poza LOG-32), mimo że
kilkadziesiąt rzeczy działa w produkcji — arkusz przestał odzwierciedlać stan
projektu. Słownik statusów pochodził z fazy PRZED kodowaniem („Do przeglądu ·
Zaakceptowane · Odrzucone · W trakcie"); dodaję fazę realizacji: Zrobione ·
W trakcie · Do zrobienia.
Statusy ustawione na podstawie FAKTYCZNIE zmergeowanego kodu, nie na oko —
wątpliwe zweryfikowane w źródłach (np. LOG-13 „ascensional" okazało się tylko
„right ascension" w komentarzu; PRE-06 „Orb" to nagłówek kolumny, nie ustawienie).
Bilans: Zrobione 43 · W trakcie 8 · Do zrobienia 26.
- Logika: 26 / 4 / 3 (brakuje m.in. LOG-09 primary directions, LOG-13
ascensional, LOG-22 glify; LOG-11 ZR/Decennials i LOG-17 asp+/- w trakcie),
- Prezentacja: 7 / 2 / 9,
- Dane: 10 / 2 / 14 (dużo tabel źródłowych jeszcze niepodpiętych).
Kosmogram (PRE-12): program od początku miał rysować koło horoskopowe — umknęło.
Podnoszę z „Could/opcjonalnie" na „Should", rozpisuję zakres (SVG po stronie
serwera: znaki, domy, planety z glifami, osie, linie aspektów; docelowo znaczniki
deklinacji/antyscji z LOG-07; zależność od glifów LOG-22) i oznaczam „Do zrobienia"
jako fokus najbliższych iteracji.
Nowy PRE-18: grafika aspektów (aspectarian) i wizualizacje pochodne horoskopu —
naturalny towarzysz kosmogramu.
Przegląd: zaktualizowana legenda statusów, licznik Prezentacji 17→18, dodana
tabela postępu realizacji per warstwa.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
56fdf01d7d |
feat(bezpieczenstwo): szyfrowanie lacz miedzy warstwami AES-256-GCM (PRE-16)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m45s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m31s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 31s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 15s
build / build (push) Successful in 4m15s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m41s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m36s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 33s
Testy / Kontrola składni wszystkich warstw (push) Successful in 15s
Warstwy rozmawialy ze soba jawnym tekstem wewnatrz klastra. Token miedzywarstwowy (LOG-32) mowil KTO pyta, ale nie ukrywal CZEGO dotyczy odpowiedz — a plyna nia surowe wiersze oryginalnych baz interpretacyjnych, czyli rdzen produktu. Kto podsluchal ruch wewnatrz sieci (drugi pod, mirror portu na switchu, zrzut z wezla), mial je w calosci. Nowy modul link_crypto (kopia w kazdej z trzech uslug — nie maja wspolnej biblioteki; test pilnuje, ze kopie sa identyczne): - AES-256-GCM na ciele kazdego zadania i odpowiedzi. GCM daje poufnosc I uwierzytelnienie naraz, wiec nie ma wariantu „zaszyfrowane, ale podatne na modyfikacje". - DWA niezalezne klucze, po jednym na pare rozmowcow (prezentacja-logika, logika-dane). Przejecie klucza prezentacji nie otwiera warstwy danych, gdzie leza cale bazy. Z kazdego klucza lacza HKDF wyprowadza osobne podklucze na kierunek, wiec zadanie i odpowiedz nigdy nie szyfruja sie tym samym kluczem. - Do materialu uwierzytelnianego (AAD) wchodza kierunek, sciezka, znacznik czasu i numer ramki — wiec ramki nie da sie przekleic na inny endpoint, odtworzyc po czasie (okno MAX_SKEW) ani przestawic w strumieniu. - Strona serwerowa to czyste ASGI: podmienia cialo zanim zobaczy je FastAPI i przepuszcza odpowiedz strumieniowa kawalek po kawalku (okno postepu dziala dalej). Fail-closed: przy ustawionym kluczu jawne zadanie dostaje odmowe. Strumien postepu (okno pisania horoskopu) tez idzie przez szyfrowane lacze: link_crypto.stream_lines() pieczetuje zadanie i odszyfrowuje odpowiedz ramka po ramce (granice ramek != granice linii NDJSON), zachowujac dostarczanie na zywo. Bez tego przy wlaczonym LINK_ENCRYPTION_REQUIRED serwer odrzucalby strumien (400) i okno postepu przestaloby dzialac. Fail-closed obejmuje takze strumien: klient bez klucza nie wysyla nic, zamiast puscic dane urodzenia jawnym tekstem, zanim serwer zdazy odmowic. Najgrozniejszy blad wyszedl z PODSLUCHU prawdziwego gniazda, nie z testow: klient bez klucza wysylal pytanie jawnym tekstem, ZANIM serwer zdazyl odmowic. Stad LINK_ENCRYPTION_REQUIRED: klient nie wysyla niczego, a usluga nie wstaje, jesli klucza brak. Ta sama zasada co przy sekrecie logowania. Klient prezentacji przepuszczony przez jeden punkt _post()/stream_lines: dopoki kazda metoda skladala zadanie sama, dolozenie nowej znaczylo, ze latwo zapomniec o tokenie albo kluczu (401 wyszedl juz raz dopiero na produkcji). Test strukturalny: kazde wyjscie w dol musi miec i token, i klucz lacza (takze strumien), a surowe httpx wolno tylko na sciezkach wyjetych spod szyfrowania. Weryfikacja: - testy link_crypto (round-trip, brak tresci baz w bajtach na sieci, odrzucenie obcego klucza / przestawionego bitu / przekleconej sciezki / przestawionej ramki / przeterminowanej koperty / urwanego strumienia; round-trip strumienia i fail-closed klienta i serwera dla strumienia), - e2e na prawdziwym uvicornie z proxy zrzucajacym gniazdo: tresci baz brak na kablu w obie strony (grep=0), takze dla strumienia horoskopu; klucz jednej pary nie otwiera drugiej, - calosc: logika 234 passed / 1 skipped, prezentacja 25 passed. docs/wdrozenie-pre16.md: instrukcja krok po kroku z uzasadnieniem kolejnosci. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
23416cb1f9 |
fix(prezentacja): limit zadan po adresie klienta, nie proxy (PRE-16)
Po wlaczeniu TLS aplikacja stanie za Ingressem, a wtedy `request.client.host` to adres POD-a Traefika — jednakowy dla wszystkich. Limiter wrzucalby caly ruch do jednego wiadra 120/min i pierwsza osoba, ktora go wyklika, odcielaby pozostalych. Cicha regresja, ktora ujawnilaby sie dopiero na produkcji. Nowe `client_ip()` czyta adres z naglowka, ale WYLACZNIE przy TRUST_PROXY — bo inaczej wystarczyloby dopisywac wlasny X-Forwarded-For, zeby przy kazdym zadaniu wygladac na kogos innego i ominac limit calkowicie. Z tego samego powodu bierzemy OSTATNI wpis listy: to jedyny, ktory dopisal nasz proxy; wczesniejsze mogl podstawic klient, wiec nie znacza nic. Szesc testow, w tym dwa istotne: - podszycie sie pod X-Forwarded-For NIE resetuje wiadra przy wylaczonym TRUST_PROXY (inaczej baze dalo by sie pompowac bez ograniczen), - za proxy dwa rozne adresy dostaja osobne wiadra i nie odcinaja sie nawzajem. Oba sprawdzone celowym zepsuciem implementacji (zawsze ufaj naglowkowi + bierz pierwszy wpis) — testy wtedy czerwienieja. 23 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
473d059a6a |
feat(logic): tabele pomocnicze horoskopu (LOG-23)
build / build (push) Successful in 1m8s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m2s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m43s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 34s
Testy / Kontrola składni wszystkich warstw (push) Successful in 22s
Komplet wyliczen, ktore astrolog czyta „obok" pozycji: - bilans zywiolow i jakosci w czterech wariantach (7 klasycznych / 10 z nowozytnymi, z Ascendentem i bez) + wykrywanie BRAKUJACYCH zywiolow — klasyczne „no air", podstawa pod scoring sily (LOG-21), - faza Ksiezyca: elongacja, nazwa fazy, procent oswietlenia, przybywa/ubywa, - stopnie krytyczne wg jakosci znaku (kardynalne 0/13/26, stale 8/21, zmienne 4/17) + 29 stopien anaretyczny i 0 stopni wejscia w znak, - dzien i godziny planetarne w porzadku chaldejskim, - syzygia prenatalna (ostatni now albo pelnia przed urodzeniem), - podzialy: dwunastniki (D12) i nawamsa (D9). Dwie rzeczy wymagaly prawdziwego liczenia, nie tabelki: * godziny planetarne sa NIEROWNE — dzien od wschodu do zachodu dzieli sie na 12, noc osobno. Bez faktycznego wschodu/zachodu wynik bylby zmyslony, wiec szukamy ich numerycznie (przejscie wysokosci Slonca przez -0°50', bisekcja jak przy stacjach z LOG-03). Doba planetarna startuje o WSCHODZIE, nie o polnocy. * syzygia prenatalna — szukanie wstecz przejscia elongacji przez 0/180 stopni. Walidacja wobec faktow NIEZALEZNYCH od naszego kodu: - 30.04.1984 to poniedzialek -> wladca dnia Ksiezyc; 5. godzina poniedzialku w porzadku chaldejskim to Slonce (Mo, Sa, Ju, Ma, Su) — zgadza sie, - wschod/zachod dla Krakowa: 03:18 / 17:57 UTC = 5:18 / 19:57 lokalnie — zgodne z rzeczywistoscia dla konca kwietnia, - syzygia: pelnia 15.04.1984 19:10:45 UTC; rzeczywista byla 19:11 — roznica ponizej minuty, - bilans przeliczony recznie: Ogien 4, Ziemia 4, Woda 3, Powietrze 0. UI: checkbox „tabele dodatkowe" na ekranie Horoskop (opt-in, bo szuka numerycznie) i sekcja wynikow. Endpoint: /chart/positions?tables=true. Testy: 28 nowych (w tym noc polarna -> brak godzin planetarnych, oraz sprawdzenie, ze w znalezionej syzygii elongacja FAKTYCZNIE wynosi 0/180). Calosc: 202 passed / 1 skipped + 17 (prezentacja). Zweryfikowane e2e w UI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
929b691238 |
fix(ui): okno postepu nad mapa, nie pod nia
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m48s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 10m1s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 42s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 32s
build / build (push) Successful in 1m16s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m54s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m55s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 39s
Testy / Kontrola składni wszystkich warstw (push) Successful in 23s
Modal postepu przy pisaniu horoskopu renderowal sie POD kontrolkami mapy — przyciski zoomu i atrybucja OSM przebijaly przez zaciemnione tlo okna. Przyczyna: Leaflet trzyma kontrolki (.leaflet-top/.leaflet-bottom) na z-index:1000, a .leaflet-container NIE tworzy wlasnego kontekstu stackowania (position:relative bez z-index), wiec te 1000 trafia wprost do korzenia. Zaden przodek mapy (form, .geo, .geo-map, .wrap) tez kontekstu nie tworzy. Okno postepu mialo z-index:50 — czyli ladowalo pod mapa. Poprawka: z-index okna 50 -> 1200 (zapas nad 1000). Jedna wartosc. Zweryfikowane w przegladarce na PRAWDZIWYCH arkuszach (leaflet.css + styles.css): - runtime elementFromPoint w punkcie kontrolek zoomu: przed = element mapy na wierzchu („MAPA PRZYKRYWA MODAL"), po = overlay na wierzchu („MODAL NA WIERZCHU"), - wizualnie: kontrolki zoomu i © OSM przed poprawka jasne na wierzchu, po — przygaszone pod modalem. Niezalezne od PRE-16 (nie rusza styles.css) — mozna zmergeowac przed nim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
114b7eebdf |
feat(ui): okno postepu z logiem podczas pisania horoskopu
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 11m21s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m50s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 34s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 21s
build / build (push) Successful in 1m49s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m20s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 10m0s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 37s
Testy / Kontrola składni wszystkich warstw (push) Successful in 25s
Generowanie trwa minutami, a zwykly POST nie dawal zadnego sygnalu — aplikacja wygladala na zawieszona. Teraz w trakcie pracy pojawia sie okno z logiem, zegarem i spinnerem. Log pokazuje RZECZYWISTE zdarzenia z serwera, nie udawany pasek postepu: - app/progress.py — strumien NDJSON; praca leci w watku roboczym, generator odpompowuje kolejke, wiec zdarzenia docz w TRAKCIE pracy, nie na koncu; heartbeat co 10s, zeby proxy nie uznalo polaczenia za martwe, - providers.generate(..., on_event) — raportuje kazda ture (start, czas trwania, liczba znakow, czy urwana), bo to tura trwa, - POST /chart/horoscope/stream w logice + proxy /horoscope/stream w prezentacji. Wynik: ostatnie zdarzenie niesie GOTOWY HTML wyrenderowany z tego samego szablonu, ktory renderuje przeladowanie strony (_prompt_result.html wydzielony z _prompt_block.html). Jedno zrodlo prawdy dla wygladu wyniku — okno wstawia go bez przeladowania. Degradacja: bez strumieniowania w przegladarce formularz idzie klasycznie i wszystko dziala jak wczesniej, tylko bez okna. Blad polaczenia konczy sie komunikatem w logu, nie cisza. BLAD ZNALEZIONY PRZY TESCIE NA ZYWO: petla kontynuacji odejmowala od budzetu ZAMOWIONY limit tury zamiast tokenow faktycznie wyprodukowanych — pierwsza tura zjadala caly budzet, wiec urwana odpowiedz nigdy nie doczekala sie dokonczenia i wracala do uzytkownika jako calosc. Naprawione i pokryte testem regresyjnym. Testy: 176 passed / 1 skipped (logika) + 17 (prezentacja). Zweryfikowane na zywo z wolna atrapa modelu: zdarzenia z poprawnymi czasami, okno z 11 liniami logu, wynik wstawiony bez przeladowania strony. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |