<title>ticket-146: feat(dashboard): add --web flag and SSE live log streaming (ticket-146)</title>
fixplesk 0.6.0
AI Cost Tracking
- 🤖 LLM usage: $1.6723 (10 commits)
- 👤 Human dev: ~$580 (5.8h @ $100/h, 30min dedup)
Generated on 2026-09-17 using openrouter/qwen/qwen3-coder-next
Diagnostyka Plesk/WordPress oparta na dowodach, z opcjonalnym LLM i kontrolowanym wykonaniem. Wydanie rozwojowe. Nie jest certyfikowanym skanerem ani autonomicznym administratorem serwera.
Wersja 0.6.0 rozwija poprzedni pakiet 0.5.0 (jego moduł guard pozostaje bez zmian). Zachowano wcześniejsze moduły diagnostyki,
DSL, kolektory, prywatność LLM, Executor, SQLite, security/offline, dokumentację i laboratoria.
Nowa grupa poleceń guard nie zastępuje security, diagnose, triage ani apply.
Nowe w 0.6.0: bezpośrednie DeepSeek API
backend="deepseek", własny DEEPSEEK_API_KEY, oficjalny endpoint, bez SDK i bez
pośrednictwa OpenRouter. Profile deepseek-flash (V4.1 Flash według dokumentacji
z 2026-09-10) i deepseek-v4-pro. Tryby thinking, poziomy low/high/max, JSON,
ograniczone odpowiedzi, brak zapisu reasoning_content. Dane nadal przechodzą strict.
Zgoda na bezpośrednie API nie jest gwarancją ZDR. Domyślnie nie przełączamy
istniejących konfiguracji; szczegółowe warunki są w docs/DEEPSEEK.md.
Nowe: bezpośrednie Z.ai API (backend zai)
backend="zai", własny ZAI_API_KEY, stały endpoint https://api.z.ai/api/paas/v4,
bez SDK i bez pośrednictwa OpenRouter. Modele potwierdzone żywą listą /models
(2026-09-16): glm-5.3, glm-5.3-flash (profile accurate/fast) oraz starsze
GLM-5.x. Te same jawne zgody co DeepSeek (require_zdr=false,
accept_provider_data_policy=true); szczegóły w docs/ZAI.md,
konfiguracja w examples/zai/.
fixplesk --config config.toml llm-info
fixplesk --config config.toml llm-preview --snapshot snapshot.json --output payload.json
Domyślne modele per provider i kolejność według dostępności
Skrypty (scripts/demo_llm_twin.py, scripts/benchmark_llm.py) czytają z .env:
LLM_PROVIDER_ORDER (kolejność providerów wg dostępności klucza), LLM_MODEL_DEEPSEEK/_ALT,
LLM_MODEL_ZAI/_ALT, LLM_MODEL_OPENROUTER/_ALT. Przy porażce modelu skrypt jawnie
przechodzi na alternatywę tego samego providera, potem do następnego w kolejności;
każdy hop jest logowany. Rdzeń silnika fixplesk nadal nie robi cichego fallbacku.
LLM_MODEL pozostaje pojedynczym domyślnym modelem narzędzia costs.
Konfiguracja: examples/deepseek/llm-section.toml; pełne demo:
examples/deepseek/config.toml. Poprzednie artefakty: history/0.5.0/dist/.
Wyniki bieżącej weryfikacji: docs/TESTING_0.6.0.md.
Laboratorium Docker: cyfrowy bliźniak i doradca LLM jedną komendą
bash scripts/demo_twin.sh uruchamia w izolowanym Dockerze deterministyczny bliźniak
Plesk/WordPress (sieć wewnętrzna, read-only, cap_drop: ALL) i kontener demo, który
wstrzykuje usterkę, wykonuje offline diagnozę, a po podaniu klucza wysyła jeden
zminimalizowany payload doradczy do wybranego modelu. Bez kluczy przepływ jest w pełni
offline i kończy się podglądem kontraktu dostawcy (llm-preview).
DEEPSEEK_API_KEY=sk-... bash scripts/demo_twin.sh # deepseek-flash (V4.1 Flash, direct)
ZAI_API_KEY=... bash scripts/demo_twin.sh # glm-5.3 (Z.ai direct)
OPENROUTER_API_KEY=sk-or-... bash scripts/demo_twin.sh # openrouter/z-ai/glm-5.3 (ZDR)
bash scripts/demo_twin.sh # offline + preview, bez kluczy
Pozostałe profile izolowane: scripts/test_offline_docker.sh (network_mode: none),
scripts/test_twin_docker.sh (pełny pakiet testów wobec bliźniaka),
scripts/test_guard_docker.sh, scripts/test_security_docker.sh,
scripts/test_wordpress_docker.sh (prawdziwy WordPress). Szczegóły: docs/DIGITAL_TWIN.md.
Benchmark doradczy LLM: DeepSeek vs z.ai
scripts/benchmark_llm.py porównuje silniki na tych samych scenariuszach (załączone
snapshoty + usterki syntetycznego bliźniaka), mierząc skuteczność walidacji Advice,
latencję, zużycie tokenów i koszt. Podczas pomiaru każdy przebieg raportuje na bieżąco
(czas, tokeny, status), więc długie żądania są zawsze widoczne. Ceny wariantów OpenRouter
pobierane są na żywo; klucze tylko ze środowiska.
python scripts/benchmark_llm.py --selftest # bez sieci i kluczy
DEEPSEEK_API_KEY=... ZAI_API_KEY=... \
python scripts/benchmark_llm.py --repeats 2 # właściwy pomiar
Wynik (2026-09-16, kontrakt strict): deepseek-v4-pro 90% skutecznych porad (47 s śr.),
zai-glm-5.3 60% (157 s, plan coding), oba flashe 30%. Pełne tabele: test-results/
i docs/analysis/llm-benchmark.md.
Funkcje zachowane z 0.5.0
| Funkcja | Implementacja | Granica |
|---|---|---|
| Pliki i katalogi | Lokalny skan document_root widocznych domen, metadane, hash, podejrzane wzorce, porównanie przebiegów | Bez dekodowania/wykonania PHP, usuwania i automatycznej kwarantanny |
| Integralność WP | Cache oficjalnych sum core dla wybranej wersji i locale oraz lokalne porównanie | Wersję wskazuje operator; brak potwierdzenia inventory i pełnej obsługi sum wtyczek premium |
| Bazy danych o zagrożeniach | Pobieranie KEV JSON, EPSS CSV.gz, Wordfence v3 JSON, sum WP; walidacja, historia, SHA-256, TTL | Bez podpisów producenta/TUF; import lokalny nie jest uwierzytelniony |
| Wersje WP | Dopasowanie core/plugin/theme do zakresów Wordfence; dołączenie cached KEV/EPSS po CVE | Komparator celowo obsługuje tylko numeryczne wersje; sufiksy oznaczają niepewność |
| Wskaźniki plików | Import własnych list SHA-256 CSV/JSON; zgodność i sprzeczności źródeł | Trafienie nie uruchamia usuwania |
| Wycieki kont | HIBP k-anon e-mail oraz osobna kontrola hasła online/offline | Bez łączenia kont z hasłami, łamania hashy i prób logowania |
| Dane WP | Odczytowy audyt wybranych wyeksportowanych pól opcji/postów i deklarowanych ról | Bez nowego połączenia SQL, automatycznego eksportu tabel i odczytu user_pass |
| Skrypty runtime | Prywatne pliki w /tmp, zamknięty DSL read-only, SHA-256, akceptacja, wynik, kopia trwała |
Tylko file.stat i file.sha256; dowolny kod LLM nie jest wykonywany |
| Prawa pliku | Plan ograniczenia praw grupy/other jednego pliku; realny fchmod po akceptacji |
Bez chown/rekurencji/ACL/dowiązań; tylko lokalny host |
| Obserwacje zmiany | HTTP GET, wybrane jednostki systemd, przyrost logów, diff i trwały dziennik | To jawnie wybrany zakres; nie test wszystkich usług i transakcji biznesowych |
Instalacja
Wymagania: Python 3.11+, Linux/POSIX. Wykonanie skryptów przez sealed memfd wymaga Linuksa. Nie opublikowano paczki w PyPI.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install ./dist/fixplesk-0.6.0-py3-none-any.whl
fixplesk --version
fixplesk guard --help
Instalacja zależności wymaga internetu albo przygotowanego repozytorium lokalnego.
Analiza zapisanych danych działa bez LLM i bez sieci. Nowe pobrania i sondy wymagają --allow-network.
Skan jednej domeny lub widocznych domen
Najpierw utwórz i sprawdź zaufane inventory. Opcja --config występuje przed podkomendą.
Nie używaj inventory pochodzącego od niezaufanego klienta HTTP. Uprawnienia deklarowane w pliku nie nadają uprawnień systemowych.
fixplesk init
fixplesk --config config.toml guard files scan --domain example.com --output scan-before.json
fixplesk --config config.toml guard files scan --all --output scan-all.json
fixplesk guard files compare --before scan-before.json --after scan-after.json --output diff.json
Zastąp example.com własnym celem istniejącym w konfiguracji. --all oznacza wyłącznie widoczne
w inventory cele, nie automatyczne odkrycie wszystkich domen serwera. Nie skanuj całego / jako root.
Nowe lokalne funkcje odmówią działania przy aktywnej konfiguracji SSH, zamiast czytać przypadkowo host lokalny.
Skan nie podąża za dowiązaniami; nie czyta hardlinków, urządzeń ani FIFO, nie przechodzi na inny filesystem.
Ma limity plików, bajtów, głębokości i czasu. Brak dostępu, rotacja czy limit trafia do gaps.
Odczyt nie jest atomowym snapshotem i może zmienić atime. Prawa POSIX nie dowodzą dostępności HTTP.
Nie jest oceniana pełna semantyka ACL/SELinux/nginx/Apache. Raportów nie zapisuj pod katalogiem witryny.
Pobieranie i import baz
fixplesk guard feeds list
fixplesk guard feeds sync --source cisa-kev --allow-network
fixplesk guard feeds sync --source epss --allow-network
# WORDFENCE_API_KEY ustaw w chronionym środowisku procesu, nie w argv.
fixplesk guard feeds sync --source wordfence --allow-network
fixplesk guard feeds status --source wordfence
fixplesk guard wp-match --inventory components.json --output vulnerabilities.json
components.json jest tablicą: id, domain, type (core/plugin/theme), slug, version,
observed_at (ISO8601 ze strefą), identity_verified (bool). Ostatnie pole jest deklaracją operatora,
nie zdalnym poświadczeniem tożsamości. Nie kopiuj daty z zegara bez rzeczywistego odczytu.
Cache zachowuje całe źródło i jego informacje licencyjne. Domyślnie trafia do ~/.cache/fixplesk/feeds.
Import lokalny: guard feeds import --source ... --input ... --obtained-at ....
Nieudany nowy import nie przełącza wskaźnika na niepoprawne dane. Nie ma automatycznej aktualizacji aplikacji ani pakietów serwera.
Opcjonalny przykład timera odświeżającego dane jest w integrations/systemd; nie jest instalowany ani włączany.
Przykład sum historycznej, jawnie wybranej wersji, nie rekomendacja aktualnej wersji WordPressa:
fixplesk guard feeds sync --source wp-checksums --version 6.8.1 --locale en_US --allow-network
fixplesk --config config.toml guard files scan --domain example.com \
--checksum-version 6.8.1 --checksum-locale en_US --output integrity.json
Nie przypisuj tych samych sum witrynom o różnych wersjach. Niezgodność jest dowodem różnicy, a nie automatycznie dowodem malware. Pierwszy własny skan nie stanowi zaufanej czystej bazy.
Kontrola kont i haseł
# HIBP_API_KEY w chronionym środowisku. Ukryty prompt e-mail; bez adresu w argv.
fixplesk guard breach email --account-ref mail-001 --consent --allow-network
# Osobne pytanie o hasło. Wymagany lokalny TTY; bez potoku, pliku ani argumentu z hasłem.
fixplesk guard breach password --online --consent --allow-network
# Offline: legalnie pozyskany korpus SHA1:count i jego rzeczywista data.
fixplesk guard breach password --offline-hashes /secure/pwned-passwords.txt \
--corpus-date 2026-09-15T00:00:00Z --consent
Kontrola e-maila używa k-anon z prefiksem 6 znaków; wymaga odpowiedniego planu HIBP.
Kontrola hasła używa prefiksu 5 znaków i paddingu. Nie ma fallbacku do wysłania całego adresu/hasła.
Nie są przechowywane surowe odpowiedzi dotyczące innych kont. Szczegóły i granice w docs/guard/BREACHES.md.
Podana data korpusu jest przykładem składni — musi odpowiadać faktycznemu źródłu.
Jawne skrypty tworzone podczas działania
fixplesk --config config.toml guard session create --domain example.com --output session.json
# Podstaw rzeczywistą ścieżkę zwróconą w session.json.
fixplesk --config config.toml guard session stage --domain example.com \
--session /tmp/fixplesk-UID-IDENTYFIKATOR --spec script-spec.json --output staged.json
fixplesk --config config.toml guard session list --domain example.com \
--session /tmp/fixplesk-UID-IDENTYFIKATOR
script-spec.json może być propozycją LLM lub operatora:
{"schema_version":1,"origin":"llm","operation":"file.sha256","path":"index.php","purpose":"Sprawdź pełną sumę pliku bez wykonywania PHP"}
guard session run --script ID --approve SHA256 to podgląd. Dopiero dodanie --execute uruchamia
zamknięty szablon. Skrypt musi pozostać bajt w bajt zgodny z generatorem. Wykonanie używa python -I
i zapieczętowanych bajtów memfd, a nie dowolnej zawartości pod zmienną nazwą w /tmp.
Nie jest to sandbox dla arbitralnego kodu. Nie ma tu nowej automatycznej rozmowy z LLM: przyjmowany jest
walidowany JSON propozycji. Dotychczasowa integracja LLM paczki nadal istnieje oddzielnie.
Kopia skryptów, manifestów, rollbacków i wyników jest pod state_dir/guard-sessions/ID.
Audyt zdarzeń znajduje się we wspólnym SQLite. guard session export tworzy prywatny ZIP.
Nie wysyłaj całego katalogu sesji do LLM ani do publicznego zgłoszenia.
Ograniczenie praw jednego pliku
Zapis wymaga allow_mutations=true w zaufanym celu inventory oraz uprawnień OS. Nie rozszerzaj uprawnień procesu tylko po to,
żeby test przeszedł. Nowa operacja nie próbuje zgadywać docelowego właściciela ani zastępować natywnych napraw konfiguracji Pleska.
fixplesk --config config.toml guard permissions plan --domain example.com \
--path backup.sql --mode 0640 --policy checks.json \
--why "Usuń zbędny zapis dla innych kont po przeglądzie uprawnień" --output permission-plan.json
fixplesk guard permissions run --plan permission-plan.json --output dry-run.json
Dobór 0640 jest przykładem, nie uniwersalną polityką. Pole digest z dry-run zatwierdza konkretny plan:
fixplesk --config config.toml guard permissions run --plan permission-plan.json \
--approve SHA256_PLANU --execute --allow-network --output execution.json
checks.json określa kontrolę, np. {"http_checks":[{"path":"/","expected_status":200,"required_text":"Nazwa witryny"}],"services":[]}.
HTTP200 bez właściwego znacznika nie przechodzi. Zmiana treści blokuje wynik, chyba że jawnie ustawisz
allow_content_drift=true. Dla usług podaj wyłącznie rzeczywiste jednostki z inventory.
Pełny model: fixplesk guard schema --kind policy.
Plan ważny jest 15 minut. Zmienia tylko prawa grupy/other jednego zwykłego pliku, bez rozszerzania praw.
Odmowa przy ACL, hardlinkach, symlinkach, zmianie treści/tożsamości i nierozliczonym wcześniejszym planie.
Brak sukcesu sondy nie powoduje domyślnie ponownego odsłonięcia starych uprawnień.
Zgoda --allow-restore-previous-mode musi być częścią planu przed wykonaniem.
Po nieznanym wyniku użyj istniejącego recovery status albo nowego guard permissions reconcile --digest ... --allow-network.
--acknowledge rozlicza obserwowany stan po kontrolach; nie wznawia i nie powtarza zapisu.
Inny wynik, zmieniona treść lub nowe inventory wymagają procedury ręcznej.
Testy, demo i plany rozwoju
python scripts/demo_guard.py --output-dir /tmp/fixplesk-guard-demo
python -m pytest tests/assurance -q
bash scripts/test_guard_docker.sh
Demo tworzy wyłącznie syntetyczne pliki i lokalne atrapowe odpowiedzi kontroli; nie diagnozuje Pleska.
Status bieżących testów jest w docs/TESTING_0.6.0.md; wcześniejszy pomiar zachowano w docs/guard/TESTING_0.5.0.md. Docker pozostaje osobnym profilem.
Szczegóły: docs/guard/ARCHITECTURE.md, docs/guard/ROADMAP.md, docs/guard/SOURCES.md.
Poprzednia instrukcja: docs/history/README_0.4.0.md.
License
Licensed under Apache-2.0.
Metadata
Release files for fixplesk 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fixplesk-0.6.1.tar.gz | 664.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fixplesk-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 875.6 kB
Release files / fixplesk-0.6.1.tar.gz
| Download URL | fixplesk-0.6.1.tar.gz |
|---|---|
| Size | 664.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d991218ca1da0614aaa50627d917c98274d64ca5e50e97ea9f913d70cc311d0b
|
|
BLAKE2b-256 checksum How to use checksums |
a758ee033bc84ab895aa428ab9a5e1cbdd84b17a25b45ea56e75c140418cf552
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / fixplesk-0.6.1-py3-none-any.whl
| Download URL | fixplesk-0.6.1-py3-none-any.whl |
|---|---|
| Size | 211.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
24fd9cc94efb45fb6aea46a0c81897c8b5907c1f8de006f741a5af6b81f5fa1c
|
|
BLAKE2b-256 checksum How to use checksums |
4209d11d2103f2ba303571fda9e105a30caec3b660bad86cef73dd359c1010e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|