From b7de32ba370ebc6465cf3a40b3afeb44f3a4dfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FabioLeit=C3=A3o?= Date: Wed, 15 Jul 2026 18:12:10 -0300 Subject: [PATCH] chore(release): 1.7.4.post5 PyPI publish counter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump version and maturity_build (.226 → .240, N=14 fix( since post4 merge 656fdc3d). PyPI-only prep — no tag/Release/container. --- CHANGELOG.md | 19 ++++++ core/about.py | 2 +- docs/releases/1.7.4.post5.md | 106 +++++++++++++++++++++++++++++ pyproject.toml | 6 +- tests/test_pyproject_sql_extras.py | 4 +- uv.lock | 2 +- 6 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 docs/releases/1.7.4.post5.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a62666..d560b697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,25 @@ Human-readable summary of user-facing changes. **Detailed release notes:** [docs --- +## 1.7.4.post5 (pending PyPI dispatch) + +> Post-release on the **`1.7.4`** public line. **`[project] version = 1.7.4.post5`** and **`[tool.databoar] maturity_build = 240`** (`N=14` `fix(` commits since post4 merge `656fdc3d`, ADR-0073). **PyPI-only** — no Git tag, no GitHub Release, no container. + +### Fixed / hardened (post5) + +- **Archives (.7z):** content scan via py7zr `BytesIOFactory` + pre-budget member extract (#1250, #1248). +- **Sessions:** orphan `running` reaper (PID liveness, TOCTOU-safe conditional UPDATE) + interrupt → `interrupted` (#1251). +- **CLI:** `--validate-config` **WARN** when optional SQL driver deps are missing (offline probe) (#1246). +- **Security:** standalone HTML form CSRF (#1231); Dataverse `org_url` / `token_url` SSRF guards (#1232); aggregate archive decompression budgets (#1233); secret-by-identity lock + reachable JWT GRACE (#1210, #1212); non-numeric / non-finite license/budget hardening; drop `Invoke-Expression` from `external-review-pack.ps1` (#1192). +- **Integrity:** honest `build_digest_matched` (no `signature_ok` overclaim) + legacy migrate zeroing (#1211). +- **OPSEC / lint:** LICENSING_SPEC evasion-vector redaction (#1234, #1235); markdown-lint git-tracked only (#1240); skills OPSEC / ATS footer path (#1191). + +### Notes (post5) + +- Full `N=14` fix set and `postN` ↔ `maturity_build` map: [docs/releases/1.7.4.post5.md](docs/releases/1.7.4.post5.md). + +--- + ## 1.7.4.post4 (pending PyPI dispatch) > Post-release on the **`1.7.4`** public line. **`[project] version = 1.7.4.post4`** and **`[tool.databoar] maturity_build = 225`** (`N=14` fixes since post3 baseline, ADR-0073 dual counter policy). diff --git a/core/about.py b/core/about.py index 73de76d6..1e318368 100644 --- a/core/about.py +++ b/core/about.py @@ -11,7 +11,7 @@ def _package_version() -> str: return version("data-boar") except Exception: - return "1.7.4.post4" + return "1.7.4.post5" def get_http_user_agent() -> str: diff --git a/docs/releases/1.7.4.post5.md b/docs/releases/1.7.4.post5.md new file mode 100644 index 00000000..c4d89959 --- /dev/null +++ b/docs/releases/1.7.4.post5.md @@ -0,0 +1,106 @@ +# Release 1.7.4.post5 (PyPI publish counter) + +**Status:** Pending PyPI upload after merge (operator **`publish-pypi`** `workflow_dispatch`: build → TestPyPI → PyPI). + +**Public line (marketing):** **`1.7.4`** — README, man pages, stakeholder copy unchanged. + +**Build / PyPI / About:** **`1.7.4.post5`** — PEP 440 post-release (publish counter per [ADR-0073](../adr/ADR-0073-version-scheme-octet-maturity-and-roadmap.md) § *PyPI dual counters*). + +**Not in this drop:** Git tag · GitHub Release · Docker / container image (PyPI-only `.postN`). + +--- + +## Mandatory map: `postN` ↔ `maturity_build` + +Per ADR-0073: **`postN`** counts **PyPI uploads**; **`maturity_build`** counts **discrete fixes** and may run ahead. This map is the mandatory audit trail. + +| PyPI / `[project] version` | `maturity_build` (octet) | Notes | +| --- | --- | --- | +| **`1.7.4`** | **`.201`** | GA on PyPI (immutable); release PR **#1024** | +| **`1.7.4.post1`** | **`.202`** | SQL drivers → optional extras ([#1047](https://github.com/DataBoar/data-boar/issues/1047)) — published | +| *(fix, unpublished on PyPI)* | **`.203`** | [#1026](https://github.com/DataBoar/data-boar/pull/1026) | +| *(fix, unpublished on PyPI)* | **`.204`** | [#1028](https://github.com/DataBoar/data-boar/pull/1028) | +| *(fix, unpublished on PyPI)* | **`.205`** | Deploy / packaging fix train | +| *(fix, unpublished on PyPI)* | **`.206`** | `main.py --version` without config | +| *(fix, unpublished on PyPI)* | **`.207`** | `fix(connectors)` symlink / reparse-point loop guard ([#1080](https://github.com/DataBoar/data-boar/pull/1080)) | +| **`1.7.4.post2`** | **`.208`** | Prior upload on this line | +| *(fix, unpublished on PyPI)* | **`.209`** | SQL sampling failures now surface in `scan_failures` ([#1140](https://github.com/DataBoar/data-boar/issues/1140), [#1144](https://github.com/DataBoar/data-boar/pull/1144)) | +| *(fix, unpublished on PyPI)* | **`.210`** | Encrypted/corrupt archive members now surface in `scan_failures` (open-core slice of [#828](https://github.com/DataBoar/data-boar/issues/828), [#1146](https://github.com/DataBoar/data-boar/pull/1146)) | +| **`1.7.4.post3`** | **`.211`** | Published with `soupsieve` CVE fix ([#1177](https://github.com/DataBoar/data-boar/pull/1177)) | +| *(fix, unpublished on PyPI)* | **`.212`** | RBAC now defaults to deny on the full route map (#1133). | +| *(fix, unpublished on PyPI)* | **`.213`** | API key comparison now uses UTF-8 byte-safe `compare_digest` (#1150). | +| *(fix, unpublished on PyPI)* | **`.214`** | Operator-gated reopen workflow pins were restored to keep governance automation stable. | +| *(fix, unpublished on PyPI)* | **`.215`** | SQL sampling transaction scope is now isolated per connection (#1194). | +| *(fix, unpublished on PyPI)* | **`.216`** | One-class compliance profiles now preserve declared-term detections (#1195). | +| *(fix, unpublished on PyPI)* | **`.217`** | XLSX exports now neutralize formula-leading cells to prevent spreadsheet injection (#1201). | +| *(fix, unpublished on PyPI)* | **`.218`** | Web exposure defaults now enforce a safe-by-default posture for remote surface (#1202). | +| *(fix, unpublished on PyPI)* | **`.219`** | Follow-up CodeQL logging and import-cycle hardening landed on the web-exposure path (#1202). | +| *(fix, unpublished on PyPI)* | **`.220`** | Remaining routes-context import cycle was removed to stabilize route wiring. | +| *(fix, unpublished on PyPI)* | **`.221`** | Config redaction now masks DSN/URL embedded credentials in `/config` (#1137). | +| *(fix, unpublished on PyPI)* | **`.222`** | Prefilter now preserves recall parity with active profile terms/regexes (#1198). | +| *(fix, unpublished on PyPI)* | **`.223`** | Help output now aligns dev invocation and installed command contract (#1130). | +| *(fix, unpublished on PyPI)* | **`.224`** | Demo sessions now resolve audit trail correctly via `/logs/{session_id}` (#1218). | +| *(fix, unpublished on PyPI)* | **`.225`** | Logs fallback hardening removed the CodeQL path-injection sink in demo retrieval (#1218, `4bd3e5bc`). | +| **`1.7.4.post4`** | **`.226`** | Pillow `12.2.0` → `12.3.0` (PYSEC-2026-2253..2257); baseline post3 + `N=15`. | +| *(fix, unpublished on PyPI)* | **`.227`** | Align ATS import footer skill path to private (#1191). | +| *(fix, unpublished on PyPI)* | **`.228`** | Standalone HTML form CSRF without WebAuthn (#1231). | +| *(fix, unpublished on PyPI)* | **`.229`** | Dataverse `org_url` / `token_url` SSRF guards (#1232). | +| *(fix, unpublished on PyPI)* | **`.230`** | Aggregate archive decompression budgets (#1233). | +| *(fix, unpublished on PyPI)* | **`.231`** | Reject non-finite `max_expansion_ratio` (nan/inf). | +| *(fix, unpublished on PyPI)* | **`.232`** | Secret-by-identity lock + reachable JWT GRACE (#1210, #1212). | +| *(fix, unpublished on PyPI)* | **`.233`** | Fail-closed on non-numeric license `exp` claim. | +| *(fix, unpublished on PyPI)* | **`.234`** | Honest `build_digest_matched` (no `signature_ok` overclaim) (#1211). | +| *(fix, unpublished on PyPI)* | **`.235`** | Zero legacy `build_digest_matched` bit on migrate (#1211). | +| *(fix, unpublished on PyPI)* | **`.236`** | Drop `Invoke-Expression` from `external-review-pack.ps1` (#1192). | +| *(fix, unpublished on PyPI)* | **`.237`** | Read `.7z` members via py7zr `BytesIOFactory` (#1250, #1248). | +| *(fix, unpublished on PyPI)* | **`.238`** | Extract pre-budget `.7z` members on budget stop (#1250, #1248). | +| *(fix, unpublished on PyPI)* | **`.239`** | Orphan session reaper (PID liveness) + interrupt → `interrupted` (#1251). | +| **`1.7.4.post5`** | **`.240`** | **This upload** — TOCTOU-safe reaper UPDATE + post5 wave; baseline `1.7.4.post4` + `N=14` `fix(` commits. | + +--- + +## Appendix — Fix set used for `N` (`N=14`) (git-literal) + +**Boundary:** merge of release PR **#1224** (`656fdc3d` — `chore(release): 1.7.4.post4`). + +```bash +git log 656fdc3d..HEAD --format='%h %s' | rg '^[0-9a-f]+ fix\(' +# COUNT=14 → maturity_build = 226 + 14 = 240 +``` + +Commits counted (newest first, as returned by `git log`): + +1. `68119f93` — `fix(session): conditional UPDATE in orphan reaper (TOCTOU)` +2. `ecefa7c2` — `fix(session): reap orphan running sessions and mark interrupts` +3. `0755f6b9` — `fix(archives): extract pre-budget .7z members on budget stop` +4. `707549ed` — `fix(archives): read .7z members via py7zr BytesIOFactory` +5. `c80e2046` — `fix(security): drop Invoke-Expression from external-review-pack.ps1` +6. `a4b5d9fe` — `fix(integrity): zero legacy build_digest_matched bit on migrate` +7. `026f17ad` — `fix(integrity): honest build_digest_matched instead of signature_ok overclaim` +8. `72ad6d75` — `fix(security): fail-closed on non-numeric license exp claim` +9. `f3313c4a` — `fix(security): lock secret-by-identity and reachable JWT GRACE (#1210 #1212)` +10. `7e714b68` — `fix(security): reject non-finite max_expansion_ratio (nan/inf)` +11. `30cd501c` — `fix(security): aggregate archive decompression budgets (#1233)` +12. `451580a1` — `fix(security): guard Dataverse org_url and token_url against SSRF (#1232)` +13. `69bb082f` — `fix(security): enforce standalone HTML form CSRF without WebAuthn (#1231)` +14. `e64ad41e` — `fix(scripts): align ATS import footer skill path to private (#1191)` + +**Not counted toward `N` (not `fix(`):** `feat(cli)` validate-config optional-driver WARN (#1246 / #1255); `docs(security)` LICENSING_SPEC (#1234/#1235); `chore` markdown-lint (#1240); `security(cursor)` skills OPSEC harness commits under #1191 that are not `fix(`. + +--- + +## Highlights (why post5) + +- Demo-relevant archive and session reliability: `.7z` content scanning restored; orphan `running` sessions reaped safely under concurrent scans. +- Trust-floor / security train from post4 follow-ups now packaged: CSRF, Dataverse SSRF, archive bomb budgets, JWT GRACE / secret-by-identity, integrity digest honesty. +- Operator hygiene: external-review-pack without `Invoke-Expression`; optional SQL driver absence visible in `--validate-config` (bundled feat, not in `N`). + +--- + +## Install + +```bash +pip install 'data-boar==1.7.4.post5' +``` + +See [USAGE.md](../USAGE.md), [QUICKSTART.md](../QUICKSTART.md), and [TROUBLESHOOTING.md](../TROUBLESHOOTING.md). diff --git a/pyproject.toml b/pyproject.toml index 5525062b..83e2aa21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "data-boar" -version = "1.7.4.post4" +version = "1.7.4.post5" description = "Data Boar — compliance-aware discovery and mapping of personal and sensitive data across databases, files, and APIs (LGPD, GDPR, CCPA, and configurable frameworks)." readme = "README.md" requires-python = ">=3.12" @@ -302,6 +302,6 @@ dev = [ ] # Operator-only maturity octet (ADR-0073). Never copy into [project].version. -# postN <-> maturity_build map: docs/releases/1.7.4.post3.md (canonical; includes post1/post2 rows). +# postN <-> maturity_build map: docs/releases/1.7.4.post5.md (canonical; includes post1–post4 rows). [tool.databoar] -maturity_build = 226 +maturity_build = 240 diff --git a/tests/test_pyproject_sql_extras.py b/tests/test_pyproject_sql_extras.py index 8fcf05b6..502dbb6a 100644 --- a/tests/test_pyproject_sql_extras.py +++ b/tests/test_pyproject_sql_extras.py @@ -64,11 +64,11 @@ def test_sql_optional_extras_present() -> None: def test_maturity_build_bumped_for_packaging_fix() -> None: data = _load_pyproject() maturity = data.get("tool", {}).get("databoar", {}).get("maturity_build") - assert maturity == 226 + assert maturity == 240 def test_version_is_174_post_release_not_semver_bump() -> None: version = _load_pyproject().get("project", {}).get("version") - assert version == "1.7.4.post4" + assert version == "1.7.4.post5" assert not str(version).startswith("1.7.5") assert not str(version).startswith("1.8.") diff --git a/uv.lock b/uv.lock index 8bb68964..eac88509 100644 --- a/uv.lock +++ b/uv.lock @@ -800,7 +800,7 @@ validation = [ [[package]] name = "data-boar" -version = "1.7.4.post4" +version = "1.7.4.post5" source = { editable = "." } dependencies = [ { name = "annotated-doc" },