Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2.52
2.2.53
51 changes: 51 additions & 0 deletions docs/BUGFIX/CLEANUP_HARDLINK_FREED_SPACE.md
Original file line number Diff line number Diff line change
@@ -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

<!-- docs:section summary -->
## 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`.

<!-- docs:section details -->
## 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.

<!-- docs:section validation -->
## 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).

<!-- docs:section risks -->
## 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.
7 changes: 7 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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ć
Expand Down
54 changes: 54 additions & 0 deletions docs/SERVICE/SCAN_PERFORMANCE.md
Original file line number Diff line number Diff line change
@@ -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

<!-- docs:section summary -->
## 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.

<!-- docs:section details -->
## 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.

<!-- docs:section validation -->
## 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).

<!-- docs:section risks -->
## 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.
36 changes: 36 additions & 0 deletions project/ticket-072/README.md
Original file line number Diff line number Diff line change
@@ -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.
91 changes: 91 additions & 0 deletions project/ticket-072/intent.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading