- Flip v1.0-VALIDATION-INDEX.md frontmatter draft -> signed-off (Sébastien QUEROL, 2026-04-13) - Tick index sign-off line (45/45 pass, 0 fail-fix-v1.1) - Replicate dated sign-off line into all 7 per-phase VALIDATION.md Validation Sign-Off blocks - Tick nyquist_compliant checkbox in phases 01/02/03/04/05/07 (06 already ticked) - Upgrade Approval lines phases 01-05 from 'pending' to signed-off with index back-link - Tick REQUIREMENTS.md NYQ-02/NYQ-03 and flip Traceability Pending -> Complete - Phase 4 attestation-only runtime gap recorded in index Residual Risk block (not reopened per plan 10-03 sign-off)
10 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created, nyquist_audited, nyquist_auditor
| phase | slug | status | nyquist_compliant | wave_0_complete | created | nyquist_audited | nyquist_auditor |
|---|---|---|---|---|---|---|---|
| 2 | driver-management | draft | true | false | 2026-04-10 | 2026-04-13 | Claude (gsd-executor, plan 08-02) |
Phase 2 — Validation Strategy
Per-phase validation contract for feedback sampling during execution.
Test Infrastructure
| Property | Value |
|---|---|
| Framework | pytest (already installed in requirements-dev.txt from Phase 1) |
| Config file | None — uses pytest auto-discovery |
| Quick run command | pytest tests/ -x -q |
| Full suite command | pytest tests/ -v |
| Estimated runtime | ~5 seconds |
Sampling Rate
- After every task commit: Run
pytest tests/ -x -q - After every plan wave: Run
pytest tests/ -v - Before
/gsd:verify-work: Full suite must be green - Max feedback latency: 10 seconds
Per-Task Verification Map
| Task ID | Plan | Wave | Requirement | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|
| 02-01-01 | 01 | 1 | DRV-01 | integration | pytest tests/test_driver_upload.py::test_upload_valid_zip -x |
❌ W0 | ⬜ pending |
| 02-01-02 | 01 | 1 | DRV-01 | unit | pytest tests/test_driver_upload.py::test_upload_non_zip -x |
❌ W0 | ⬜ pending |
| 02-01-03 | 01 | 1 | DRV-01 | unit | pytest tests/test_driver_upload.py::test_upload_no_inf -x |
❌ W0 | ⬜ pending |
| 02-02-01 | 02 | 1 | DRV-02 | unit | pytest tests/test_inf_parser.py::test_simple_driver_desc -x |
❌ W0 | ⬜ pending |
| 02-02-02 | 02 | 1 | DRV-02 | unit | pytest tests/test_inf_parser.py::test_token_resolution -x |
❌ W0 | ⬜ pending |
| 02-02-03 | 02 | 1 | DRV-02 | unit | pytest tests/test_inf_parser.py::test_utf16_encoding -x |
❌ W0 | ⬜ pending |
| 02-02-04 | 02 | 1 | DRV-02 | unit | pytest tests/test_inf_parser.py::test_multi_model_inf -x |
❌ W0 | ⬜ pending |
| 02-03-01 | 03 | 2 | DRV-03 | integration | pytest tests/test_driver_upload.py::test_drivers_page -x |
❌ W0 | ⬜ pending |
| 02-03-02 | 03 | 2 | DRV-03 | integration | pytest tests/test_driver_upload.py::test_upload_returns_select -x |
❌ W0 | ⬜ pending |
| 02-04-01 | 01 | 1 | DRV-04 | integration | pytest tests/test_driver_upload.py::test_driver_persisted -x |
❌ W0 | ⬜ pending |
| 02-04-02 | 01 | 1 | DRV-04 | integration | pytest tests/test_driver_upload.py::test_dedup_upload -x |
❌ W0 | ⬜ pending |
| 02-05-01 | 02 | 1 | DRV-05 | unit | pytest tests/test_inf_parser.py::test_unused_files -x |
❌ W0 | ⬜ pending |
| 02-05-02 | 03 | 2 | DRV-05 | integration | pytest tests/test_driver_upload.py::test_unused_files_in_response -x |
❌ W0 | ⬜ pending |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
tests/test_inf_parser.py— stubs for DRV-02 (INF parsing, token resolution, encoding, multi-model)tests/test_driver_upload.py— stubs for DRV-01, DRV-03, DRV-04, DRV-05 (upload endpoint integration tests)tests/fixtures/sample.inf— minimal valid INF fixture with%TOKEN%valuestests/fixtures/sample_utf16.inf— UTF-16 LE encoded INF fixturetests/fixtures/sample_multi_model.inf— INF with NTamd64 and undecorated sectionsimptune/services/__init__.py— package marker (services/ directory)
Framework already installed; conftest.py with tmp_data_dir fixture already covers DB isolation
Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|---|---|---|---|
| Upload form renders correctly in browser | DRV-03 | Visual layout verification | Open /drivers, verify file input and submit button visible |
| Dropdown populated after upload in browser | DRV-03 | HTMX swap visual verification | Upload sample ZIP, verify <select> appears with driver names |
Nyquist Record
Audited 2026-04-13 by Claude (gsd-executor, plan 08-02). One row per Phase 2 success criterion derived from
milestones/v1.0-ROADMAP.mdPhase 2 goal + plan outcomes (DRV-01..05), cross-checked against02-VERIFICATION.md(14/14 observable truths verified 2026-04-10) andREQUIREMENTS.mdv1.0 DRV-0x block. Evidence cites committed tests, source lines, or the dated VERIFICATION report. Status values:pass/fail-fix-v1.1/deferred-v1.2/wont-do.Phase 2 goal (v1.0-ROADMAP.md): "Technicians upload driver packages and select driver names from parsed INF data — no free-text entry."
| # | Success Criterion | Observable Check | Evidence | Status | Notes |
|---|---|---|---|---|---|
| 1 | DRV-01 — User can upload a driver package (ZIP containing INF + supporting files) via the web UI | pytest tests/test_driver_upload.py::test_upload_valid_zip returns 200 on POST /drivers/upload with a synthetic ZIP; ::test_upload_non_zip and ::test_upload_no_inf both return 400 |
tests/test_driver_upload.py::test_upload_valid_zip, ::test_upload_non_zip, ::test_upload_no_inf; imptune/api/drivers.py POST /drivers/upload handler (commit c648fc5); 02-VERIFICATION.md rows 8 + 10 (2026-04-10) |
pass | Three-path coverage (success, non-ZIP, ZIP without INF). |
| 2 | DRV-02 — System parses uploaded INF files and extracts valid driver names (DriverDesc), resolving %TOKEN% references, handling UTF-16/UTF-8/ANSI encodings, and deduping multi-model entries | pytest tests/test_inf_parser.py — 16 tests covering test_simple_driver_desc, test_token_resolution, test_detect_encoding_utf16le/be/utf8bom/ansi, test_utf16_encoding, test_multi_model_inf, test_architecture_detection_*, test_cat_file_detection_* |
tests/test_inf_parser.py (16 tests, 281 lines); imptune/services/inf_parser.py — parse_inf, _detect_encoding, _resolve_tokens (commits 290106d RED, 5056922 GREEN); 02-VERIFICATION.md rows 1-7 |
pass | RawConfigParser(strict=False) + optionxform=str preserves DriverDesc casing; BOM-sniffing for encoding detection. |
| 3 | DRV-03 — User can select a driver name from a parsed-INF dropdown on the drivers page (no free-text entry) | pytest tests/test_driver_upload.py::test_drivers_page (form present) and ::test_upload_returns_select (response contains <select and a parsed driver name) |
tests/test_driver_upload.py::test_drivers_page, ::test_upload_returns_select; imptune/templates/drivers.html (hx-post="/drivers/upload", hx-target="#driver-list"); imptune/templates/partials/driver_list.html (<select aria-label="Driver names">); 02-VERIFICATION.md rows 9 + 14 |
pass | Template always renders <select> even for single-name drivers (decision in 02-02-SUMMARY). Real-browser HTMX swap covered by row 6. |
| 4 | DRV-04 — Uploaded driver packages are persisted to the Docker volume (DRIVERS_DIR) under SHA256 content-addressed names and survive container restart; re-uploading the same ZIP does not duplicate the Driver record |
pytest tests/test_driver_upload.py::test_driver_persisted (file lands on disk under tmp_data_dir/drivers/) and ::test_dedup_upload (2 uploads → Driver.select().where(sha256==...).count() == 1) |
tests/test_driver_upload.py::test_driver_persisted, ::test_dedup_upload; imptune/storage/driver_store.py::DriverStore.save (SHA256-named files); imptune/api/drivers.py lines 85-99 (DriverStore(_cfg.DRIVERS_DIR).save(data) → Driver.get_or_create(sha256=…)); 02-VERIFICATION.md rows 11 + 12 |
pass | Content-addressed storage gives dedup for free. _cfg.DRIVERS_DIR read dynamically at call time so monkeypatch works in tests (02-02-SUMMARY decision). |
| 5 | DRV-05 — System flags unused files (files in ZIP not referenced by the INF) to help technicians reduce driver package size | pytest tests/test_inf_parser.py::test_unused_files (parser returns unused_files list) and pytest tests/test_driver_upload.py::test_unused_files_in_response (word "unused" present in response HTML) |
tests/test_inf_parser.py::test_unused_files; tests/test_driver_upload.py::test_unused_files_in_response; imptune/services/inf_parser.py ParsedInf.unused_files; imptune/templates/partials/driver_list.html unused-files notice; 02-VERIFICATION.md rows 5 + 13 |
pass | |
| 6 | DRV-01 runtime gap — POST /drivers/upload must not return HTTP 500 on real driver ZIPs uploaded via the browser (reported 2026-04-13 during Phase 8 kickoff; parallel to the v1.1 UX-01 DriverDesc-refresh requirement) |
pytest tests/test_driver_upload.py::test_upload_500_regression (two parametrized variants: plain UTF-8 and UTF-16 LE BOM) returns 200, never 500; plus OOB refresh covered by ::test_upload_oob_* contract tests |
Phase 9 commit 10ee09a (fix handler: caller: str = Form("") + OOB branch in imptune/api/drivers.py); Phase 9 commit d1de839 (regression + OOB RED tests); Phase 9 commit 72c6a98 (printer_form.html wiring); .planning/phases/09-ux-tech-debt-closure/09-01-SUMMARY.md (UX-01 complete 2026-04-13); REQUIREMENTS.md v1.1 UX-01 = Complete |
pass | Historical gap recorded per CONTEXT.md locked decision. At Phase 8 kickoff this was slated as fail-fix-v1.1 linked to Phase 9 / UX-01. Resolved 2026-04-13 in Phase 9 Plan 01 (commits d1de839 + 10ee09a + 72c6a98); 112 tests green post-fix. Closed as pass citing the fixing commits, consistent with the 08-01 precedent (row 14 Phase 1 spike → Phase 10 RTVAL-01). |
Audit outcome: 6/6 rows pass. No fail-fix-v1.1, deferred-v1.2, or wont-do rows. Phase 2 is Nyquist-compliant: every DRV-0x success criterion has exactly one observable check with cited, committed evidence. The Phase 8 kickoff-surfaced POST /drivers/upload 500 gap is captured as row 6 and closed via Phase 9 / UX-01 fixing commits — fully honoring the CONTEXT.md locked-decision mandate.
Validation Sign-Off
- All tasks have
<automated>verify or Wave 0 dependencies - Sampling continuity: no 3 consecutive tasks without automated verify
- Wave 0 covers all MISSING references
- No watch-mode flags
- Feedback latency < 10s
nyquist_compliant: trueset in frontmatter- Nyquist audit complete — 2026-04-13 — Sébastien QUEROL
Approval: Nyquist-audited 2026-04-13 by Claude (gsd-executor, plan 08-02) — 6/6 pass; signed off 2026-04-13 by Sébastien QUEROL (index: v1.0-VALIDATION-INDEX.md)