add final acceptance verification

This commit is contained in:
Marco0300
2026-09-03 13:02:04 +02:00
parent 9622f76977
commit 561efe8855
10 changed files with 718 additions and 1 deletions
+96
View File
@@ -0,0 +1,96 @@
# Phase 17 Final Acceptance
## Decision
**Local acceptance: PASS. Production deployment: BLOCKED / not attempted.**
This decision applies to the repository at commit `9622f769776637a40fdae797adccba91445cd351` (branch `main`). The acceptance run validates the local checkout and bounded, offline pilot behavior. It is not evidence that the application was pushed to the remote repository or deployed to a production host.
## Acceptance matrix
| Area | Local evidence | Result | Production interpretation |
| --- | --- | --- | --- |
| Phases 14: baseline workflow, auth, jobs/events | API regression suite, tenant/auth/job checks | PASS locally | SQLite and the in-process worker remain pilot-only |
| Phase 5: source-adapter safety boundary | Source lifecycle, dry-run, CSV/manual-reference tests | PASS locally | No live source is enabled; terms, approval, rate, retention, and circuit controls remain prerequisites |
| Phase 6: normalization and reversible deduplication | Canonicalization, threshold, merge/reversal and tenant tests | PASS locally | Merge permission, full conflict snapshots, concurrency, and production rollback hardening remain open |
| Phase 7: domain intelligence | PSL/DNS-state/candidate and no-false-availability tests | PASS locally | No production resolver, cache, or authorized availability provider is enabled |
| Phase 8: SSRF-safe website observation | Scanner policy, limits, unsafe-target and history tests | PASS locally | Production egress isolation, DNS-rebinding/redirect testing, durable retention, and monitoring remain open |
| Phase 9: official-site contact observation | Extraction, provenance, false-positive and suppression tests | PASS locally | No SMTP probing or outreach; legal, retention, and production isolation gates remain |
| Phase 10: scoring | Versioned rules, explanations, recalculation and suppression tests | PASS locally | Production approval lifecycle, durable scheduling, snapshots, and rollback remain open |
| Phase 11: operator review workflow | Saved views, review queue, dashboard and bounded bulk-action tests | PASS locally | Production audit completeness, idempotency, per-item outcomes, and queue/count hardening remain open |
| Phase 12: CRM and suppression center | Pipeline, interactions, outcomes, reports, and suppression tests | PASS locally | Record-keeping only; no delivery provider or outbound worker exists |
| Phase 13: evidence-grounded AI assistance | Provider-disabled, evidence/citation, approval, limits, and isolation tests | PASS locally | Provider/DPA, legal, secret-management, evaluation, retention, and operational approval remain required |
| Phase 14: draft-only outreach boundary | Draft/gate/idempotency/no-send tests | PASS locally | Outreach remains disabled; consent/legal basis, provider, delivery feedback, and approval controls are not production-complete |
| Phase 15: deployment/readiness/recovery assets | Backup/restore, readiness, config, shell, and safety checks | PASS locally | Host, TLS/DNS/Virtualmin, off-host backups, monitoring, and operator access are unavailable |
| Phase 16: deterministic pilot benchmark | `scripts/benchmark_phase16.py --no-latency`; synthetic fixture report | PASS locally | Synthetic metrics do not establish production quality, capacity, availability, or SLOs |
| Phase 17: final acceptance | This matrix, bounded capacity smoke, reproducibility and blocker review | PASS locally | Production gate remains blocked until external prerequisites are verified |
## Bounded local capacity smoke
The Phase 17 smoke is deterministic, in-memory, and deliberately bounded. It is a guard against accidental unbounded retention, not a load test or capacity claim.
- Synthetic collection: 1,000 items.
- Requested page size: 100; returned items: 100; `has_more=true`.
- Synthetic large batch: 5,000 input items; retained items: 100; input was truncated.
- Enforced smoke limits: maximum page size 100 and maximum retained batch items 100.
- Smoke result: `bounded=true`.
These figures do **not** measure production throughput, concurrency, queue durability, memory pressure, latency SLOs, availability, or safe operating limits. Production capacity requires a reviewed host profile, representative workload, durable worker/database design, observability, and an approved load-test plan.
## Reproducibility and verification record
The final acceptance collector passed with:
- API suite: **100 tests, exit 0** (`python3 -m unittest discover -v -s apps/api/tests -t apps/api`).
- Phase 16 semantic benchmark without variable timing: **passed**.
- Python compilation of scripts and API modules: **passed**.
- Shell syntax checks for backup, healthcheck, restore, and rollback scripts: **passed**.
- JSON validation for the benchmark and acceptance schemas/reports: **passed**.
- Compose config validation: **passed** (`docker compose -f docker-compose.yml config --quiet`).
- Safety invariants: outreach disabled, no send network path, and tenant routes present: **passed**.
- Git state: acceptance head resolved to `9622f769776637a40fdae797adccba91445cd351`; working-tree status was recorded before documentation edits.
The deterministic benchmark reports 100% normalization accuracy, 100% matching precision/recall, 100% contact precision/recall, 100% website-fixture accuracy, reproducible scoring, and zero tenant leakage. The fixture set is synthetic and small; see `docs/BENCHMARKS.md` for methodology and limitations. Timing observations are local pilot signals only.
Repeatable local checks from the repository root:
```sh
python3 scripts/final_acceptance.py --output /tmp/prospect-final-acceptance.json
python3 scripts/benchmark_phase16.py --no-latency --output /tmp/prospect-phase16.json
python3 -m unittest discover -v -s apps/api/tests -t apps/api
python3 -m compileall -q apps/api apps/web
bash -n scripts/*.sh
docker compose config --quiet
git diff --check
```
## Blockers and prerequisites
### Remote publication
Remote push is blocked by missing repository authentication and unverified permission to push the intended branch. The configured remote is `https://repo.mmcloud.co.za/root/MarketingTool.git`; no push was attempted by this acceptance work. A local commit, passing tests, or a clean diff is not a remote publication. Resolve authentication and branch permission, then verify the remote revision independently.
### Production deployment
Deployment is blocked because no production host, Docker/Compose access, protected deployment directory, or deployment operator is available in this run. Before promotion, verify all of the following:
- reviewed remote revision and release owner;
- patched Linux host with Docker Engine/Compose v2, adequate CPU/RAM/disk, firewalling, and restricted Docker access;
- Virtualmin or equivalent perimeter, DNS control, HTTPS certificates and renewal monitoring, and private API exposure where appropriate;
- protected environment/secret manager for `SESSION_SECRET` and any one-time bootstrap values; remove bootstrap values after provisioning and rotate the password;
- encrypted off-host backup destination, checksum/restore drill, retention and legal-hold ownership;
- monitoring for health, restarts, resources, auth failures, backups, TLS, migrations, and unexpected egress;
- named rollback owner and approval to restore data if compatibility is established;
- authenticated tenant-isolation smoke tests and migration validation on the target host.
### Legal and provider enablement
Real source, AI, DNS/availability, scanner, or outreach providers are not enabled by this local acceptance. Any future provider requires an allowlisted identity, owner, approved purpose/data class, tenant scope, region/retention terms, rate and cost caps, timeout/retry/circuit policy, secret-manager injection, current product/security/legal approval, terms/DPA review where applicable, and explicit operational enablement. Outreach additionally requires jurisdiction-specific legal review, documented consent or lawful basis, suppression synchronization, human approval, delivery feedback, retention/deletion/legal-hold controls, and a tested kill switch. Until those gates are complete, `AUTOMATED_OUTREACH_ENABLED=false` remains mandatory.
## Rollback decision
**Decision: retain the current local revision; do not promote or roll back.** There is no production deployment to undo. If a future promotion fails health, integrity, tenant-isolation, migration, or smoke validation, stop traffic and writes as appropriate, record the image/config/backup revisions, restore the previously verified compatible image/config first, and restore data only after schema compatibility and incident-owner approval. Never run an older binary against an incompatible newer schema, and never use `docker compose down -v` on a data-bearing environment. Re-run liveness/readiness, authenticated isolation, and integrity checks before re-enabling traffic.
## Scope boundary
Phase 17 completes the **local acceptance documentation and verification boundary**. It does not claim remote push, host provisioning, credential availability, legal approval, provider enablement, or production deployment. Those are separate external gates and must be recorded as evidence in the release checklist before any production go decision.