5 Commits

Author SHA1 Message Date
gitea 10970c579f astroklient: warstwa pośrednia — pełne astro, bez generowania i administracji (4/5)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m19s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m26s
Testy / Testy astrodemo (pull_request) Failing after 0s
Testy / Testy astroklient (pull_request) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 7s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 5s
build / build (push) Successful in 19s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m25s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m26s
Testy / Testy astrodemo (push) Failing after 0s
Testy / Testy astroklient (push) Successful in 9m29s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 7s
Testy / Kontrola składni wszystkich warstw (push) Successful in 5s
Trzeci produkt drabiny: astrodemo (dwie funkcje) → astroklient → astrololo.
Po trzech poprzednich krokach jest cienki, bo jest ZŁOŻENIEM, a nie kopią:
własne main.py z ośmioma importami, a rdzeń — ekrany, szablony, zasoby — bierze
z warstwy prezentacji przy budowaniu obrazu. Jedno źródło, dwa produkty; inaczej
te same 2500 linii szablonów żyłyby w dwóch egzemplarzach i rozjechały się
w ciągu tygodni, po cichu.

CO MA: Horoskop, Interpretacje, Kalendarz, Synastria, Sygnifikatory, wgrywanie
plików. Wyszukiwarka miejsca i strefa czasowa zgodnie z ustaleniem.

CZEGO NIE MA I DLACZEGO NIE DA SIĘ WŁĄCZYĆ: plików usuniętych wg usun.txt nie ma
w obrazie. Nie istnieje uprawnienie, którym dałoby się je odsłonić, bo katalog
funkcji składa się ze ZGŁOSZEŃ ekranów obecnych w obrazie. To dlatego „każde
konto dostaje wszystko, co ta usługa umie" jest tu bezpieczne i nie wymaga
wypisywania listy: zbiór liczy się z katalogu, więc opisuje ten produkt.

KONTA jak w astrodemo: z konfiguracji środowiska (ASTROKLIENT_USERS), jeden
poziom dostępu, bez pliku kont i bez ekranu ich zakładania. Konta rozdziela się
po to, żeby każde miało własną pulę plików.

PULE PER KONTO — tu była realna dziura. Warstwa logiczna przenosiła pulę tylko
przy raporcie i operacjach na plikach, więc Kalendarz i Sygnifikatory czytałyby
CAŁY udział: jedno konto widziałoby pliki drugiego, mimo obietnicy izolacji.
Domknięte: TimelineRequest i QueryRequest niosą teraz pulę, a QueryService buduje
klienta danych na żądanie.

Pula jedzie w każdym żądaniu w dół i bierze się z kontekstu ustawianego przy
wejściu, nigdy z formularza. Test podstawia `tenant=ktos-inny` w POST i sprawdza,
że w dół poszedł login zalogowanego.

WARSTWA WSPÓLNA ROZDZIELONA OD POJĘCIA ADMINISTRATORA. base.html miał wpisany na
sztywno warunek `can(request, 'admin')` i odsyłacz do ekranu kont — czyli
w produkcie bez tego ekranu zostawał martwy link i nazwa czegoś, czego nie ma.
Rejestr niesie teraz wymagane uprawnienie, a szablon dostaje gotową listę.
Podstawa przestała też importować moduły służące jednemu ekranowi (konta, stany
plików), bo produkt bez tego ekranu wlókł ich zależności.

ZAPORA SŁOWNIKOWA NAD REALNYM DRZEWEM. Test buduje złożenie tak samo jak
Dockerfile i szuka słów o funkcjach, których nie ma — w odpowiedziach ORAZ
w plikach. Pierwsza wersja znalazła dziesięć trafień, w tym trzy moje własne
docstringi WYLICZAJĄCE nieobecne funkcje: zdanie „nie ma tu generowania tekstu"
mówi wprost, że coś takiego istnieje, więc jest takim samym śladem jak przycisk.
Po poprawkach: zero. Test ma kontrolę negatywną — podrzucony plik ma go wywrócić.

