{
  "$schema": "https://dcsf.net/changelog.schema.json",
  "schema_version": "dcsf-changelog-v1",
  "project": {
    "name": "DCSF",
    "alternateName": "DataHouse CSF",
    "maintainer": "DataHouse / eTop sp. z o.o.",
    "url": "https://dcsf.net/",
    "license": "GPL-3.0",
    "price": {
      "amount": 0,
      "currency": "USD"
    },
    "contact": "dat@etop.pl"
  },
  "updated": "2026-09-16",
  "latest_release": {
    "public_version": "DH20.22",
    "technical_version": "15.10.25",
    "published": "2026-09-16T10:32:19Z",
    "artifact_sha256": "b7bdc84c464d09c21be037a176e813cb9bbc016f90f8b62b4ca7d5b2aed0d9d6",
    "metadata_url": "https://dcsf.net/release.json"
  },
  "history_coverage": {
    "complete": false,
    "public_versions": [
      "DH20.22",
      "DH20.21",
      "DH20.20",
      "DH20.19",
      "DH20.18"
    ],
    "note": "Structured history currently covers these 5 verified releases, not every historical DCSF release."
  },
  "releases": [
    {
      "version": "DH20.22",
      "technical_version": "15.10.25",
      "published": "2026-09-16T10:32:19Z",
      "channel": "stable",
      "latest": true,
      "changes": [
        {
          "title": {
            "en": "Optional AI System Scan",
            "pl": "Opcjonalny AI System Scan"
          },
          "description": {
            "en": "AI System Scan adds quick and deep assessments to the DCSF administration interface. It is disabled by default and requires the administrator to configure a personal OpenAI API key and select a model.",
            "pl": "AI System Scan dodaje szybki i pogłębiony przegląd do interfejsu administracyjnego DCSF. Funkcja jest domyślnie wyłączona i wymaga podania przez administratora własnego klucza OpenAI API oraz wyboru modelu."
          }
        },
        {
          "title": {
            "en": "Bounded evidence and private credentials",
            "pl": "Ograniczony zakres dowodów i chroniony klucz"
          },
          "description": {
            "en": "A single background scan collects a bounded local security snapshot, with limits on reads, processes, data size and execution time. The API key is kept in a separate root-only file and is never rendered back into the interface.",
            "pl": "Pojedynczy skan w tle zbiera ograniczony zestaw lokalnych danych bezpieczeństwa, z limitami odczytów, procesów, rozmiaru danych i czasu wykonania. Klucz API jest w osobnym pliku dostępnym tylko dla roota i nigdy nie wraca do interfejsu."
          }
        },
        {
          "title": {
            "en": "Findings tied to supplied evidence",
            "pl": "Wnioski powiązane z przekazanymi dowodami"
          },
          "description": {
            "en": "OpenAI Responses API requests use store=false, no tools and strict structured output. Findings and recommendations must cite valid evidence IDs from the submitted snapshot. Results are advisory and do not automatically execute repairs.",
            "pl": "Żądania OpenAI Responses API używają store=false, bez narzędzi i ze ścisłym formatem odpowiedzi. Wnioski oraz zalecenia muszą wskazywać prawidłowe identyfikatory dowodów z wysłanego zestawu. Raport doradza, ale nie wykonuje automatycznie napraw."
          }
        }
      ],
      "release_notes": "https://dcsf.net/updates/#dh20.22",
      "source_commit": "487c486c4f55ce5853fcf9c64273e2ed489b9281",
      "artifact": {
        "url": "https://update.dcsf.net/releases/15.10.25/dcsf-15.10.25.tar.gz",
        "sha256": "b7bdc84c464d09c21be037a176e813cb9bbc016f90f8b62b4ca7d5b2aed0d9d6",
        "size": 5866418
      },
      "manifest": {
        "url": "https://update.dcsf.net/releases/15.10.25/manifest.txt",
        "signature_url": "https://update.dcsf.net/releases/15.10.25/manifest.txt.sig",
        "sha256": "7912c1f790faabba52a5f13f7663daa1fd21be4c7ad776d2531d01d8673721fe"
      },
      "metadata_url": "https://update.dcsf.net/releases/15.10.25/release.json"
    },
    {
      "version": "DH20.21",
      "technical_version": "15.10.24",
      "published": "2026-09-14T12:20:40Z",
      "channel": "stable",
      "latest": false,
      "changes": [
        {
          "title": {
            "en": "Exporter warnings stop migration",
            "pl": "Ostrzeżenia eksportera zatrzymują migrację"
          },
          "description": {
            "en": "The migration bootstrap refuses to continue when iptables-save returns exit code 0 but its diagnostics report an incompatible nft table. A successful exit status alone is not accepted as proof of a complete firewall export.",
            "pl": "Bootstrap migracji odmawia kontynuacji, gdy iptables-save zwraca kod wyjścia 0, ale w diagnostyce zgłasza niezgodną tabelę nft. Sam poprawny kod zakończenia nie jest dowodem kompletnego eksportu firewalla."
          }
        },
        {
          "title": {
            "en": "Mixed and omitted firewall state is refused",
            "pl": "Odmowa przy mieszanym lub pominiętym stanie"
          },
          "description": {
            "en": "Migration is refused when legacy and nft rules coexist, or when an active standard nftables table is omitted from the export. An incomplete snapshot cannot silently become the rollback baseline.",
            "pl": "Migracja jest odrzucana, gdy równocześnie istnieją reguły legacy i nft albo eksport pomija aktywną standardową tabelę nftables. Niepełna kopia nie może po cichu stać się podstawą przywracania stanu."
          }
        },
        {
          "title": {
            "en": "Complete, checksum-bound migration evidence",
            "pl": "Pełne dowody migracji objęte sumami kontrolnymi"
          },
          "description": {
            "en": "The migration backup saves the full nft list ruleset output and exporter diagnostics. These files are included in the backup SHA-256 checksums so the captured rules and export evidence can be verified together.",
            "pl": "Kopia migracyjna zapisuje pełny wynik nft list ruleset oraz diagnostykę eksporterów. Pliki te wchodzą do sum kontrolnych SHA-256 backupu, aby razem weryfikować zapisane reguły i dowody przebiegu eksportu."
          }
        }
      ],
      "release_notes": "https://dcsf.net/updates/#dh20.21",
      "source_commit": "a1875fc8cea317a401cde5e8e8de900cba4abe64",
      "artifact": {
        "url": "https://update.dcsf.net/releases/15.10.24/dcsf-15.10.24.tar.gz",
        "sha256": "5f520af0826686e3811e063f1eb6acb5b44391ef522a61c4fe3a2a62c48bcd30",
        "size": 5850851
      },
      "manifest": {
        "url": "https://update.dcsf.net/releases/15.10.24/manifest.txt",
        "signature_url": "https://update.dcsf.net/releases/15.10.24/manifest.txt.sig",
        "sha256": "4e183800491e159c4a03c9ed6d22bea584dce712c4e67c6973c5d03e9626e813"
      },
      "metadata_url": "https://update.dcsf.net/releases/15.10.24/release.json"
    },
    {
      "version": "DH20.20",
      "technical_version": "15.10.23",
      "published": "2026-09-13T20:38:12Z",
      "channel": "stable",
      "latest": false,
      "changes": [
        {
          "title": {
            "en": "LFD active after production updates",
            "pl": "Aktywne LFD po aktualizacji produkcyjnej"
          },
          "description": {
            "en": "After a successful production-profile update (TESTING=0), the installer restarts LFD and checks the result, including active service state on systemd. The new daemon code takes effect immediately; TESTING=1 installations are not started.",
            "pl": "Po udanej aktualizacji profilu produkcyjnego (TESTING=0) instalator restartuje LFD i sprawdza wynik, w tym aktywność usługi na systemd. Nowy kod demona działa od razu; instalacje z TESTING=1 nie są uruchamiane."
          }
        }
      ],
      "release_notes": "https://dcsf.net/updates/#dh20.20",
      "source_commit": "591c5870c69df1168a2a3f72263a4338853ef51a",
      "artifact": {
        "url": "https://update.dcsf.net/releases/15.10.23/dcsf-15.10.23.tar.gz",
        "sha256": "e7b87e873bf4e50adc0fadf53afe63cadad96e7e59efbec4b03683f32f02a58e",
        "size": 5850803
      },
      "manifest": {
        "url": "https://update.dcsf.net/releases/15.10.23/manifest.txt",
        "signature_url": "https://update.dcsf.net/releases/15.10.23/manifest.txt.sig",
        "sha256": "17b09fe445561a9e0fdc52dba1156cd15839b539eb1ad971931198f84754b300"
      },
      "metadata_url": "https://update.dcsf.net/releases/15.10.23/release.json"
    },
    {
      "version": "DH20.19",
      "technical_version": "15.10.22",
      "published": "2026-09-13T20:05:57Z",
      "channel": "stable",
      "latest": false,
      "changes": [
        {
          "title": {
            "en": "Separate procfs context budget",
            "pl": "Oddzielny budżet kontekstu procfs"
          },
          "description": {
            "en": "Contextual identity checks have a separate, bounded procfs scan budget. Hosts with many processes no longer generate false excessive usage alerts from this budget collision; ordinary process, per-UID and global limits are not relaxed.",
            "pl": "Kontrole kontekstowej tożsamości mają osobny, ograniczony budżet skanowania procfs. Przy wielu procesach nie powstają już fałszywe alarmy excessive usage spowodowane kolizją tych budżetów; zwykłe limity procesu, UID i całego skanowania nie są osłabiane."
          }
        }
      ],
      "release_notes": "https://dcsf.net/updates/#dh20.19",
      "source_commit": "d320055318a796d65a0496b67b7f72e5fdeca04a",
      "artifact": {
        "url": "https://update.dcsf.net/releases/15.10.22/dcsf-15.10.22.tar.gz",
        "sha256": "bc7902a47ebd3a17af31aebf61c2dec50d20dfa7bc43cb300201ac64c962eb21",
        "size": 5850775
      },
      "manifest": {
        "url": "https://update.dcsf.net/releases/15.10.22/manifest.txt",
        "signature_url": "https://update.dcsf.net/releases/15.10.22/manifest.txt.sig",
        "sha256": "47b906f1734c8561eb0269e14c8ecd443f68b1bad9378e02e57a5c9f01d35b7a"
      },
      "metadata_url": "https://update.dcsf.net/releases/15.10.22/release.json"
    },
    {
      "version": "DH20.18",
      "technical_version": "15.10.21",
      "published": "2026-09-13T07:47:43Z",
      "channel": "stable",
      "latest": false,
      "changes": [
        {
          "title": {
            "en": "Accurate systemd Apache detection for Zimbra",
            "pl": "Trafna detekcja Apache na systemd z Zimbrą"
          },
          "description": {
            "en": "Systemd service state is authoritative for Apache and ModSecurity log checks. A private Zimbra httpd process does not make an inactive system Apache appear active. The legacy init process fallback is retained.",
            "pl": "O kontroli logów Apache i ModSecurity rozstrzyga stan usługi systemd. Prywatny proces httpd Zimbry nie oznacza aktywnego systemowego Apache. Zachowano kontrolę procesu dla starszego init."
          }
        }
      ],
      "release_notes": "https://dcsf.net/updates/#dh20.18",
      "source_commit": "3b1a4aba7d42e6c36e021d214dc47678ebc1a583",
      "artifact": {
        "url": "https://update.dcsf.net/releases/15.10.21/dcsf-15.10.21.tar.gz",
        "sha256": "6977705fd2137a3caaaf18587151fac49eb5d090a83fee81e16cd438def1d1c6",
        "size": 5850698
      },
      "manifest": {
        "url": "https://update.dcsf.net/releases/15.10.21/manifest.txt",
        "signature_url": "https://update.dcsf.net/releases/15.10.21/manifest.txt.sig",
        "sha256": "05fcbf0260e45817c1e06555a1c91c8a4429be573425772fb0dade09e67e6076"
      },
      "metadata_url": "https://update.dcsf.net/releases/15.10.21/release.json"
    }
  ],
  "ai_system_scan": {
    "name": "AI System Scan",
    "introduced_in_public_release": "DH20.22",
    "introduced_in_technical_version": "15.10.25",
    "enabled_by_default": false,
    "administrator_api_key_required": true,
    "modes": [
      "quick",
      "deep"
    ],
    "model_options": [
      "gpt-5-mini",
      "gpt-5.4-mini",
      "gpt-5.6-terra"
    ],
    "model_access": "These are the model choices offered by this release. Availability depends on the administrator OpenAI API account.",
    "key_storage": "Separate root-owned private file, mode 0600; never rendered back into the administration UI.",
    "execution": {
      "single_background_scan": true,
      "bounded_evidence": true,
      "bounded_execution_time": true,
      "automatic_remediation": false
    },
    "provider": {
      "name": "OpenAI",
      "endpoint": "https://api.openai.com/v1/responses",
      "store": false,
      "tools": [],
      "strict_output_schema": true,
      "valid_sent_evidence_ids_required": true
    },
    "disclosure": {
      "en": "Selected local security diagnostics are sent to OpenAI after activation. Recognised secret values are redacted, but this is not an anonymity guarantee. store=false is not a Zero Data Retention guarantee; the API account and provider data policies still apply. Optional API usage is billed separately from the free DCSF software. Findings need administrator review and do not guarantee that every security issue is detected.",
      "pl": "Po włączeniu wybrane lokalne dane diagnostyczne bezpieczeństwa są wysyłane do OpenAI. Rozpoznane sekrety są maskowane, ale nie jest to gwarancja anonimowości. store=false nie gwarantuje Zero Data Retention; nadal obowiązują ustawienia konta API i zasady dostawcy. Opcjonalne użycie API jest rozliczane osobno od bezpłatnego DCSF. Wnioski wymagają oceny administratora i nie gwarantują wykrycia wszystkich problemów bezpieczeństwa."
    },
    "data_policy_url": "https://developers.openai.com/api/docs/guides/your-data",
    "documentation_url": "https://dcsf.net/updates/#ai-system-scan"
  },
  "retained_capabilities": [
    {
      "title": {
        "en": "Exporter warnings stop migration",
        "pl": "Ostrzeżenia eksportera zatrzymują migrację"
      },
      "description": {
        "en": "The migration bootstrap refuses to continue when iptables-save returns exit code 0 but its diagnostics report an incompatible nft table. A successful exit status alone is not accepted as proof of a complete firewall export.",
        "pl": "Bootstrap migracji odmawia kontynuacji, gdy iptables-save zwraca kod wyjścia 0, ale w diagnostyce zgłasza niezgodną tabelę nft. Sam poprawny kod zakończenia nie jest dowodem kompletnego eksportu firewalla."
      }
    },
    {
      "title": {
        "en": "Mixed and omitted firewall state is refused",
        "pl": "Odmowa przy mieszanym lub pominiętym stanie"
      },
      "description": {
        "en": "Migration is refused when legacy and nft rules coexist, or when an active standard nftables table is omitted from the export. An incomplete snapshot cannot silently become the rollback baseline.",
        "pl": "Migracja jest odrzucana, gdy równocześnie istnieją reguły legacy i nft albo eksport pomija aktywną standardową tabelę nftables. Niepełna kopia nie może po cichu stać się podstawą przywracania stanu."
      }
    },
    {
      "title": {
        "en": "Complete, checksum-bound migration evidence",
        "pl": "Pełne dowody migracji objęte sumami kontrolnymi"
      },
      "description": {
        "en": "The migration backup saves the full nft list ruleset output and exporter diagnostics. These files are included in the backup SHA-256 checksums so the captured rules and export evidence can be verified together.",
        "pl": "Kopia migracyjna zapisuje pełny wynik nft list ruleset oraz diagnostykę eksporterów. Pliki te wchodzą do sum kontrolnych SHA-256 backupu, aby razem weryfikować zapisane reguły i dowody przebiegu eksportu."
      }
    },
    {
      "title": {
        "en": "Separate procfs context budget",
        "pl": "Oddzielny budżet kontekstu procfs"
      },
      "description": {
        "en": "Contextual identity checks have a separate, bounded procfs scan budget. Hosts with many processes no longer generate false excessive usage alerts from this budget collision; ordinary process, per-UID and global limits are not relaxed.",
        "pl": "Kontrole kontekstowej tożsamości mają osobny, ograniczony budżet skanowania procfs. Przy wielu procesach nie powstają już fałszywe alarmy excessive usage spowodowane kolizją tych budżetów; zwykłe limity procesu, UID i całego skanowania nie są osłabiane."
      }
    },
    {
      "title": {
        "en": "LFD active after production updates",
        "pl": "Aktywne LFD po aktualizacji produkcyjnej"
      },
      "description": {
        "en": "After a successful production-profile update (TESTING=0), the installer restarts LFD and checks the result, including active service state on systemd. The new daemon code takes effect immediately; TESTING=1 installations are not started.",
        "pl": "Po udanej aktualizacji profilu produkcyjnego (TESTING=0) instalator restartuje LFD i sprawdza wynik, w tym aktywność usługi na systemd. Nowy kod demona działa od razu; instalacje z TESTING=1 nie są uruchamiane."
      }
    },
    {
      "title": {
        "en": "Bounded registration retry",
        "pl": "Ograniczone ponawianie rejestracji"
      },
      "description": {
        "en": "Installation registration uses the extensionless HTTPS API with bounded retry and backoff. A transient failure can be retried without an unbounded wait; signed identity and source-address checks remain in force.",
        "pl": "Rejestracja instalacji korzysta z API HTTPS bez rozszerzenia pliku oraz ograniczonych prób retry i backoff. Chwilowy błąd można ponowić bez nieograniczonego oczekiwania; podpis tożsamości i kontrola adresu źródłowego pozostają wymagane."
      }
    },
    {
      "title": {
        "en": "SELinux-aware installation",
        "pl": "Instalacja świadoma stanu SELinux"
      },
      "description": {
        "en": "The installer checks SELinux state before using chcon. Disabled SELinux no longer produces misleading relabel warnings, while enabled systems retain context handling.",
        "pl": "Instalator sprawdza stan SELinux przed użyciem chcon. Wyłączony SELinux nie powoduje już mylących ostrzeżeń o etykietowaniu, a aktywne środowiska zachowują obsługę kontekstów."
      }
    },
    {
      "title": {
        "en": "Native systemd handling",
        "pl": "Natywna obsługa systemd"
      },
      "description": {
        "en": "A systemd-only host no longer reports missing legacy SysV init files or tries to change ownership of files that are not installed. Legacy init remains supported.",
        "pl": "Host działający wyłącznie na systemd nie zgłasza braku starych plików startowych SysV ani nie próbuje zmieniać właściciela nieistniejących plików. Starszy init pozostaje obsługiwany."
      }
    },
    {
      "title": {
        "en": "Accurate Apache and ModSecurity checks",
        "pl": "Trafna kontrola Apache i ModSecurity"
      },
      "description": {
        "en": "Inactive Apache and default ModSecurity log paths are informational. With systemd, actual service state is authoritative: Zimbra's private /opt/zimbra/common/bin/httpd is not mistaken for the system Apache service. Legacy init retains a process fallback.",
        "pl": "Nieaktywny Apache i domyślne ścieżki logów ModSecurity mają status informacyjny. Na systemd rozstrzyga rzeczywisty stan usługi: prywatny /opt/zimbra/common/bin/httpd nie jest mylony z systemowym Apache. Starszy init zachowuje kontrolę procesu."
      }
    },
    {
      "title": {
        "en": "Validated Zimbra mail transport",
        "pl": "Sprawdzony transport poczty Zimbra"
      },
      "description": {
        "en": "The canonical Zimbra sendmail symlink is recognized through the trusted-path check. This targeted compatibility repair does not make arbitrary symlinks trusted.",
        "pl": "Kanoniczny symlink sendmail Zimbry jest rozpoznawany przez kontrolę zaufanej ścieżki. Ta celowana poprawka zgodności nie nadaje zaufania dowolnym symlinkom."
      }
    }
  ],
  "security_status_url": "https://dcsf.net/security.json",
  "security_register_url": "https://dcsf.net/hardening/",
  "provenance": "Release identity, publication timestamp, source commit and artifact digest are cross-checked against each signed versioned manifest. Change summaries are maintainer documentation, not signed manifest fields. Retained capabilities are not claimed as new fixes in the latest release."
}
