3825f670a1
VALIDATION.md: Nyquist audit — 3 gaps found, 2 resolved automated (SHARE-03 permission field, SHARE-05 is_shared indicator), 1 escalated to manual-only (STORE-06 requires INTEGRATION=1 PostgreSQL). VERIFICATION.md: was untracked artifact from gsd-verifier run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
101 lines
5.5 KiB
Markdown
101 lines
5.5 KiB
Markdown
---
|
|
phase: "6.1"
|
|
slug: close-v1-audit-gaps
|
|
status: validated
|
|
nyquist_compliant: true
|
|
wave_0_complete: true
|
|
created: 2026-05-30
|
|
audited: 2026-05-30
|
|
gaps_found: 3
|
|
gaps_resolved: 2
|
|
gaps_manual: 1
|
|
---
|
|
|
|
# Phase 6.1 — Validation Strategy
|
|
|
|
> Nyquist validation contract for Phase 6.1: Close v1.0 Audit Gaps (SHARE-01..05, ADMIN-06, STORE-06).
|
|
|
|
---
|
|
|
|
## Test Infrastructure
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Framework** | pytest 9.0.3, pytest-asyncio 1.4.0 |
|
|
| **Config file** | `backend/pytest.ini` — `asyncio_mode = auto`, `testpaths = tests` |
|
|
| **Quick run command** | `docker compose exec backend python -m pytest tests/test_shares.py tests/test_audit.py -v` |
|
|
| **Full suite command** | `docker compose exec backend python -m pytest -v` |
|
|
| **Estimated runtime** | ~2 seconds (shares+audit), ~45 seconds (full suite) |
|
|
|
|
---
|
|
|
|
## Sampling Rate
|
|
|
|
- **After every task commit:** Run `docker compose exec backend python -m pytest tests/test_shares.py tests/test_audit.py -v`
|
|
- **After every plan wave:** Run `docker compose exec backend python -m pytest -v`
|
|
- **Before `/gsd:verify-work`:** Full suite must be green
|
|
- **Max feedback latency:** ~2 seconds (targeted), ~45 seconds (full)
|
|
|
|
---
|
|
|
|
## Per-Task Verification Map
|
|
|
|
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
|
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
|
| 06.1-01-T1 | 01 | 1 | — | — | `second_auth_user` fixture distinct from `auth_user` (no handle collision) | integration | `pytest tests/test_shares.py -v` | ✅ | ✅ green |
|
|
| 06.1-01-T2 | 01 | 1 | SHARE-01 | T-04-04-02 | POST /api/shares 201; 404 on unknown handle | integration | `pytest tests/test_shares.py::test_share_success tests/test_shares.py::test_share_handle_not_found -v` | ✅ | ✅ green |
|
|
| 06.1-01-T2 | 01 | 1 | SHARE-02 | T-04-04-03, T-04-04-04 | /received has metadata only (no extracted_text); recipient quota unchanged | integration | `pytest tests/test_shares.py::test_shared_with_me tests/test_shares.py::test_share_no_quota_impact -v` | ✅ | ✅ green |
|
|
| 06.1-01-T2 | 01 | 1 | SHARE-03 | — | shares default to permission="view"; POST and GET list both assert field value | integration | `pytest tests/test_shares.py::test_share_default_permission_view -v` | ✅ | ✅ green |
|
|
| 06.1-01-T2 | 01 | 1 | SHARE-04 | T-04-04-02 | DELETE 204 removes share; IDOR: recipient DELETE → 404 not 403 | integration | `pytest tests/test_shares.py::test_revoke_share tests/test_shares.py::test_share_revoke_wrong_owner_404 -v` | ✅ | ✅ green |
|
|
| 06.1-01-T2 | 01 | 1 | SHARE-05 | — | Owner's GET /api/documents shows is_shared=True after sharing; False before | integration | `pytest tests/test_shares.py::test_share_indicator_in_owner_list -v` | ✅ | ✅ green |
|
|
| 06.1-02-T1 | 02 | 1 | ADMIN-06 | D-15 | paginated viewer shape; no filename/extracted_text/password_hash/credentials_enc in items or metadata_; admin gate 403; filter by event_type narrows results; CSV export | integration | `pytest tests/test_audit.py -v` | ✅ | ✅ green |
|
|
|
|
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
|
|
|
---
|
|
|
|
## Wave 0 Requirements
|
|
|
|
Existing infrastructure covered all phase requirements. No Wave 0 work needed.
|
|
|
|
- `backend/tests/conftest.py` — `async_client`, `auth_user`, `admin_user`, `db_session` fixtures (pre-existing)
|
|
- `second_auth_user` fixture added in Plan 06.1-01 Task 1 (commit b7df971)
|
|
|
|
---
|
|
|
|
## Manual-Only Verifications
|
|
|
|
| Behavior | Requirement | Why Manual | Test Instructions |
|
|
|----------|-------------|------------|-------------------|
|
|
| `test_delete_decrements_quota` passes as PASSED (not XFAIL) under live PostgreSQL | STORE-06 | `test_quota.py:196` has `@pytest.mark.xfail(strict=False, reason="requires PostgreSQL for atomic UUID-typed quota SQL")` — runs as xfail on SQLite. Live PostgreSQL required to confirm the atomic `GREATEST(0, used_bytes - delta)` SQL works correctly. | Run: `INTEGRATION=1 docker compose exec backend python -m pytest tests/test_quota.py::test_delete_decrements_quota -v` — expect `PASSED`, not `XFAIL` or `XPASS`. |
|
|
|
|
---
|
|
|
|
## Validation Sign-Off
|
|
|
|
- [x] All tasks have automated verify commands
|
|
- [x] Sampling continuity: no 3 consecutive tasks without automated verify
|
|
- [x] Wave 0: no stubs — all tests implemented with real assertions
|
|
- [x] No watch-mode flags
|
|
- [x] Feedback latency < 5s (targeted suite)
|
|
- [x] `nyquist_compliant: true` set in frontmatter
|
|
|
|
**Approval:** validated 2026-05-30
|
|
|
|
---
|
|
|
|
## Validation Audit 2026-05-30
|
|
|
|
| Metric | Count |
|
|
|--------|-------|
|
|
| Requirements assessed | 7 (SHARE-01..05, ADMIN-06, STORE-06) |
|
|
| Gaps found | 3 (SHARE-03 partial, SHARE-05 missing, STORE-06 partial) |
|
|
| Resolved (automated) | 2 (SHARE-03, SHARE-05 — new tests added) |
|
|
| Escalated to manual-only | 1 (STORE-06 — requires live PostgreSQL INTEGRATION=1) |
|
|
| Tests added this audit | 2 (`test_share_default_permission_view`, `test_share_indicator_in_owner_list`) |
|
|
| Total phase tests after audit | 14 (9 shares + 5 audit) |
|
|
|
|
### Note on VERIFICATION.md stale state
|
|
|
|
The existing `06.1-VERIFICATION.md` was generated before commit `451fff1` (which added `test_audit_log_filter_by_event_type`) and incorrectly listed "Gap 1 — audit filter behavioral tests missing" as unresolved. At audit time, `test_audit.py` contained 5 tests (not 4 as stated), and Gap 1 was already closed. The VERIFICATION.md gap count of 2 was reduced to 1 real gap (STORE-06) for this audit, plus 2 test-coverage gaps (SHARE-03, SHARE-05) that were resolved here.
|