usun.txt jest DANYMI, nie tekstem w Dockerfile: czyta go też test pilnujący, żeby
zgadzał się ze złożeniem w main.py. Rozjazd znaczyłby albo martwy kod w obrazie,
albo błąd dopiero przy uruchomieniu.

CI: astroklient buduje się z KORZENIA repozytorium (jego Dockerfile sięga po
rdzeń), a zmiana w warstwie prezentacji też go przebudowuje — bez tego jego obraz
zostawałby ze starymi ekranami, a różnicy nie byłoby widać do zgłoszenia
użytkownika.

Testy: astroklient 12, presentation 368, astrodemo 28, logic 342, data 42,
render 41.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 20:40:38 +02:00
gitea 320a0ab24e PRE-27: pełne ukrycie niedostępnych funkcji (paranoja)
build-render / build (push) Failing after 8s
build-swisseph / build (push) Successful in 9s
build / build (push) Successful in 8s
Testy / Testy warstwy logicznej (silnik) (push) Failing after 5s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Failing after 4s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Failing after 4s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 6s
Testy / Kontrola składni wszystkich warstw (push) Failing after 4s
Ukrywanie jest teraz nadrzędne wobec wygody i czytelności komunikatów.
Persona: konto z uprawnieniami files + files_input, zatrudnione wyłącznie do
wgrywania plików. Nie ma się dowiedzieć, po co je wgrywa ani co program będzie
robił — bo to rozgada.

Audyt sześciu kanałów wycieku (statyki, HTML, sondowanie HTTP, ekran plików,
odpowiedzi JSON i błędy, pozostałe warstwy) potwierdził 26 wycieków, każdy
odtworzony uruchomionym kodem i zweryfikowany adwersarialnie. Ani jeden nie był
przyciskiem.

ZASÓB JEST CZĘŚCIĄ FUNKCJI
/static/ omijało CAŁĄ bramkę (PUBLIC_PREFIXES), więc każdy skrypt i arkusz
pobierał ktokolwiek, także niezalogowany, pod zgadywalnym adresem — a ich treść
wymienia ekrany, dostawców modeli i przeznaczenie plików. Ruch ten nie trafiał
przy tym ani do dziennika, ani pod limit żądań, więc wyciek był niewidoczny.
Zasoby idą teraz trasą z bramką; każdy ma w features.STATIC uprawnienie swojego
ekranu. Publiczny został jeden base.css, bo potrzebuje go ekran logowania.

KOMENTARZ NIE JEDZIE NA DRUT
Komentarze w CSS/JS opisywały funkcje pełnymi zdaniami po polsku — łącznie
z „Wstrzymane widzi tylko administrator", czyli i mechanizmem kwarantanny,
i istnieniem konta o wyższych uprawnieniach. _asset_body() usuwa je przy
serwowaniu; w repozytorium zostają.

styles.css rozbity na base.css + arkusz na ekran + x-ai.css. Jeden plik z
wszystkimi selektorami był spisem treści programu. Podział zrobiony
mechanicznie, z osobnym sprawdzeniem, że żaden ekran nie stracił reguły.

base.html ładował skrypty kosmogramu na KAŻDEJ stronie — konto mające wyłącznie
Pliki pobierało je przy wejściu na swój jedyny ekran, razem ze wzmianką
o „przyszłej zakładce". Teraz dokłada je ekran, który ich używa.

RÓŻNICA JEST INFORMACJĄ
Komunikat po wgraniu pliku różnił się zależnie od wyniku walidacji — czyli był
wyrocznią do odgadywania reguł, które ma znać tylko administrator — i mówił
wprost, że plik „musi zatwierdzić administrator". Teraz jest jeden, ten sam.

_logic_error wypisywał na ekran nazwę trasy, nazwę podsystemu, nazwę gałęzi
rozwojowej i wewnętrzny host:port. Jedno zdanie dla wszystkich awarii, szczegóły
do dziennika. Odsiew w jednym punkcie, nie w siedemnastu wywołaniach.

