diff --git a/Directory.Build.props b/Directory.Build.props
index 6232b02a..defc4645 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -22,10 +22,14 @@
+
+
+ $(WarningsAsErrors);RS0016;RS0017;RS0026;RS0027;RS0022;RS0023;RS0024;RS0025
+
- 6.1.15
+ 6.1.16
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 15b1b322..f2a68835 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -9,6 +9,7 @@
+
diff --git a/docs/0_de/governance/045_CODE_QUALITY_POLICY_DE.MD b/docs/0_de/governance/045_CODE_QUALITY_POLICY_DE.MD
index 866e5573..79d7423f 100644
--- a/docs/0_de/governance/045_CODE_QUALITY_POLICY_DE.MD
+++ b/docs/0_de/governance/045_CODE_QUALITY_POLICY_DE.MD
@@ -788,3 +788,16 @@ Diese Policy ist in der CI-RoC-Matrix auf folgende Regeldateien gemappt:
- `Microsoft.CodeAnalysis.BannedApiAnalyzers` (fail-closed über `BannedSymbols.txt`)
- `Meziantou.Analyzer`
- Für `FileTypeDetectionLib` ist mindestens `Microsoft.CodeAnalysis.BannedApiAnalyzers` mit derselben zentralen Banlist (`tools/analyzers/BannedSymbols.txt`) verpflichtend.
+
+## 13. Public-API-Governance (fail-closed)
+- `FileTypeDetectionLib` muss `Microsoft.CodeAnalysis.PublicApiAnalyzers` als `PrivateAssets=all` referenzieren.
+- Baseline-Dateien liegen unter `src/FileTypeDetection/`:
+ - `PublicAPI.Shipped.txt` (veröffentlichte API)
+ - `PublicAPI.Unshipped.txt` (noch nicht veröffentlichte API-Änderungen)
+- Bei absichtlichen API-Änderungen:
+ 1. Eintrag zuerst in `PublicAPI.Unshipped.txt`.
+ 2. Vor Stable-Release in `PublicAPI.Shipped.txt` überführen und `PublicAPI.Unshipped.txt` leeren.
+ 3. Changelog/Versionshistorie aktualisieren und Evidence im PR nachziehen.
+- Der Build läuft fail-closed über folgende RS-Fehler:
+ - `RS0016`, `RS0017`, `RS0022`, `RS0023`, `RS0024`, `RS0025`, `RS0026`, `RS0027`
+- Nicht beabsichtigte API-Drift ist blocker und darf nicht gemerged werden.
diff --git a/docs/0_de/versioning/002_HISTORY_VERSIONS.MD b/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
index 29a0dbd3..f60fc9d8 100644
--- a/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
@@ -12,7 +12,7 @@ Heuristik für die Rückwirkungs-Zuordnung:
- `docs|test|ci|chore|tooling|refactor|fix` => Patch
Aktueller Entwicklungsstand:
-- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.15`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
+- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.16`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
Hinweis:
- Die Spalte `Keyword` verwendet den technischen Klassifizierungswert aus der Historie.
@@ -20,6 +20,7 @@ Hinweis:
| Version | Kurzbeschreibung | Commit | Keyword |
|---|---|---|---|
+| `6.1.16` | API-Auditierbarkeit fail-closed aktiviert: `Microsoft.CodeAnalysis.PublicApiAnalyzers` zentral eingebunden, Public-API-Baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) für `FileTypeDetectionLib` eingeführt und Governance-/Versioning-Dokumentation um den verbindlichen API-Änderungsprozess erweitert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance-Drift geschlossen: Branch-Protection-Review-Policy und Scorecard-Governance-Mappings auf den verifizierten Ist-Stand `required_approving_review_count = 0` konsolidiert, inklusive aktualisierter Prozesskontrollen für verpflichtende Required-Checks und Review-Thread-Evidence gemäß `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 Pipeline-Konvergenz geschlossen: Release-Workflow erzwingt NuGet-Online-Konvergenz jetzt fail-closed auch für `workflow_dispatch`, Release-Metadaten werden artefaktbasiert deterministisch aufgelöst und Fuzzing-Blocker-/Governance-Evidence-Dokumentation entsprechend nachgezogen | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.13` | FC-0016 abgeschlossen: In-Code-XML-Dokumentation im gesamten CSCore sprachlich auf Deutsch vereinheitlicht (inkl. konsistenter ``- und `
`-Verwendungsstruktur) und Terminologie für Audit-/Betriebskontexte konsolidiert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD b/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
index 1d520842..7dc5399b 100644
--- a/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
@@ -7,6 +7,16 @@
Alle Änderungen werden hier technisch dokumentiert. Die Release-Version selbst ist
der Git-Tag `vX.Y.Z` (optional `-prerelease`) als SSOT.
+## [6.1.16]
+- Added:
+ - `Microsoft.CodeAnalysis.PublicApiAnalyzers` als zentrales Analyzer-Paket aufgenommen und für `FileTypeDetectionLib` aktiviert.
+ - Public-API-Baseline-Dateien `src/FileTypeDetection/PublicAPI.Shipped.txt` und `src/FileTypeDetection/PublicAPI.Unshipped.txt` eingeführt.
+- Changed:
+ - Build-Gate für Public API ist fail-closed aktiv: Änderungen an der öffentlichen API müssen nun explizit als shipped/unshipped deklariert werden.
+- Docs/CI/Tooling:
+ - Governance-Policy (DE/EN + Spiegel) um verbindlichen API-Änderungsprozess ergänzt.
+ - Versionskonvergenz aktiv auf `6.1.16` gesetzt (`RepoVersion`, `Version`, `PackageVersion`, Versionshistorie DE/EN).
+
## [6.1.15]
- Changed:
- Governance-Mapping für `CodeReviewID` auf den verifizierten Branch-Protection-Iststand harmonisiert (`required_approving_review_count = 0`, `require_code_owner_reviews = false`, `require_last_push_approval = false`).
diff --git a/docs/1_en/governance/045_CODE_QUALITY_POLICY_DE.MD b/docs/1_en/governance/045_CODE_QUALITY_POLICY_DE.MD
index 566e9e37..7b397b98 100644
--- a/docs/1_en/governance/045_CODE_QUALITY_POLICY_DE.MD
+++ b/docs/1_en/governance/045_CODE_QUALITY_POLICY_DE.MD
@@ -155,3 +155,16 @@ This policy is mapped in the CI RoC matrix to the following rule files:
- `tools/ci/policies/rules/naming_snt.yaml`
- `tools/ci/policies/rules/shell_safety.yaml`
- `tools/ci/policies/rules/versioning_svt.yaml`
+
+## 12. Public API Governance (fail-closed)
+- `FileTypeDetectionLib` must reference `Microsoft.CodeAnalysis.PublicApiAnalyzers` with `PrivateAssets=all`.
+- Baseline files are stored in `src/FileTypeDetection/`:
+ - `PublicAPI.Shipped.txt` (released API)
+ - `PublicAPI.Unshipped.txt` (not-yet-released API changes)
+- For intentional API changes:
+ 1. Add entries to `PublicAPI.Unshipped.txt` first.
+ 2. Move entries into `PublicAPI.Shipped.txt` before a stable release and clear `PublicAPI.Unshipped.txt`.
+ 3. Update changelog/version history and attach PR evidence.
+- Build enforcement is fail-closed via these RS diagnostics:
+ - `RS0016`, `RS0017`, `RS0022`, `RS0023`, `RS0024`, `RS0025`, `RS0026`, `RS0027`
+- Unintended public API drift is a blocker and must not be merged.
diff --git a/docs/1_en/versioning/002_HISTORY_VERSIONS.MD b/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
index b80fb538..b2ecdcd4 100644
--- a/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
@@ -12,13 +12,14 @@ Heuristics for retroactive classification:
- `docs|test|ci|chore|tooling|refactor|fix` => patch
Current state:
-- Current release line contains `6.x` (current working state: `v6.1.15`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
+- Current release line contains `6.x` (current working state: `v6.1.16`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
Note:
- The \"short description\" column follows the original commit/PR intent text for deterministic traceability and is not normalized to a single language.
| Version | Short description | Commit | Keyword |
|---|---|---|---|
+| `6.1.16` | API auditability fail-closed enabled: `Microsoft.CodeAnalysis.PublicApiAnalyzers` was added centrally, a public API baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) was introduced for `FileTypeDetectionLib`, and governance/versioning docs now define the mandatory API-change process | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance drift closed: branch-protection review policy and Scorecard governance mappings were aligned to the verified state `required_approving_review_count = 0`, including updated process controls for mandatory required checks and review-thread evidence per `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 pipeline convergence closed: release workflow now enforces NuGet online convergence fail-closed for `workflow_dispatch` too, resolves release metadata deterministically via artifact, and aligns fuzzing-blocker/governance evidence documentation | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.13` | FC-0016 completed: unified in-code XML documentation language to German across CSCore (including consistent `` and `
` structure) and consolidated terminology for audit/operational contexts | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD b/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
index f9eb1ba6..e7715517 100644
--- a/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
@@ -6,6 +6,16 @@
All changes are documented here in technical terms. The release version itself is the Git tag `vX.Y.Z` (optional `-prerelease`) as SSOT.
+## [6.1.16]
+- Added:
+ - Added `Microsoft.CodeAnalysis.PublicApiAnalyzers` as a centrally managed analyzer package and enabled it for `FileTypeDetectionLib`.
+ - Introduced public API baseline files `src/FileTypeDetection/PublicAPI.Shipped.txt` and `src/FileTypeDetection/PublicAPI.Unshipped.txt`.
+- Changed:
+ - Public API build gate is now fail-closed: any public API change must be declared explicitly as shipped/unshipped.
+- Docs/CI/Tooling:
+ - Extended governance policy docs (DE/EN + mirrors) with a mandatory API-change process.
+ - Version convergence set to `6.1.16` (`RepoVersion`, `Version`, `PackageVersion`, DE/EN version history).
+
## [6.1.15]
- Changed:
- Harmonized the governance mapping for `CodeReviewID` with the verified branch-protection state (`required_approving_review_count = 0`, `require_code_owner_reviews = false`, `require_last_push_approval = false`).
diff --git a/docs/governance/045_CODE_QUALITY_POLICY_DE.MD b/docs/governance/045_CODE_QUALITY_POLICY_DE.MD
index 9e8b5942..523bb1d5 100644
--- a/docs/governance/045_CODE_QUALITY_POLICY_DE.MD
+++ b/docs/governance/045_CODE_QUALITY_POLICY_DE.MD
@@ -788,3 +788,16 @@ Diese Policy ist in der CI-RoC-Matrix auf folgende Regeldateien gemappt:
- `Microsoft.CodeAnalysis.BannedApiAnalyzers` (fail-closed über `BannedSymbols.txt`)
- `Meziantou.Analyzer`
- Für `FileTypeDetectionLib` ist mindestens `Microsoft.CodeAnalysis.BannedApiAnalyzers` mit derselben zentralen Banlist (`tools/analyzers/BannedSymbols.txt`) verpflichtend.
+
+## 13. Public-API-Governance (fail-closed)
+- `FileTypeDetectionLib` muss `Microsoft.CodeAnalysis.PublicApiAnalyzers` als `PrivateAssets=all` referenzieren.
+- Baseline-Dateien liegen unter `src/FileTypeDetection/`:
+ - `PublicAPI.Shipped.txt` (veröffentlichte API)
+ - `PublicAPI.Unshipped.txt` (noch nicht veröffentlichte API-Änderungen)
+- Bei absichtlichen API-Änderungen:
+ 1. Eintrag zuerst in `PublicAPI.Unshipped.txt`.
+ 2. Vor Stable-Release in `PublicAPI.Shipped.txt` überführen und `PublicAPI.Unshipped.txt` leeren.
+ 3. Changelog/Versionshistorie aktualisieren und Evidence im PR nachziehen.
+- Der Build läuft fail-closed über folgende RS-Fehler:
+ - `RS0016`, `RS0017`, `RS0022`, `RS0023`, `RS0024`, `RS0025`, `RS0026`, `RS0027`
+- Nicht beabsichtigte API-Drift ist blocker und darf nicht gemerged werden.
diff --git a/docs/governance/145_CODE_QUALITY_POLICY_DE.MD b/docs/governance/145_CODE_QUALITY_POLICY_DE.MD
index 5a9789cd..f47330b8 100644
--- a/docs/governance/145_CODE_QUALITY_POLICY_DE.MD
+++ b/docs/governance/145_CODE_QUALITY_POLICY_DE.MD
@@ -155,3 +155,16 @@ This policy is mapped in the CI RoC matrix to the following rule files:
- `tools/ci/policies/rules/naming_snt.yaml`
- `tools/ci/policies/rules/shell_safety.yaml`
- `tools/ci/policies/rules/versioning_svt.yaml`
+
+## 12. Public API Governance (fail-closed)
+- `FileTypeDetectionLib` must reference `Microsoft.CodeAnalysis.PublicApiAnalyzers` with `PrivateAssets=all`.
+- Baseline files are stored in `src/FileTypeDetection/`:
+ - `PublicAPI.Shipped.txt` (released API)
+ - `PublicAPI.Unshipped.txt` (not-yet-released API changes)
+- For intentional API changes:
+ 1. Add entries to `PublicAPI.Unshipped.txt` first.
+ 2. Move entries into `PublicAPI.Shipped.txt` before a stable release and clear `PublicAPI.Unshipped.txt`.
+ 3. Update changelog/version history and attach PR evidence.
+- Build enforcement is fail-closed via these RS diagnostics:
+ - `RS0016`, `RS0017`, `RS0022`, `RS0023`, `RS0024`, `RS0025`, `RS0026`, `RS0027`
+- Unintended public API drift is a blocker and must not be merged.
diff --git a/docs/versioning/002_HISTORY_VERSIONS.MD b/docs/versioning/002_HISTORY_VERSIONS.MD
index d682b157..8f121b7a 100644
--- a/docs/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/versioning/002_HISTORY_VERSIONS.MD
@@ -12,7 +12,7 @@ Heuristik für die Rückwirkungs-Zuordnung:
- `docs|test|ci|chore|tooling|refactor|fix` => Patch
Aktueller Entwicklungsstand:
-- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.15`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
+- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.16`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
Hinweis:
- Die Spalte `Keyword` verwendet den technischen Klassifizierungswert aus der Historie.
@@ -20,6 +20,7 @@ Hinweis:
| Version | Kurzbeschreibung | Commit | Keyword |
|---|---|---|---|
+| `6.1.16` | API-Auditierbarkeit fail-closed aktiviert: `Microsoft.CodeAnalysis.PublicApiAnalyzers` zentral eingebunden, Public-API-Baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) für `FileTypeDetectionLib` eingeführt und Governance-/Versioning-Dokumentation um den verbindlichen API-Änderungsprozess erweitert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance-Drift geschlossen: Branch-Protection-Review-Policy und Scorecard-Governance-Mappings auf den verifizierten Ist-Stand `required_approving_review_count = 0` konsolidiert, inklusive aktualisierter Prozesskontrollen für verpflichtende Required-Checks und Review-Thread-Evidence gemäß `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 Pipeline-Konvergenz geschlossen: Release-Workflow erzwingt NuGet-Online-Konvergenz jetzt fail-closed auch für `workflow_dispatch`, Release-Metadaten werden artefaktbasiert deterministisch aufgelöst und Fuzzing-Blocker-/Governance-Evidence-Dokumentation entsprechend nachgezogen | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.13` | FC-0016 abgeschlossen: In-Code-XML-Dokumentation im gesamten CSCore sprachlich auf Deutsch vereinheitlicht (inkl. konsistenter ``- und `
`-Verwendungsstruktur) und Terminologie für Audit-/Betriebskontexte konsolidiert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/versioning/003_CHANGELOG_RELEASES.MD b/docs/versioning/003_CHANGELOG_RELEASES.MD
index a4fec49e..333ad8ce 100644
--- a/docs/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/versioning/003_CHANGELOG_RELEASES.MD
@@ -7,6 +7,16 @@
Alle Änderungen werden hier technisch dokumentiert. Die Release-Version selbst ist
der Git-Tag `vX.Y.Z` (optional `-prerelease`) als SSOT.
+## [6.1.16]
+- Added:
+ - `Microsoft.CodeAnalysis.PublicApiAnalyzers` als zentrales Analyzer-Paket aufgenommen und für `FileTypeDetectionLib` aktiviert.
+ - Public-API-Baseline-Dateien `src/FileTypeDetection/PublicAPI.Shipped.txt` und `src/FileTypeDetection/PublicAPI.Unshipped.txt` eingeführt.
+- Changed:
+ - Build-Gate für Public API ist fail-closed aktiv: Änderungen an der öffentlichen API müssen nun explizit als shipped/unshipped deklariert werden.
+- Docs/CI/Tooling:
+ - Governance-Policy (DE/EN + Spiegel) um verbindlichen API-Änderungsprozess ergänzt.
+ - Versionskonvergenz aktiv auf `6.1.16` gesetzt (`RepoVersion`, `Version`, `PackageVersion`, Versionshistorie DE/EN).
+
## [6.1.15]
- Changed:
- Governance-Mapping für `CodeReviewID` auf den verifizierten Branch-Protection-Iststand harmonisiert (`required_approving_review_count = 0`, `require_code_owner_reviews = false`, `require_last_push_approval = false`).
diff --git a/docs/versioning/102_HISTORY_VERSIONS.MD b/docs/versioning/102_HISTORY_VERSIONS.MD
index 169bce03..1775318f 100644
--- a/docs/versioning/102_HISTORY_VERSIONS.MD
+++ b/docs/versioning/102_HISTORY_VERSIONS.MD
@@ -12,13 +12,14 @@ Heuristics for retroactive classification:
- `docs|test|ci|chore|tooling|refactor|fix` => patch
Current state:
-- Current release line contains `6.x` (current working state: `v6.1.15`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
+- Current release line contains `6.x` (current working state: `v6.1.16`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
Note:
- The \"short description\" column follows the original commit/PR intent text for deterministic traceability and is not normalized to a single language.
| Version | Short description | Commit | Keyword |
|---|---|---|---|
+| `6.1.16` | API auditability fail-closed enabled: `Microsoft.CodeAnalysis.PublicApiAnalyzers` was added centrally, a public API baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) was introduced for `FileTypeDetectionLib`, and governance/versioning docs now define the mandatory API-change process | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance drift closed: branch-protection review policy and Scorecard governance mappings were aligned to the verified state `required_approving_review_count = 0`, including updated process controls for mandatory required checks and review-thread evidence per `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 pipeline convergence closed: release workflow now enforces NuGet online convergence fail-closed for `workflow_dispatch` too, resolves release metadata deterministically via artifact, and aligns fuzzing-blocker/governance evidence documentation | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.13` | FC-0016 completed: unified in-code XML documentation language to German across CSCore (including consistent `` and `
` structure) and consolidated terminology for audit/operational contexts | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/versioning/103_CHANGELOG_RELEASES.MD b/docs/versioning/103_CHANGELOG_RELEASES.MD
index ec4651c7..feeb4fd2 100644
--- a/docs/versioning/103_CHANGELOG_RELEASES.MD
+++ b/docs/versioning/103_CHANGELOG_RELEASES.MD
@@ -6,6 +6,16 @@
All changes are documented here in technical terms. The release version itself is the Git tag `vX.Y.Z` (optional `-prerelease`) as SSOT.
+## [6.1.16]
+- Added:
+ - Added `Microsoft.CodeAnalysis.PublicApiAnalyzers` as a centrally managed analyzer package and enabled it for `FileTypeDetectionLib`.
+ - Introduced public API baseline files `src/FileTypeDetection/PublicAPI.Shipped.txt` and `src/FileTypeDetection/PublicAPI.Unshipped.txt`.
+- Changed:
+ - Public API build gate is now fail-closed: any public API change must be declared explicitly as shipped/unshipped.
+- Docs/CI/Tooling:
+ - Extended governance policy docs (DE/EN + mirrors) with a mandatory API-change process.
+ - Version convergence set to `6.1.16` (`RepoVersion`, `Version`, `PackageVersion`, DE/EN version history).
+
## [6.1.15]
- Changed:
- Harmonized the governance mapping for `CodeReviewID` with the verified branch-protection state (`required_approving_review_count = 0`, `require_code_owner_reviews = false`, `require_last_push_approval = false`).
diff --git a/src/FileTypeDetection/FileTypeDetectionLib.vbproj b/src/FileTypeDetection/FileTypeDetectionLib.vbproj
index 929d9c22..018af9ef 100644
--- a/src/FileTypeDetection/FileTypeDetectionLib.vbproj
+++ b/src/FileTypeDetection/FileTypeDetectionLib.vbproj
@@ -7,8 +7,8 @@
true
false
Tomtastisch.FileClassifier
- 6.1.15
- 6.1.15
+ 6.1.16
+ 6.1.16
tomtastisch
Deterministic file type and MIME detection with fail-closed archive safety checks, secure extraction primitives, and reproducible hashing evidence for .NET.
filetype;mime;detection;magic-bytes;sniffing;archive;zip;tar;7z;rar;zipslip;security;hashing;sha256;deterministic;dotnet;netstandard2.0;net8;net10
diff --git a/src/FileTypeDetection/PublicAPI.Shipped.txt b/src/FileTypeDetection/PublicAPI.Shipped.txt
new file mode 100644
index 00000000..e127deb4
--- /dev/null
+++ b/src/FileTypeDetection/PublicAPI.Shipped.txt
@@ -0,0 +1,144 @@
+Overrides Tomtastisch.FileClassifier.FileType.ToString() -> String
+Shared Tomtastisch.FileClassifier.ArchiveProcessing.ExtractToMemory(path As String, verifyBeforeExtract As Boolean) -> System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry)
+Shared Tomtastisch.FileClassifier.ArchiveProcessing.TryExtractToMemory(data As Byte()) -> System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry)
+Shared Tomtastisch.FileClassifier.ArchiveProcessing.TryValidate(data As Byte()) -> Boolean
+Shared Tomtastisch.FileClassifier.ArchiveProcessing.TryValidate(path As String) -> Boolean
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashBytes(data As Byte()) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashBytes(data As Byte(), label As String) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashBytes(data As Byte(), label As String, options As Tomtastisch.FileClassifier.HashOptions) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashEntries(entries As System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry)) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashEntries(entries As System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry), label As String) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashEntries(entries As System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry), label As String, options As Tomtastisch.FileClassifier.HashOptions) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashFile(path As String) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.HashFile(path As String, options As Tomtastisch.FileClassifier.HashOptions) -> Tomtastisch.FileClassifier.HashEvidence
+Shared Tomtastisch.FileClassifier.EvidenceHashing.VerifyRoundTrip(path As String) -> Tomtastisch.FileClassifier.HashRoundTripReport
+Shared Tomtastisch.FileClassifier.EvidenceHashing.VerifyRoundTrip(path As String, options As Tomtastisch.FileClassifier.HashOptions) -> Tomtastisch.FileClassifier.HashRoundTripReport
+Shared Tomtastisch.FileClassifier.FileMaterializer.Persist(data As Byte(), destinationPath As String) -> Boolean
+Shared Tomtastisch.FileClassifier.FileMaterializer.Persist(data As Byte(), destinationPath As String, overwrite As Boolean) -> Boolean
+Shared Tomtastisch.FileClassifier.FileMaterializer.Persist(data As Byte(), destinationPath As String, overwrite As Boolean, secureExtract As Boolean) -> Boolean
+Shared Tomtastisch.FileClassifier.FileTypeDetector.ReadFileSafe(path As String) -> Byte()
+Shared Tomtastisch.FileClassifier.FileTypeDetector.TryValidateArchive(path As String) -> Boolean
+Shared Tomtastisch.FileClassifier.FileTypeOptions.GetOptions() -> String
+Shared Tomtastisch.FileClassifier.FileTypeOptions.LoadOptions(json As String) -> Boolean
+Shared Tomtastisch.FileClassifier.FileTypeProjectBaseline.ApplyDeterministicDefaults() -> Void
+Tomtastisch.FileClassifier.ArchiveProcessing
+Tomtastisch.FileClassifier.DetectionDetail
+Tomtastisch.FileClassifier.DetectionDetail.DetectedType() -> Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.DetectionDetail.ExtensionVerified() -> Boolean
+Tomtastisch.FileClassifier.DetectionDetail.ReasonCode() -> String
+Tomtastisch.FileClassifier.DetectionDetail.UsedStructuredRefinement() -> Boolean
+Tomtastisch.FileClassifier.DetectionDetail.UsedZipContentCheck() -> Boolean
+Tomtastisch.FileClassifier.EvidenceHashing
+Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Doc = 7 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Gif = 4 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Jpeg = 3 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Pdf = 1 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Png = 2 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Ppt = 9 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Unknown = 0 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Webp = 5 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Xls = 8 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileKind.Zip = 6 -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileMaterializer
+Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.FileType.Aliases() -> System.Collections.Immutable.ImmutableArray(Of String)
+Tomtastisch.FileClassifier.FileType.Allowed() -> Boolean
+Tomtastisch.FileClassifier.FileType.CanonicalExtension() -> String
+Tomtastisch.FileClassifier.FileType.Kind() -> Tomtastisch.FileClassifier.FileKind
+Tomtastisch.FileClassifier.FileType.Mime() -> String
+Tomtastisch.FileClassifier.FileTypeDetector
+Tomtastisch.FileClassifier.FileTypeDetector.Detect(data As Byte()) -> Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.FileTypeDetector.Detect(path As String) -> Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.FileTypeDetector.Detect(path As String, verifyExtension As Boolean) -> Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.FileTypeDetector.DetectAndVerifyExtension(path As String) -> Boolean
+Tomtastisch.FileClassifier.FileTypeDetector.DetectDetailed(path As String) -> Tomtastisch.FileClassifier.DetectionDetail
+Tomtastisch.FileClassifier.FileTypeDetector.DetectDetailed(path As String, verifyExtension As Boolean) -> Tomtastisch.FileClassifier.DetectionDetail
+Tomtastisch.FileClassifier.FileTypeDetector.ExtractArchiveSafe(path As String, destinationDirectory As String, verifyBeforeExtract As Boolean) -> Boolean
+Tomtastisch.FileClassifier.FileTypeDetector.ExtractArchiveSafeToMemory(path As String, verifyBeforeExtract As Boolean) -> System.Collections.Generic.IReadOnlyList(Of Tomtastisch.FileClassifier.ZipExtractedEntry)
+Tomtastisch.FileClassifier.FileTypeDetector.IsOfType(data As Byte(), kind As Tomtastisch.FileClassifier.FileKind) -> Boolean
+Tomtastisch.FileClassifier.FileTypeDetector.New() -> Void
+Tomtastisch.FileClassifier.FileTypeOptions
+Tomtastisch.FileClassifier.FileTypeProjectBaseline
+Tomtastisch.FileClassifier.FileTypeProjectOptions
+Tomtastisch.FileClassifier.FileTypeProjectOptions.AllowUnknownArchiveEntrySize() -> Boolean
+Tomtastisch.FileClassifier.FileTypeProjectOptions.AllowUnknownArchiveEntrySize(AutoPropertyValue As Boolean) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.DeterministicHash() -> Tomtastisch.FileClassifier.HashOptions
+Tomtastisch.FileClassifier.FileTypeProjectOptions.DeterministicHash(AutoPropertyValue As Tomtastisch.FileClassifier.HashOptions) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.HeaderOnlyNonZip() -> Boolean
+Tomtastisch.FileClassifier.FileTypeProjectOptions.Logger() -> Microsoft.Extensions.Logging.ILogger
+Tomtastisch.FileClassifier.FileTypeProjectOptions.Logger(AutoPropertyValue As Microsoft.Extensions.Logging.ILogger) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxBytes() -> Long
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxBytes(AutoPropertyValue As Long) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipCompressionRatio() -> Integer
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipCompressionRatio(AutoPropertyValue As Integer) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipEntries() -> Integer
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipEntries(AutoPropertyValue As Integer) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipEntryUncompressedBytes() -> Long
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipEntryUncompressedBytes(AutoPropertyValue As Long) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipNestedBytes() -> Long
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipNestedBytes(AutoPropertyValue As Long) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipNestingDepth() -> Integer
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipNestingDepth(AutoPropertyValue As Integer) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipTotalUncompressedBytes() -> Long
+Tomtastisch.FileClassifier.FileTypeProjectOptions.MaxZipTotalUncompressedBytes(AutoPropertyValue As Long) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.New() -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.RejectArchiveLinks() -> Boolean
+Tomtastisch.FileClassifier.FileTypeProjectOptions.RejectArchiveLinks(AutoPropertyValue As Boolean) -> Void
+Tomtastisch.FileClassifier.FileTypeProjectOptions.SniffBytes() -> Integer
+Tomtastisch.FileClassifier.FileTypeProjectOptions.SniffBytes(AutoPropertyValue As Integer) -> Void
+Tomtastisch.FileClassifier.HashDigestSet
+Tomtastisch.FileClassifier.HashDigestSet.FastLogicalXxHash3() -> String
+Tomtastisch.FileClassifier.HashDigestSet.FastPhysicalXxHash3() -> String
+Tomtastisch.FileClassifier.HashDigestSet.HasLogicalHash() -> Boolean
+Tomtastisch.FileClassifier.HashDigestSet.HasPhysicalHash() -> Boolean
+Tomtastisch.FileClassifier.HashDigestSet.HmacLogicalSha256() -> String
+Tomtastisch.FileClassifier.HashDigestSet.HmacPhysicalSha256() -> String
+Tomtastisch.FileClassifier.HashDigestSet.LogicalSha256() -> String
+Tomtastisch.FileClassifier.HashDigestSet.PhysicalSha256() -> String
+Tomtastisch.FileClassifier.HashEvidence
+Tomtastisch.FileClassifier.HashEvidence.CompressedBytes() -> System.Collections.Immutable.ImmutableArray(Of Byte)
+Tomtastisch.FileClassifier.HashEvidence.DetectedType() -> Tomtastisch.FileClassifier.FileType
+Tomtastisch.FileClassifier.HashEvidence.Digests() -> Tomtastisch.FileClassifier.HashDigestSet
+Tomtastisch.FileClassifier.HashEvidence.Entry() -> Tomtastisch.FileClassifier.ZipExtractedEntry
+Tomtastisch.FileClassifier.HashEvidence.EntryCount() -> Integer
+Tomtastisch.FileClassifier.HashEvidence.Label() -> String
+Tomtastisch.FileClassifier.HashEvidence.Notes() -> String
+Tomtastisch.FileClassifier.HashEvidence.SourceType() -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashEvidence.TotalUncompressedBytes() -> Long
+Tomtastisch.FileClassifier.HashEvidence.UncompressedBytes() -> System.Collections.Immutable.ImmutableArray(Of Byte)
+Tomtastisch.FileClassifier.HashOptions
+Tomtastisch.FileClassifier.HashOptions.IncludeFastHash() -> Boolean
+Tomtastisch.FileClassifier.HashOptions.IncludeFastHash(AutoPropertyValue As Boolean) -> Void
+Tomtastisch.FileClassifier.HashOptions.IncludePayloadCopies() -> Boolean
+Tomtastisch.FileClassifier.HashOptions.IncludePayloadCopies(AutoPropertyValue As Boolean) -> Void
+Tomtastisch.FileClassifier.HashOptions.IncludeSecureHash() -> Boolean
+Tomtastisch.FileClassifier.HashOptions.IncludeSecureHash(AutoPropertyValue As Boolean) -> Void
+Tomtastisch.FileClassifier.HashOptions.MaterializedFileName() -> String
+Tomtastisch.FileClassifier.HashOptions.MaterializedFileName(AutoPropertyValue As String) -> Void
+Tomtastisch.FileClassifier.HashOptions.New() -> Void
+Tomtastisch.FileClassifier.HashRoundTripReport
+Tomtastisch.FileClassifier.HashRoundTripReport.Evidence(slot As Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot) -> Tomtastisch.FileClassifier.HashEvidence
+Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot
+Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot.H1 = 1 -> Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot
+Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot.H2 = 2 -> Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot
+Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot.H3 = 3 -> Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot
+Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot.H4 = 4 -> Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot
+Tomtastisch.FileClassifier.HashRoundTripReport.InputPath() -> String
+Tomtastisch.FileClassifier.HashRoundTripReport.IsArchiveInput() -> Boolean
+Tomtastisch.FileClassifier.HashRoundTripReport.LogicalConsistent() -> Boolean
+Tomtastisch.FileClassifier.HashRoundTripReport.LogicalEquals(otherSlot As Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot) -> Boolean
+Tomtastisch.FileClassifier.HashRoundTripReport.Notes() -> String
+Tomtastisch.FileClassifier.HashRoundTripReport.PhysicalEquals(otherSlot As Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot) -> Boolean
+Tomtastisch.FileClassifier.HashRoundTripReport.Slots() -> Tomtastisch.FileClassifier.HashRoundTripReport.HashSlot()
+Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashSourceType.ArchiveEntries = 3 -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashSourceType.FilePath = 1 -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashSourceType.MaterializedFile = 4 -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashSourceType.RawBytes = 2 -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.HashSourceType.Unknown = 0 -> Tomtastisch.FileClassifier.HashSourceType
+Tomtastisch.FileClassifier.ZipExtractedEntry
+Tomtastisch.FileClassifier.ZipExtractedEntry.Content() -> System.Collections.Immutable.ImmutableArray(Of Byte)
+Tomtastisch.FileClassifier.ZipExtractedEntry.OpenReadOnlyStream() -> System.IO.MemoryStream
+Tomtastisch.FileClassifier.ZipExtractedEntry.RelativePath() -> String
+Tomtastisch.FileClassifier.ZipExtractedEntry.Size() -> Integer
diff --git a/src/FileTypeDetection/PublicAPI.Unshipped.txt b/src/FileTypeDetection/PublicAPI.Unshipped.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/src/FileTypeDetection/packages.lock.json b/src/FileTypeDetection/packages.lock.json
index 3afea75e..c6a56459 100644
--- a/src/FileTypeDetection/packages.lock.json
+++ b/src/FileTypeDetection/packages.lock.json
@@ -14,6 +14,12 @@
"resolved": "3.3.4",
"contentHash": "0k2Jwpc8eq0hjOtX6TxRkHm9clkJ2PAQ3heEHgqIJZcsfdFosC/iyz18nsgTVDDWpID80rC7aiYK7ripx+Qndg=="
},
+ "Microsoft.CodeAnalysis.PublicApiAnalyzers": {
+ "type": "Direct",
+ "requested": "[3.3.4, )",
+ "resolved": "3.3.4",
+ "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA=="
+ },
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Direct",
"requested": "[10.0.3, )",
@@ -211,6 +217,12 @@
"resolved": "3.3.4",
"contentHash": "0k2Jwpc8eq0hjOtX6TxRkHm9clkJ2PAQ3heEHgqIJZcsfdFosC/iyz18nsgTVDDWpID80rC7aiYK7ripx+Qndg=="
},
+ "Microsoft.CodeAnalysis.PublicApiAnalyzers": {
+ "type": "Direct",
+ "requested": "[3.3.4, )",
+ "resolved": "3.3.4",
+ "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA=="
+ },
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Direct",
"requested": "[10.0.3, )",
@@ -271,6 +283,12 @@
"resolved": "3.3.4",
"contentHash": "0k2Jwpc8eq0hjOtX6TxRkHm9clkJ2PAQ3heEHgqIJZcsfdFosC/iyz18nsgTVDDWpID80rC7aiYK7ripx+Qndg=="
},
+ "Microsoft.CodeAnalysis.PublicApiAnalyzers": {
+ "type": "Direct",
+ "requested": "[3.3.4, )",
+ "resolved": "3.3.4",
+ "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA=="
+ },
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Direct",
"requested": "[10.0.3, )",