fix(12.1): make cloud freshness authoritative — plan 02 documentation and version

- Version bump 0.2.3 → 0.2.4 (user-visible sync status corrected)
- CLAUDE.md: update current state; add apply_listing_and_finalize to module map; add no-independent-fresh rule
- README.md: bump version
- RUNBOOK.md: update freshness state docs; explain complete=True gate and last_refreshed_at behavior
- SECURITY.md: add T-12.1-06..10 threat closure evidence for Plan 02
This commit is contained in:
curo1305
2026-06-22 08:34:51 +02:00
parent bfa4dc502a
commit 70a543a8c1
6 changed files with 28 additions and 6 deletions
+20
View File
@@ -417,3 +417,23 @@ Integration tests activate with `INTEGRATION=1` against a disposable PostgreSQL
**Gate 3 — No new Python or frontend packages introduced.**
**Gate 4 — No hardcoded credentials in Compose or test files.**
---
## Phase 12.1 Plan 02 — Truthful Freshness Gate
| Threat ID | Threat | Mitigation disposition | Status | Evidence |
|-----------|--------|----------------------|--------|---------|
| T-12.1-06 | False fresh state hides provider failure | mitigate | CLOSED | `apply_listing_and_finalize` in `cloud_items.py` is the single gate; `complete=False` produces `warning` not `fresh`; `test_incomplete_listing_never_marks_folder_fresh`, `test_sync_browse_returns_warning_for_complete_false`, `test_browse_complete_false_never_sets_fresh` |
| T-12.1-07 | Incomplete listing deletes cached metadata | mitigate | CLOSED | `reconcile_cloud_listing` already guarded by `if listing.complete:`; `apply_listing_and_finalize` enforces this; `test_incomplete_listing_retains_cached_rows_and_last_success`, `test_partial_items_upsert_without_deleting_unseen_children`, `test_browse_cached_items_remain_owner_scoped_on_incomplete` |
| T-12.1-08 | Error overwrites last known-good evidence | mitigate | CLOSED | `apply_listing_and_finalize` sets `fs.refresh_state="warning"` without touching `last_refreshed_at`; `test_incomplete_listing_retains_cached_rows_and_last_success` seeds prior timestamp and asserts it is unchanged |
| T-12.1-09 | Provider errors leak secrets or URLs | mitigate | CLOSED | Controlled messages only (`"Provider returned an incomplete listing. Showing cached results."`); `ListingResult.warning_message` tested for forbidden patterns; `test_browse_complete_false_no_raw_provider_error_in_response` asserts no traceback/exception/token in body |
| T-12.1-10 | Refresh changes bytes/quota | mitigate | CLOSED | Existing no-byte/no-MinIO/no-quota assertions still pass; `apply_listing_and_finalize` only calls `reconcile_cloud_listing` and `update_folder_state` — no byte IO |
### Phase 12.1 Plan 02 Security Gate Evidence
```
pytest -q backend/tests/test_cloud_items.py backend/tests/test_cloud.py backend/tests/test_cloud_security.py
89 passed
```
Bandit over modified files (`services/cloud_items.py`, `api/cloud/browse.py`, `tasks/cloud_tasks.py`): 0 HIGH, 0 MEDIUM findings.