docs(08-01): add Phase 1 Nyquist Record to 01-VALIDATION.md
- Append ## Nyquist Record table above Validation Sign-Off - 14 rows: one observable check per Phase 1 success criterion (derived from v1.0-ROADMAP.md goal + plan outcomes) - Evidence cites committed tests (test_health, test_static, test_db, test_intunewin), source file:lines, commit SHAs, or 01-VERIFICATION.md rows - Row 14 closes former 'Upload to real Intune tenant' spike: fail-fix-v1.1 -> resolved PASS citing Phase 10 RTVAL-01 sign-off (2026-04-13) - Frontmatter: nyquist_compliant true, nyquist_audited 2026-04-13, nyquist_auditor set - All historical sections preserved verbatim
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
phase: 1
|
||||
slug: foundation
|
||||
status: draft
|
||||
nyquist_compliant: false
|
||||
nyquist_compliant: true
|
||||
wave_0_complete: false
|
||||
created: 2026-04-10
|
||||
nyquist_audited: 2026-04-13
|
||||
nyquist_auditor: Claude (gsd-executor, plan 08-01)
|
||||
---
|
||||
|
||||
# Phase 1 — Validation Strategy
|
||||
@@ -71,6 +73,33 @@ created: 2026-04-10
|
||||
|
||||
---
|
||||
|
||||
## Nyquist Record
|
||||
|
||||
> Audited 2026-04-13 by Claude (gsd-executor, plan 08-01). One row per Phase 1 success criterion derived from `milestones/v1.0-ROADMAP.md` Phase 1 goal + plan outcomes, cross-checked against `01-VERIFICATION.md` (13/13 observable truths verified on 2026-04-10) and `REQUIREMENTS.md` (INFRA-01, INFRA-02). Evidence cites committed tests, source lines, or the dated VERIFICATION report. Status values: `pass` / `fail-fix-v1.1` / `deferred-v1.2` / `wont-do`.
|
||||
|
||||
**Phase 1 goal (v1.0-ROADMAP.md):** *"A running Docker container with the app scaffold, data schema, and validated .intunewin generation capability."*
|
||||
|
||||
| # | Success Criterion | Observable Check | Evidence | Status | Notes |
|
||||
|---|-------------------|------------------|----------|--------|-------|
|
||||
| 1 | `docker compose up` starts the app and serves HTTP 200 on `GET /health` | `pytest tests/test_health.py::test_health_returns_200` returns the health payload | `tests/test_health.py::test_health_returns_200`; `imptune/api/health.py` (router returns `{"status": "ok"}`); 01-VERIFICATION.md row 1 (2026-04-10) | pass | INFRA-01. Docker image build itself is a human check (network to pico/htmx/alpine CDNs); covered by 01-VERIFICATION.md §"Human Verification Required" #1 and later exercised end-to-end during Phase 10 RTVAL-01 tenant upload (commit 7b37bdb referenced build 1c3f458). |
|
||||
| 2 | Container has no Node.js dependency and starts from a single `python:3.12-slim-bookworm` image | `grep -n "^FROM" Dockerfile` returns only `FROM python:3.12-slim-bookworm`; no `node`/`npm` install layer | `Dockerfile` line 1; commit 34c7cb3 (`feat(01-01)`); 01-VERIFICATION.md row 2 | pass | INFRA-02 — "no Node.js" arm. |
|
||||
| 3 | All static assets (Pico CSS, HTMX, Alpine.js) are served from `/static/` with zero CDN references in templates | `pytest tests/test_static.py::test_no_cdn_urls_in_templates` | `tests/test_static.py::test_no_cdn_urls_in_templates`; `imptune/templates/base.html` (4 `/static/` refs, zero `https://`); 01-VERIFICATION.md row 3 | pass | INFRA-02 — offline static arm. |
|
||||
| 4 | App shell displays a sidebar with Dashboard, Drivers, Printers, Clients, Packages sections | Grep `imptune/templates/base.html` for the 5 nav hrefs (`/`, `/drivers`, `/printers`, `/clients`, `/packages`) | `imptune/templates/base.html` sidebar nav; 01-VERIFICATION.md row 4; Phase 7 `GET /packages` closure (commit landed under phase 07) proves the link is live | pass | Dashboard quick-action buttons intentionally `aria-disabled` in Phase 1 — documented, not a gap. |
|
||||
| 5 | App follows OS dark/light theme preference automatically | Grep `imptune/templates/base.html` line 2 for `data-theme="auto"` | `imptune/templates/base.html` line 2; 01-VERIFICATION.md row 5 | pass | UI polish criterion from 01-01 plan frontmatter. |
|
||||
| 6 | SQLite database initializes automatically on first run with all 4 tables (Client, Driver, Printer, Icon) | `pytest tests/test_db.py::test_create_tables` | `tests/test_db.py::test_create_tables`; `imptune/db/database.py::init_db`; `imptune/main.py` lifespan call (commit 88d9c5f); 01-VERIFICATION.md row 6 | pass | INFRA-01 — schema arm. Full 4-table upfront schema decision (v1.0 key decision). |
|
||||
| 7 | Database uses WAL journal mode and has foreign keys enabled | `pytest tests/test_db.py::test_wal_mode` and `::test_foreign_keys` | `tests/test_db.py::test_wal_mode`, `::test_foreign_keys`; `imptune/db/database.py` pragmas `{"journal_mode": "wal", "foreign_keys": 1}`; 01-VERIFICATION.md row 7 | pass | |
|
||||
| 8 | Database file is created inside the `DATA_DIR` volume path, not inside the container filesystem | Grep `imptune/db/database.py` for `cfg.DB_PATH`; grep `docker-compose.yml` for `imptune_data:/data`; grep for `DATA_DIR=/data` env | `imptune/db/database.py` (`db.init(cfg.DB_PATH, ...)`); `docker-compose.yml` named volume + env; 01-VERIFICATION.md row 8 | pass | Persistence-across-restart property. |
|
||||
| 9 | Schema creation is idempotent — repeated startups do not fail or duplicate tables | `pytest tests/test_db.py::test_idempotent` | `tests/test_db.py::test_idempotent`; `create_tables(..., safe=True)` in `init_db()`; 01-VERIFICATION.md row 9 | pass | |
|
||||
| 10 | A Python function produces a valid `.intunewin` file from a source directory and setup file name | `pytest tests/test_intunewin.py::test_output_is_valid_zip` | `tests/test_intunewin.py::test_output_is_valid_zip`; `imptune/generators/intunewin_builder.py::build_intunewin`; commit 25f82e6; 01-VERIFICATION.md row 10 | pass | Python-native .intunewin core decision (pycryptodome, no IntuneWinAppUtil.exe). |
|
||||
| 11 | `.intunewin` output contains outer ZIP with `IntuneWinPackage/Contents/IntunePackage.intunewin` and `IntuneWinPackage/Metadata/Detection.xml` | `pytest tests/test_intunewin.py::test_outer_zip_structure` | `tests/test_intunewin.py::test_outer_zip_structure`; `imptune/generators/intunewin_builder.py` outer-ZIP assembly lines 103-111; 01-VERIFICATION.md row 11 | pass | |
|
||||
| 12 | Encrypted blob uses correct byte layout: HMAC-SHA256 (32 bytes) + IV (16 bytes) + AES-256-CBC ciphertext | `pytest tests/test_intunewin.py::test_encrypted_blob_layout tests/test_intunewin.py::test_iv_is_16_bytes tests/test_intunewin.py::test_hmac_matches` | `tests/test_intunewin.py` (`test_encrypted_blob_layout`, `test_iv_is_16_bytes`, `test_hmac_matches`); `imptune/generators/intunewin_builder.py` (blob = `mac_digest + iv + ciphertext`); 01-VERIFICATION.md row 12 | pass | HMAC-over-IV+ciphertext scope later hardened in commit 74535ea during Phase 10 RTVAL-01 debug — but the byte-layout contract verified here is still the canonical one. |
|
||||
| 13 | `Detection.xml` contains correct `EncryptionKey`, `MacKey`, `InitializationVector`, `Mac`, `FileDigest` values matching the actual encryption | `pytest tests/test_intunewin.py::test_detection_xml_fields tests/test_intunewin.py::test_decryption_roundtrip tests/test_intunewin.py::test_file_digest_matches tests/test_intunewin.py::test_unencrypted_content_size` | `tests/test_intunewin.py` (5 tests listed); 01-VERIFICATION.md row 13 | pass | Detection.xml field ordering also re-aligned with IntuneWinAppUtil.exe reference format in commit 7716246 (Phase 10 debug); byte-level equivalence preserved. |
|
||||
| 14 | `.intunewin` output is accepted by a real Microsoft Intune tenant end-to-end (decrypt + app registration) | Dated runtime check recorded in Phase 10 `RUNTIME-VALIDATION.md` (RTVAL-01) | Phase 10 `RUNTIME-VALIDATION.md` RTVAL-01 PASS (2026-04-13, re-test on fixed build after ISSUE-01 resolved via commits 74535ea + 7716246); artifact `.planning/phases/10-real-world-runtime-validation/evidence/Copieur_2eme.intunewin`; STATE.md decision log [Phase 10-01 / 10-02 RTVAL-01 PASS] | pass | Was the single Phase 1 Nyquist gap ("Upload to real Intune tenant" spike in the Manual-Only Verifications table above). Resolved by Phase 10 (NYQ→RTVAL-01) on 2026-04-13; originally would have been `fail-fix-v1.1` → Phase 10 / RTVAL-01, now closed as `pass` citing the Phase 10 sign-off. |
|
||||
|
||||
**Audit outcome:** 14/14 rows `pass`. No `fail-fix-v1.1`, `deferred-v1.2`, or `wont-do` rows. Phase 1 is Nyquist-compliant: every success criterion has exactly one observable check with cited, committed evidence.
|
||||
|
||||
---
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
|
||||
|
||||
Reference in New Issue
Block a user