Files
OmniOilPersonal/openspec/changes/notify-approved-access-requests/verify-report.md
2026-05-14 08:56:48 -05:00

213 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Verification Report
**Change**: notify-approved-access-requests
**Version**: N/A
**Mode**: Strict TDD
**Verified branch/commit**: `backup/local-work-before-remote-update` / working tree after final strict-TDD scenario coverage
**Verification date**: 2026-05-13
---
## Completeness
| Metric | Value |
|--------|-------|
| Tasks total | 79 |
| Tasks complete | 77 |
| Tasks incomplete | 2 |
Incomplete tasks in `openspec/changes/notify-approved-access-requests/tasks.md`:
- Phase 0: `0.3` production env confirmation for `INVITATION_BASE_URL=https://app.omnioil.app` and `SMTP_*` remains unchecked.
- Phase 9: `9.6` manual happy path with stubbed SMTP remains unchecked because this focused verification used automated DB integration evidence, not browser/manual SMTP QA.
Phase 5 backend DB integration tasks are now complete: the ignored harness ran against the disposable PostgreSQL/Timescale fixture and passed 5/5, covering provisioning, SMTP-failure persistence, invalid activation rejection, resend token rotation, and non-provider/customer `admin` denial through production handlers/routes.
---
## Build & Tests Execution
**Build**: Not run — user constraint says do not build.
**Tests / targeted verification commands**:
1. Current focused verification: `$env:DATABASE_URL='postgres://omnioil_test:omnioil_test_password@127.0.0.1:55432/omnioil_access_request_test'; cargo test -p backend-api --test access_request_db_integration -- --ignored --nocapture`
- ✅ 5 passed, 0 failed, 0 ignored.
- Passed tests:
- `approve_pending_and_in_review_requests_provision_customer_access`
- `smtp_failure_persists_provisioning_and_failed_email_status`
- `invalid_activation_tokens_do_not_change_user_or_invitation_state`
- `resend_revokes_previous_unconsumed_tokens_and_creates_fresh_invitation`
- `customer_admin_is_forbidden_from_provider_console_resend_route_without_rotating_tokens`
- Non-failing warnings: 4 dead-code warnings for helper functions/types used only by unit tests.
2. Current focused unit evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api access_request_emails`
- ✅ 2 passed, 0 failed.
3. Current focused unit evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api auth`
- ✅ 5 passed, 0 failed.
4. Retained prior backend targeted evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api access_requests`
- ✅ 10 passed, 0 failed, 16 filtered.
5. Retained prior backend targeted evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api invitations`
- ✅ 3 passed, 0 failed, 23 filtered.
6. Retained prior backend targeted evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api invitation_tokens`
- ✅ 3 passed, 0 failed, 19 filtered.
7. Retained prior backend targeted evidence: `$env:SQLX_OFFLINE='true'; cargo test -p backend-api smtp_mailer`
- ✅ 2 passed, 0 failed, 20 filtered.
8. Retained prior frontend evidence: `pnpm --dir services/frontend-admin test -- ActivatePage`
- ✅ Focused activation-page tests passed.
9. Retained prior frontend evidence: `pnpm --dir services/frontend-console test -- AccessRequestsPage`
- ✅ 17 passed, 0 failed.
10. Not rerun in this focused pass: `cargo fmt -- --check`
- ⚠️ External waiver candidate. Prior focused verification showed it fails only on unrelated repo-wide Rust formatting drift outside this SDD change. Per maintainer direction, do not mix the global formatting cleanup into this feature and do not mark it as an in-scope feature failure.
**Coverage**: Not available (`openspec/config.yaml` marks coverage unavailable).
---
## TDD Compliance
| Check | Result | Details |
|-------|--------|---------|
| TDD Evidence reported | ✅ | Engram `sdd/notify-approved-access-requests/apply-progress` contains a TDD Cycle Evidence table. |
| All tasks have tests | ✅ | The final three previously untested scenarios now have runtime coverage: customer `admin` provider denial, activation-link construction, and non-provider resend rejection. |
| RED confirmed (tests exist) | ✅ | Apply-progress records RED for the DB harness/library extraction before `src/lib.rs` existed. |
| GREEN confirmed (tests pass) | ✅ | Real DB harness passed 5/5 against disposable PostgreSQL on port `55432`; focused unit suites for link/auth passed. |
| Triangulation adequate | ✅ | DB harness covers multiple persisted-state branches: pending/in-review, re-approval rejection, active existing user, provider duplicate, SMTP failure, invalid tokens, and resend rotation. |
| Safety Net for modified files | ✅ | Targeted backend unit suites and DB integration harness evidence exist; frontend focused suites are retained from prior verify/apply passes. |
**TDD Compliance**: 6/6 checks pass for the automated strict-TDD scenario coverage requested in this pass.
---
## Test Layer Distribution
| Layer | Tests | Files | Tools |
|-------|-------|-------|-------|
| Unit / structural | 22 backend tests in accumulated focused evidence | Rust module tests | `cargo test` |
| DB integration | 5 passed scenario tests | `services/backend-api/tests/access_request_db_integration.rs` | `cargo test -p backend-api --test access_request_db_integration -- --ignored --nocapture` with explicit `DATABASE_URL` |
| Integration / component | 17 Console tests + focused Admin activation tests retained from prior evidence | TSX test files | Vitest + Testing Library / React DOM |
| E2E | 0 | 0 | Available project scripts, not used |
---
## Changed File Coverage
Coverage analysis skipped — no coverage tool detected.
---
## Assertion Quality
**Assertion quality**: ✅ No tautology or ghost-loop assertions found in inspected related tests. The DB integration tests assert persisted database state through production handlers instead of smoke checks.
---
## Quality Metrics
**Linter**: Not rerun in this focused pass; prior verify/apply evidence reported frontend lint passing.
**Formatter**: ⚠️ External waiver candidate — not rerun in this focused pass; prior evidence showed repo-wide `cargo fmt -- --check` fails only on unrelated Rust formatting drift outside this SDD change.
**Type Checker**: Not run — no build/type-check command executed under the user constraint.
---
## Spec Compliance Matrix
| Requirement | Scenario | Test | Result |
|-------------|----------|------|--------|
| Approve Request Provisions Customer Access | Approving a pending request provisions new customer admin | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access` | ✅ COMPLIANT |
| Approve Request Provisions Customer Access | Approving an in-review request provisions access | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access` | ✅ COMPLIANT |
| Approve Request Provisions Customer Access | Approving a closed request is rejected | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access` re-approval assertion | ✅ COMPLIANT |
| Existing User Is Linked, Not Duplicated | Existing user email is approved again | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access` active-customer branch | ✅ COMPLIANT |
| Existing User Is Linked, Not Duplicated | Existing active user is linked | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access`; `access_requests > active_user_resend_sends_access_ready_notification_without_invitation_rotation` | ✅ COMPLIANT |
| Customer Roles Remain Separated From Provider Roles | Provisioned customer admin cannot access provider Console | `auth > customer_admin_role_does_not_satisfy_platform_claims`; `access_request_db_integration > customer_admin_is_forbidden_from_provider_console_resend_route_without_rotating_tokens` | ✅ COMPLIANT |
| Activation Invitation Uses Secure Opaque Token | Activation token is created securely | `invitation_tokens`; `access_requests > provisioning_audit_metadata_never_contains_raw_activation_token`; DB harness asserts invitation rows exist but not raw token persistence directly | ⚠️ PARTIAL |
| Activation Invitation Uses Secure Opaque Token | Activation link targets customer Admin app | `access_request_emails > activation_link_uses_configured_invitation_base_url_and_activate_path`; `activation_email_defaults_to_production_admin_activate_url` | ✅ COMPLIANT |
| Activation Sets Password And Enables Login | Valid activation succeeds | `ActivatePage` success test; backend activation success path structurally exists, but DB harness focuses invalid-token no-op | ⚠️ PARTIAL |
| Activation Sets Password And Enables Login | Expired activation is rejected | `access_request_db_integration > invalid_activation_tokens_do_not_change_user_or_invitation_state`; `invitations > expired_consumed_and_revoked_invitations_cannot_activate` | ✅ COMPLIANT |
| Activation Sets Password And Enables Login | Consumed activation is rejected | `access_request_db_integration > invalid_activation_tokens_do_not_change_user_or_invitation_state`; `invitations > expired_consumed_and_revoked_invitations_cannot_activate` | ✅ COMPLIANT |
| Activation Sets Password And Enables Login | Revoked activation is rejected | `access_request_db_integration > invalid_activation_tokens_do_not_change_user_or_invitation_state`; `invitations > expired_consumed_and_revoked_invitations_cannot_activate` | ✅ COMPLIANT |
| Approval Email Delivery Is Recoverable | Email send succeeds | `access_requests > invitation_email_delivery_update_marks_success_as_sent_and_clears_error`; no SMTP-accepted DB integration test found | ⚠️ PARTIAL |
| Approval Email Delivery Is Recoverable | Email send fails | `access_request_db_integration > smtp_failure_persists_provisioning_and_failed_email_status`; Console failed resend UI test | ✅ COMPLIANT |
| Resend Rotates Activation Tokens | Resend invalidates previous token | `access_request_db_integration > resend_revokes_previous_unconsumed_tokens_and_creates_fresh_invitation`; Console resend API/UI test | ✅ COMPLIANT |
| Resend Rotates Activation Tokens | Resend is provider-only | `auth > customer_admin_role_does_not_satisfy_platform_claims`; `access_request_db_integration > customer_admin_is_forbidden_from_provider_console_resend_route_without_rotating_tokens` | ✅ COMPLIANT |
| Initial Trial Is Created Without Full Billing Automation | Approved project starts trial | `access_request_db_integration > approve_pending_and_in_review_requests_provision_customer_access`; `smtp_failure_persists_provisioning_and_failed_email_status` | ✅ COMPLIANT |
| Initial Trial Is Created Without Full Billing Automation | Trial expiration does not belong to activation token | Backend activation query ignores subscription/trial state; no runtime test found | ⚠️ PARTIAL |
| Console Shows Provisioning State | Approved request detail shows provisioning status | `AccessRequestsPage.test.tsx > shows provisioned project...`; backend `ACCESS_REQUEST_SELECT` unit test | ✅ COMPLIANT |
| Console Shows Provisioning State | Failed email shows resend action | `AccessRequestsPage.test.tsx > shows resend action for failed invitation...` | ✅ COMPLIANT |
| Console Shows Provisioning State | Sent email without expiration issue hides urgent resend | `AccessRequestsPage.test.tsx > shows provisioned project...` and expired/consumed test | ✅ COMPLIANT |
**Compliance summary**: 16/21 scenarios compliant, 5/21 partial, 0/21 untested.
---
## Correctness (Static — Structural Evidence)
| Requirement | Status | Notes |
|------------|--------|-------|
| Approve Request Provisions Customer Access | ✅ Implemented + DB tested | Approval transaction creates project/user/access/trial/invitation and status; DB harness passed. |
| Existing User Is Linked, Not Duplicated | ✅ Implemented + DB tested | Existing active user is linked without password reset/deactivation; provider-role duplicate is blocked. |
| Customer Roles Remain Separated From Provider Roles | ✅ Implemented + tested | New users use role `admin`; `PlatformClaims` rejects customer roles; DB route test proves customer `admin` receives 403 from provider resend without token rotation. |
| Activation Invitation Uses Secure Opaque Token | ✅ Mostly | Token helper uses 32 random bytes and SHA-256 hash; activation-link construction is unit-tested for `INVITATION_BASE_URL`, `/activate`, production default, and raw token query parameter; direct DB raw-token absence remains covered by prior audit/unit evidence. |
| Activation Sets Password And Enables Login | ⚠️ Partial | Public activation endpoint validates hash/state, hashes password, activates user, consumes invitation, and audits activation; invalid-token DB safety is tested, valid backend activation DB success is not directly tested. |
| Approval Email Delivery Is Recoverable | ✅ Failure path DB tested / ⚠️ success path partial | SMTP failure persists approval/provisioning and marks email failed. SMTP accepted path is helper-tested, not DB/SMTP-integrated. |
| Resend Rotates Activation Tokens | ✅ Implemented + DB tested | Provider resend route revokes unconsumed invitations and creates a fresh token for inactive users; active users receive access-ready notification. |
| Initial Trial Is Created Without Full Billing Automation | ✅ Implemented + DB tested | DB harness asserts trial subscription rows for provisioned projects. |
| Console Shows Provisioning State | ✅ Implemented + UI tested | Backend returns display fields; Console displays state and resend actions. |
| Docs And Deployment | ✅ Structural | Deployment docs and env examples document invitation base URL, SMTP variables, 7-day trial, and SMTP failure resend guidance without secrets. |
---
## Coherence (Design)
| Decision | Followed? | Notes |
|----------|-----------|-------|
| ADR-1 auto-create `edge_projects` | ✅ Yes | DB harness proves project row creation; unit tests prove deterministic defaults. |
| ADR-2 customer role `admin` | ✅ Yes | New users use `admin`; provider roles are blocked for duplicate email. |
| ADR-3 existing email links user | ✅ Yes | DB harness proves existing active customer user is linked and preserved. |
| ADR-4 inactive until activation | ✅ Yes | DB harness proves newly provisioned users are inactive. |
| ADR-5 hash-only opaque token | ✅ Mostly | Token/hash helpers and audit metadata tests exist; direct DB raw-token absence assertion remains partial. |
| ADR-6 Admin `/activate` | ✅ Yes | Backend route and Admin page exist; production URL is documented. |
| ADR-7 SMTP failure does not rollback | ✅ Yes | DB harness proves approval/provisioning survive SMTP-disabled failure and invitation status becomes `failed`. |
| ADR-8 resend revokes prior tokens | ✅ Yes | DB harness proves previous open invitations are revoked, consumed invitations are preserved, and a fresh open invitation is created. |
| ADR-9 7-day trial | ✅ Yes | DB harness proves `subscriptions(status='trial', trial_ends_at IS NOT NULL)` exists. |
---
## Issues Found
### CRITICAL — must fix before strict SDD archive
None for the final three strict-TDD scenario gaps requested in this pass.
### WARNING
1. Phase `0.3` production env confirmation remains unchecked. This is an operational release/deploy readiness item, not a feature-code failure.
2. Phase `9.6` manual happy path remains unchecked. Automated DB evidence now covers the backend path, but no browser/manual stubbed-SMTP happy path was performed in this focused verification.
3. SMTP accepted delivery is helper-tested but not DB/SMTP-integrated; the failure/recovery path is now DB-tested.
### EXTERNAL / WAIVER CANDIDATE
1. Repo-wide Rust formatting drift remains external to this feature. Do not mark it as an in-scope failure and do not fix it inside this change unless explicitly authorized as a separate cleanup.
### Resolved Since Prior Verify
- **Phase 5 DB integration blocker resolved** — real disposable PostgreSQL evidence passed 4/4 using the production-handler harness.
- **Phase 9.1 complete** — targeted backend DB integration command passed.
- **Final three strict-TDD scenario gaps resolved** — customer `admin` provider denial, activation-link target construction, and non-provider resend rejection now have runtime tests.
---
## Verdict
**PASS WITH WARNINGS for automated strict-TDD scenario coverage; remaining warnings are release-readiness/manual verification items.**
There is no remaining Phase 5 DB integration blocker and the three previously untested strict scenarios now have runtime coverage. Repo-wide `cargo fmt` drift remains external. Production env confirmation and manual SMTP happy path remain release-readiness tasks.