Ponadto: stopka nie ogłasza architektury, /health nie nazywa warstwy, konto bez
ekranów dostaje 404 zamiast tłumaczenia, ekran plików mówi o plikach zamiast
o „bazach interpretacyjnych", klasy .house-warning i .account-card przemianowane
na neutralne, a logic/data/render/engine-swisseph nie wystawiają już /docs ani
/openapi.json i nie publikują portów na hoście.

ZAPORA SŁOWNIKOWA
test_slownik_zakazany.py nie sprawdza miejsc, tylko przechodzi wszystko, co dane
konto może pobrać, i szuka słów, które nie mają prawa paść (87 pozycji dla tej
persony). Nazwy funkcji, adresy ekranów i nazwy zasobów biorą się wprost
z katalogu, więc nowa funkcja obejmuje się sama. Kontrola pozytywna pilnuje, żeby
test nie przechodził dlatego, że program jest pusty.

Sprawdzone: zapora puszczona na treść sprzed poprawek daje 16 trafień na samym
styles.css i łapie każdy ze zneutralizowanych komunikatów. 358 testów zielonych,
ekrany obejrzane w przeglądarce.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 17:54:03 +02:00
gitea 8b6ecc727d feat(domy): przypisanie do domu przez wyrocznię + poprawki układu strony
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m44s
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 20s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
build / build (push) Successful in 23s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m38s
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 17s
Testy / Kontrola składni wszystkich warstw (push) Successful in 9s
ETAP 5, część pierwsza: assign_house pod wyrocznią (swe_house_pos).
Osobny rodzaj błędu niż same cuspy — i od razu jeden znalazł.

BŁĄD: assign_house szło ZAWSZE do przodu. Przy dużych szerokościach systemy
dzielące koła wielkie mają kolejność domów ODWRÓCONĄ (przy φ=−84,3° cusp domu I
wypada na 174,2°, a domu II na 165,3°) — co nie jest usterką, bo wyrocznia zwraca
dokładnie te same wartości. Suma przeskoków „do przodu" wychodziła 3960° zamiast
360°, czyli każdy krok obchodził koło dookoła. Planety lądowały w złych domach
dla regiomontanusa, campanusa i topocentrica: 9,7-12,5% przypadków. Błąd cichy —
wykres wyglądał bez zarzutu. Kierunek bierzemy teraz z samych cuspów.

TOPOCENTRIC MA JEDNAK GRANICĘ DZIEDZINY — korekta tego, co pisałem wcześniej.
Cuspy są poprawne wszędzie (zgodne z wyrocznią co do zera), ale powyżej koła
podbiegunowego przestają DZIELIĆ OKRĄG: cusp VII (= I + 180°) wypada przed
cuspem VI i domy nachodzą na siebie. Przypisanie planety traci wtedy sens —
co potwierdza sama wyrocznia, której swe_house_pos przeczy tam własnym cuspom
(100% zgodności do 62°, 83,9% przy 66°, ok. 50% przy 72°; regiomontanus 100%
w tych samych punktach). Odmawiamy, z jawnym fallbackiem jak Placidus i Koch.

Próg jest WYPROWADZONY z warunku „dwanaście cuspów sumuje się do 360°", nie
dobrany pod wynik testu — i wypada na kole podbiegunowym (zmierzone: 100%
podziałów do 65°, 78% w pasie 66-67°). To inny rodzaj granicy niż u Placidusa
i Kocha: tam nie istnieją same cuspy, tu istnieją, tylko nie tworzą podziału.

Framework dostał pojęcie dziedziny WĘŻSZEJ niż wyroczni (NARROWER_THAN_ORACLE),
zamiast wyjątku „bo topocentric": skoro wyrocznia przeczy sama sobie, nie może
rozstrzygać, więc tam nie porównujemy — a nasze przypisanie jest w tym obszarze
sprawdzane testem samospójności z cuspami, bez swissepha.

UKŁAD STRONY — zmierzony na żywej stronie, nie na oko:
- tabela porównania przy 13 systemach miała 14 kolumn i 1863 px, a stała
  w rodzicu bez overflow-x, więc ROZPYCHAŁA CAŁY DOKUMENT: 1713 px przy oknie
  1280 px, poziomy pasek na body. Teraz ma własny kontener przewijany
  (dokument 1265 px, nie przewija się), a numer domu jest przyklejony do lewej,
  bo inaczej po przewinięciu nie wiadomo, który to wiersz.
- przypis „* nie działa za kołem podbiegunowym" siedział WEWNĄTRZ <label>
  selektora, łamał się na dwie linie i rozciągał wiersz siatki ze 66 do 108 px,
  rozjeżdżając go z sąsiednim polem. Wyjaśnienie stoi teraz raz, przy
  checkboxach z gwiazdkami; wiersz wrócił do 66 px.
- 13 checkboxów na flexie zawijało się w poszarpane wiersze — jest siatka
  o stałej szerokości kolumny (auto-fill, więc na wąskim ekranie kolumn mniej).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 13:55:13 +02:00
gitea 7266f671a4 feat(domy): Placidus i Koch + jawny fallback poza kołem podbiegunowym
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 17s
Testy / Kontrola składni wszystkich warstw (push) Successful in 8s
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m28s
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 18s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 8s
Etap 2: dwa systemy łuku dobowego — jedyne, które mają miejsca, gdzie po prostu
NIE ISTNIEJĄ. Koch zgadza się z wyrocznią co do zera; Placidus do 1,7e-6°, przy
czym to próg zbieżności WYROCZNI, nie nasz: nasze cuspy spełniają definicję
Placidusa z dokładnością 1e-12° (osobny test, działa bez swissepha).

Placidus jako jedyny nie ma wzoru zamkniętego — cusp jest zdefiniowany warunkiem
na samego siebie („punkt, który przebył 1/3 swojego półłuku"), więc iterujemy po
punkcie stałym do 1e-11°. Brak zbieżności traktujemy jako wyjście poza dziedzinę,
nie jako wynik.

Koch okazał się natomiast ZAMKNIĘTY: jego kryterium to czas od wschodu stopnia
stojącego na MC, a półłuk tego stopnia znamy wprost z jego deklinacji. Definicja
za Astrodienst (astro.com/astrowiki/en/Koch_House_System) — nie zgadywana.

Powyżej koła podbiegunowego oba odmawiają liczenia i wyrocznia odmawia dokładnie
tych samych przypadków (5245/20 000 losowych, zero rozjazdów dziedziny). Odmowa
jest wyjątkiem, nie liczbą: cicha podmiana systemu jest niewykrywalna z wykresu.

Ustępstwo wobec rzeczywistości siedzi osobno, w cusps_detailed(): podstawia
Porphyry'ego i ZAWSZE zostawia ślad. Ten ślad idzie wszystkimi trzema wyjściami —
na ekran (ramka, nie „muted"), w prompt do modelu (inaczej napisze „Twój Placidus"
o Porphyrym) i do PDF-a, w ramce PRZED rysunkami. Astrolog z Tromsø dostaje
wynik i wie, że go dostał inaczej.

Przy okazji: nazwy systemów były zaszyte w czterech szablonach naraz. Przy trzech
systemach uchodziło to na sucho, przy dziesięciu nie — jest katalog w jednym
miejscu, a testy szablonów RENDERUJĄ je zamiast szukać tekstu w źródle, więc
łapią też literówki w Jinja.

Większe jądro efemeryd (de441): świadomie zdegradowane do „nice to have" —
rozszerza wyłącznie zakres dat, nie poprawia niczego w obecnym. Odnotowane
w domain.py przy JD_MIN/JD_MAX, żeby nie wróciło po cichu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 22:04:33 +02:00
gitea 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>
2026-07-30 14:01:42 +02:00