diff --git a/VERSION b/VERSION index 9b6e760..921e37d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.52 +2.2.53 diff --git a/docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md b/docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md new file mode 100644 index 0000000..9603e75 --- /dev/null +++ b/docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md @@ -0,0 +1,51 @@ +--- +{ + "schema": "wellmanifest.docs/document/v2", + "id": "cleanup-hardlink-freed-space", + "kind": "bugfix", + "version": 1, + "title": "fixos cleanup reports only space really returned to the filesystem", + "status": "accepted", + "owner": "semcod/fixos", + "scope": "repository", + "updated": "2026-10-13", + "source_revision": "975468a43e78886f0c3540d527651d3de5987d0b", + "priority": "P1", + "evidence": ["https://github.com/semcod/fixos/pull/98"] +} +--- + +# fixos cleanup reports only space really returned to the filesystem + + +## Cel i rezultat + +On 2026-10-13 `fixos cleanup -s npm,uv,pnpm,conda,pip,go,cargo --yes` +reported 5.62 GB freed while `df` showed about 4.2 GB. After the fix +`space_freed_gb` counts only blocks that left the filesystem; bytes still +linked from elsewhere are reported as `shared_hardlink_gb`. + + +## Zakres i rozwiązanie + +uv, pnpm and conda hardlink cache files into environments. Deleting the +cache link frees nothing while the environment link survives, but +`ServiceCleaner.cleanup_service` used the directory-size drop. +`ServiceCleaner._shared_hardlink_bytes` sums allocated bytes of regular files +whose inode has more links than are seen inside the planned paths. It is +measured before and after the cleanup command and subtracted from the +size delta. Docker keeps its daemon-based measurement. + + +## Weryfikacja + +`TestHardlinkAwareFreedSpace` in `tests/unit/test_service_cleanup.py` builds +real hardlinks on `tmp_path`; it fails on `fcef9db` and passes with the fix. +110 cleanup tests and `./project/governance-check.sh` pass (ticket-069). + + +## Ryzyka i następny krok + +The extra walk costs one `lstat` per file in the cleaned cache. Rollback: +revert ticket-069. Dry-run estimates still show the directory size as an +upper bound; making them hardlink-aware is a possible follow-up. diff --git a/docs/README.md b/docs/README.md index 38c9cc8..9e84a1d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,6 +19,13 @@ Ta dokumentacja dotyczy narzędzia do diagnostyki i naprawy systemu fixOS. - [CONTRIBUTING](CONTRIBUTING.md) — uruchamianie testów i zasady zmian. - [TODO](../TODO.md) — wyłącznie aktywne, ręcznie zweryfikowane zadania. +## Zmiany (wellmanifest/docs v2) + +- [BUGFIX: zwolnione miejsce przy hardlinkach](BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md) + — `space_freed_gb` liczy tylko bloki zwrócone systemowi plików. +- [SERVICE: wydajność skanów](SERVICE/SCAN_PERFORMANCE.md) — budżet czasu + `fixos quick` i jednorazowy pomiar `/tmp`. + ## Ważne Strony `api.md`, `modules.md`, `coverage.md` i `dependency-graph.md` mogą być diff --git a/docs/SERVICE/SCAN_PERFORMANCE.md b/docs/SERVICE/SCAN_PERFORMANCE.md new file mode 100644 index 0000000..c891898 --- /dev/null +++ b/docs/SERVICE/SCAN_PERFORMANCE.md @@ -0,0 +1,54 @@ +--- +{ + "schema": "wellmanifest.docs/document/v2", + "id": "scan-performance", + "kind": "service", + "version": 1, + "title": "fixos quick stays within its time budget and cleanup sizes /tmp in one pass", + "status": "accepted", + "owner": "semcod/fixos", + "scope": "repository", + "updated": "2026-10-13", + "source_revision": "d168071323693191be9c786ac69a18c56928beb6", + "priority": "P1", + "evidence": ["https://github.com/semcod/fixos/pull/99"] +} +--- + +# fixos quick stays within its time budget and cleanup sizes /tmp in one pass + + +## Cel i rezultat + +On a loaded host (load ~65 on 16 CPUs) `fixos cleanup --list` took 110 s and +`fixos quick` 13–72 s. Measured on the same host after ticket-070: +`_scan_tmp()` over 10 102 entries 36.7 s → 0.7 s, `fixos quick` 7.6 s → 2.7 s, +with identical candidates and cache sizes. + + +## Zakres i rozwiązanie + +- `_scan_tmp` started one `du` per stale `/tmp` entry. `_dir_sizes` now runs + one `du -sbl0` per 512 directories; `--count-links` keeps per-directory + results and NUL output survives any file name. Missing entries fall back to + the per-entry measurement. +- `native_scan.measure_batch` accepts `timeout` and `python_fallback`. quick + passes `2 × cache_timeout` and no Python walk, so a slow disk can no longer + stretch it to minutes. Results are looked up by resolved path. +- A cache that misses the budget shows its last complete size from quick + history with `last_complete_at`; it stays `complete: false` and is excluded + from growth comparisons. + + +## Weryfikacja + +New tests in `test_cleanup_tmp.py`, `test_native_scan.py` and +`test_quick_snapshot.py`; 80 tests in the related suites and +`./project/governance-check.sh` pass (ticket-070). + + +## Ryzyka i następny krok + +Under extreme I/O a cache may be shown from history instead of measured. +Rollback: revert ticket-070. Next hotspot: `_discover_xdg_cache_dirs` walks all +of `~/.cache` (~34 s on the same host) and could reuse a cached measurement. diff --git a/project/ticket-072/README.md b/project/ticket-072/README.md new file mode 100644 index 0000000..84e0f47 --- /dev/null +++ b/project/ticket-072/README.md @@ -0,0 +1,36 @@ +# Ticket 072: docs for hardlink-aware freed space and scan performance; release 2.2.53 + +- **ID**: ticket-072 +- **Owner**: claude +- **Status**: IN_PROGRESS +- **Workflow state**: EDIT +- **Created**: 2026-10-13 + +## Goal and scope + +- Compact v2 documents (`wellmanifest/docs` 19efafb): + [BUGFIX](../../docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md) for ticket-069 and + [SERVICE](../../docs/SERVICE/SCAN_PERFORMANCE.md) for ticket-070, linked from + `docs/README.md`. +- Release projection: `VERSION` and `pyproject.toml` declare 2.2.53, packaging + tickets 069-071. `goal -a --bump patch` could not do it: goal 2.2.0 rejects + fixos's computed-version `setup.py` ("selector version was not found"), + fixed in semcod/goal#188. As in ticket-067 the carriers are bumped here; + registry publication runs after merge via `goal -a --delivery-mode + publish-only` once goal#188 is merged. + +The docs checker passes both deliverables; its remaining findings concern the +managed `.governance/docs/SNAPSHOT_MIGRATION.md` from the new-project package, +which cannot be edited locally without breaking the managed digest. + +SESSION_EXECUTION_AUTHORIZATION: user requested a version bump and publication through `goal -a`. + +## Acceptance criteria + +- [x] AC-01: both documents exist, are indexed and pass `docs/standard/check.py`. +- [x] AC-02: `test_version_parity.py` and `./project/governance-check.sh` pass. + +## Tracking boundary + +This directory contains the minimal reviewed intent. Optional participant prose +and raw command logs are not required delivery output. diff --git a/project/ticket-072/intent.json b/project/ticket-072/intent.json new file mode 100644 index 0000000..db52df4 --- /dev/null +++ b/project/ticket-072/intent.json @@ -0,0 +1,91 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-072", + "summary": "docs for hardlink-aware freed space and scan performance; release 2.2.53", + "workstream": "integration", + "classification": { + "kind": "SERVICE", + "priority": "P2", + "origin": "requested" + }, + "allowedPaths": [ + "project/ticket-072/**", + "TODO.md", + "project/TICKETS.md", + "VERSION", + "docs/BUGFIX/**", + "docs/README.md", + "docs/SERVICE/**", + "pyproject.toml" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md" + ], + "stacks": [ + "python" + ], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "48f7ba713b84a3558636bc5dad4f48a8bbee2fa5", + "targetBranch": "main", + "outcome": "Compact v2 docs (wellmanifest/docs) describe the hardlink-aware freed-space report and the scan performance budget, and version carriers declare 2.2.53 so the release packages tickets 069-070.", + "nonGoals": [ + "No runtime code change.", + "Registry publication happens only after merge, via goal publish-only." + ], + "complexity": "S", + "estimatedMinutes": 20, + "budgets": { + "maxImplementationFiles": 5, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "One BUGFIX and one SERVICE compact document linked from docs/README.md; release bump via goal.", + "components": [ + { + "name": "docs-and-release", + "paths": [ + "docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md", + "docs/SERVICE/SCAN_PERFORMANCE.md", + "docs/README.md", + "VERSION", + "pyproject.toml" + ] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": { + "impact": "none", + "states": [], + "evidence": [] + }, + "rollback": "Revert the commit." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": [ + "test -f docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md", + "test -f docs/SERVICE/SCAN_PERFORMANCE.md" + ], + "evidence": "project/ticket-072/README.md" + }, + { + "criterion": "AC-02", + "commands": [ + "pytest -q tests/unit/test_version_parity.py", + "./project/governance-check.sh" + ], + "evidence": "project/ticket-072/README.md" + } + ] + } +} diff --git a/pyproject.toml b/pyproject.toml index f3366f9..f2acfc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "fixos" -version = "2.2.52" +version = "2.2.53" description = "AI-powered Linux/Windows diagnostics and repair – audio, hardware, system issues" readme = "README.md" requires-python = ">=3.10"