From 7fd48dda0390e1e2d6157868435b39ccd0fc3ed6 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Sun, 22 Feb 2026 21:22:00 +0100 Subject: [PATCH] feat(api): public-api-analyzer als fail-closed gate aktivieren --- Directory.Build.props | 6 +- Directory.Packages.props | 1 + .../governance/045_CODE_QUALITY_POLICY_DE.MD | 13 ++ docs/0_de/versioning/002_HISTORY_VERSIONS.MD | 3 +- .../0_de/versioning/003_CHANGELOG_RELEASES.MD | 10 ++ .../governance/045_CODE_QUALITY_POLICY_DE.MD | 13 ++ docs/1_en/versioning/002_HISTORY_VERSIONS.MD | 3 +- .../1_en/versioning/003_CHANGELOG_RELEASES.MD | 10 ++ docs/governance/045_CODE_QUALITY_POLICY_DE.MD | 13 ++ docs/governance/145_CODE_QUALITY_POLICY_DE.MD | 13 ++ docs/versioning/002_HISTORY_VERSIONS.MD | 3 +- docs/versioning/003_CHANGELOG_RELEASES.MD | 10 ++ docs/versioning/102_HISTORY_VERSIONS.MD | 3 +- docs/versioning/103_CHANGELOG_RELEASES.MD | 10 ++ .../FileTypeDetectionLib.vbproj | 4 +- src/FileTypeDetection/PublicAPI.Shipped.txt | 144 ++++++++++++++++++ src/FileTypeDetection/PublicAPI.Unshipped.txt | 0 src/FileTypeDetection/packages.lock.json | 18 +++ 18 files changed, 270 insertions(+), 7 deletions(-) create mode 100644 src/FileTypeDetection/PublicAPI.Shipped.txt create mode 100644 src/FileTypeDetection/PublicAPI.Unshipped.txt 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, )",