phase 16 implementation
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
Event,Purpose,Trigger,Allowed_properties,Personal_data,Consent_category,Environment,Implementation_status
|
||||
demo_open,CTA discovery,dialog opens,routeId; locale; direction; resolvedTheme; source,No,analytics,test sink only,instrumented; disabled
|
||||
demo_validation_error,Validation friction,client validation fails,routeId; locale; direction; resolvedTheme; source; errorCount,No,analytics,test sink only,instrumented; disabled
|
||||
demo_submit_attempt,Funnel attempt,validated submit,routeId; locale; direction; resolvedTheme; source,No,analytics,test sink only,instrumented; disabled
|
||||
demo_submit_success,Confirmed completion,adapter acceptance,routeId; locale; direction; resolvedTheme; source,No,analytics,test sink only,instrumented; disabled
|
||||
demo_submit_failure,Failure category,normalized failure,routeId; locale; direction; resolvedTheme; source; errorCode,No,analytics,test sink only,instrumented; disabled
|
||||
demo_close,Dialog abandonment,user closes,routeId; locale; direction; resolvedTheme; source; reason,No,analytics,test sink only,instrumented; disabled
|
||||
|
@@ -0,0 +1,8 @@
|
||||
# Phase 14 Component Variant Update
|
||||
|
||||
Two backward-compatible component changes support the integration flow:
|
||||
|
||||
1. `TextInput` now forwards its native input ref so a dialog can place initial focus on the first field and restore the approved error-focus pattern.
|
||||
2. `CTA` accepts optional `primaryNode` and `secondaryNode` slots while retaining its existing action-object API. This permits a semantic button trigger for the native demo dialog without turning a button action into a fake navigation link.
|
||||
|
||||
No visual token, component family, or existing prop behavior was removed.
|
||||
@@ -0,0 +1,6 @@
|
||||
Purpose,Required_for_local_flow,Required_for_production,Current_behavior,Decision_owner,Blocker
|
||||
Necessary demo processing,Payload discarded,Legal basis/notice required,Production disabled,Legal,P9-003
|
||||
Privacy acknowledgment,No final acknowledgment,Pending decision,Operational local notice only,Legal,P9-003
|
||||
Marketing opt-in,No,Optional if approved; never preselected,Not rendered/transmitted,Legal + Marketing,P9-003
|
||||
Analytics consent,Injected test consent only,Pending policy,Disabled; test sink gated,Legal + Analytics,P9-004
|
||||
Advertising consent,No,No approved use,No advertising code,Legal + Marketing,P9-004
|
||||
|
@@ -0,0 +1,11 @@
|
||||
Field,Purpose,Required,Source,Browser_processing,Server_processing,External_recipients,Storage_location,Retention,Deletion_path,Consent_or_legal_basis,Logging,Analytics,Owner,Open_issue
|
||||
fullName,Identify requester,Yes,User form/current locale,DOM memory only; client validation,strict validation and normalization,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops + Legal,P9-002; P9-003
|
||||
workEmail,Follow-up address,Yes,User form/current locale,DOM memory only; client validation,lowercase and practical validation,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops + Legal,P9-002; P9-003
|
||||
company,Qualify organization,Yes,User form/current locale,DOM memory only; client validation,strict validation and normalization,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops,P9-002
|
||||
fleetSize,Approved qualification,Yes,User form/current locale,DOM memory only; client validation,enum validation,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops,P9-002
|
||||
market,Optional market context,No,User form/current locale,DOM memory only; client validation,trim and length limit,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops + Legal,P9-013
|
||||
preferredLanguage,Demo language preference,No,User form/current locale,DOM memory only; client validation,enum validation,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops,P9-002
|
||||
message,Optional demo focus,No,User form/current locale,DOM memory only; client validation,trim and 1000-character limit,None,None,Request lifetime only,Automatic discard,Unapproved for production,Prohibited,Prohibited,Sales Ops + Legal,P9-002; P9-003
|
||||
idempotencyKey,Transport deduplication,Yes,Browser UUID,memory only,bounded local result coalescing,None,process memory,900 seconds default,TTL/process restart,Necessary technical processing; production policy pending,Not logged,Prohibited,Engineering,P14-004
|
||||
source,CTA entry point,Yes,Application allowlist,event detail,enum validation,None,None,request lifetime,automatic,Operational context,Category only if approved,Allowlisted after consent,Product + Analytics,P9-004
|
||||
correlationId,Privacy-safe error correlation,Generated,Server UUID,failure response only,generated per attempt,None,None currently,None,automatic,Necessary diagnostics,Allowed without payload if observability approved,Prohibited,Engineering,P14-005
|
||||
|
@@ -0,0 +1,25 @@
|
||||
# Phase 14 Demo Form Contract
|
||||
|
||||
## Approved business fields
|
||||
|
||||
The implementation preserves the Phase 9 contract exactly: `fullName`, `workEmail`, `company`, `fleetSize`, optional `market`, optional `preferredLanguage`, optional `message`, `idempotencyKey`, and `source`. No phone, job title, location count, revenue, marketing profile, or lead-scoring field was added.
|
||||
|
||||
Fleet-size values are `1-9`, `10-24`, `25-49`, `50-99`, `100-249`, and `250+`.
|
||||
|
||||
## Transport envelope
|
||||
|
||||
The JSON submission body contains an approved lead object and a separate non-business guard object. The guard contains an empty honeypot and the form-open timestamp. Both objects reject unknown fields. The timestamp is not treated as authoritative identity or anti-fraud evidence.
|
||||
|
||||
## Validation
|
||||
|
||||
Client validation improves correction. The same strict Zod schema is executed on the server. Text is trimmed, repeated whitespace is collapsed, email casing is normalized, lengths are bounded, enum values are allowlisted, and unknown fields are rejected. Email validation is deliberately practical rather than a theatrical reenactment of the entire email RFC.
|
||||
|
||||
## State machine
|
||||
|
||||
`idle → validating → submitting → success | recoverable_error | terminal_error`
|
||||
|
||||
A pending submission disables repeat activation. The same idempotency key is retained for a retry after a recoverable transport failure. Success is rendered only after adapter acceptance.
|
||||
|
||||
## Privacy and consent boundary
|
||||
|
||||
The local adapter discards the payload and does not create a lead. The operational notice states this explicitly. Final privacy notice, legal basis, acknowledgment, marketing opt-in, retention, and deletion behavior remain blocked by P9-003. Production submission cannot be enabled by the shipped configuration.
|
||||
@@ -0,0 +1,11 @@
|
||||
Key,Kind,Status_production,Status_local,Locale_behavior,Target,Issue,Release_rule,Notes
|
||||
book-demo,modal/form,blocked,active,EN/FR/AR,Local discard adapter only,P9-002; P9-003,"Approved destination, legal text, retention and deletion policy",Local success states no external lead was created.
|
||||
contact-sales,external-url,blocked,blocked,EN/FR/AR,None,P9-015,Approved sales destination,No guessed email or URL.
|
||||
product-tour,modal/media,blocked,blocked,EN/FR/AR,None,P9-012,"Approved medium, captions, transcript and embed policy",No embed loaded.
|
||||
pricing,internal intent,placeholder,placeholder,Localized homepage section,#pricing,P9-008,Commercial approval,No public prices or checkout.
|
||||
login,external-url,blocked,blocked,EN/FR/AR,None,P9-014,Approved origin and redirect policy,Authentication excluded.
|
||||
privacy,internal-route,placeholder,placeholder,Localized route,privacy placeholder,P9-003,Approved localized legal copy,Not final policy.
|
||||
terms,internal-route,placeholder,placeholder,Localized route,terms placeholder,P9-003,Approved localized legal copy,Not final terms.
|
||||
accessibility,internal-route,placeholder,placeholder,Localized route,accessibility placeholder,P13-002,Manual review and approved statement,Non-indexable placeholder.
|
||||
cookie-settings,modal,blocked,blocked,EN/FR/AR,None,P9-004,Approved consent categories and withdrawal mechanism,Analytics disabled.
|
||||
support,external-url,blocked,blocked,EN/FR/AR,None,P9-015,Approved support destination,No placeholder contact data.
|
||||
|
@@ -0,0 +1,9 @@
|
||||
Variable,Purpose,Visibility,Environments,Validation,Default,Secret,Owner,Rotation,Missing_behavior
|
||||
SITE_ORIGIN,Canonical/allowed origin,server,production/test,absolute URL,none,No,Infrastructure,domain change,existing production gate
|
||||
NEXT_PUBLIC_DEMO_ENABLED,Expose demo trigger,public,all,boolean,false,No,Product + Engineering,n/a,production disabled
|
||||
DEMO_SUBMISSION_MODE,blocked/local adapter,server,all,enum,local non-production; blocked production,No,Engineering,n/a,safe inferred default
|
||||
DEMO_REQUEST_TIMEOUT_MS,Bound adapter call,server,all,250-15000 integer,4000,No,Engineering,n/a,4000
|
||||
DEMO_IDEMPOTENCY_TTL_SECONDS,Local coalescing TTL,server,all,60-86400 integer,900,No,Engineering,n/a,900
|
||||
DEMO_TEST_SCENARIOS_ENABLED,Deterministic failures,server,test,boolean,false,No,QA,n/a,disabled
|
||||
DEMO_LOCAL_TEST_MODE,Loopback production-like test escape,server,local test,boolean plus loopback SITE_ORIGIN,false,No,QA + Engineering,n/a,production local mode rejected
|
||||
NEXT_PUBLIC_ANALYTICS_MODE,disabled/test sink,public,test,enum,disabled,No,Analytics + Engineering,n/a,disabled
|
||||
|
@@ -0,0 +1,6 @@
|
||||
Service_type,Vendor,Status,Authentication,Endpoint,Data_sent,Timeout,Retry,Idempotency,Owner,Blocker
|
||||
CRM/lead destination,Unapproved,Blocked,Unknown,None,None,4-second boundary,No blind retry,Local coalescing; vendor semantics pending,Sales Ops + Engineering,P9-002
|
||||
Scheduling,Unapproved,Blocked,Unknown,None,None,n/a,n/a,n/a,Sales Ops,P14-006
|
||||
Email,Unapproved,Blocked,Unknown,None,None,n/a,n/a,n/a,Sales Ops + Engineering,P14-007
|
||||
Analytics,Unapproved,Blocked,Unknown,None,None,n/a,n/a,provider pending,Analytics + Legal,P9-004
|
||||
Consent management,Unapproved,Blocked,Unknown,None,None,n/a,n/a,n/a,Legal + Product,P9-003; P9-004
|
||||
|
@@ -0,0 +1,9 @@
|
||||
Flag,Default_production,Default_development,Owner,Disabled_behavior,Enablement_requirements
|
||||
demoSubmissionEnabled,false,true with local discard,Product + Engineering,non-navigable localized reason,"CRM, legal, privacy, operations and QA approval"
|
||||
crmIntegrationEnabled,false,false,Sales Ops + Engineering,blocked adapter,P9-002
|
||||
schedulerEnabled,false,false,Sales Ops,no scheduler,approved provider and accessibility review
|
||||
analyticsEnabled,false,false,Analytics + Legal,no delivery/network/storage,P9-004
|
||||
marketingConsentEnabled,false,false,Legal,not rendered/transmitted,approved text and withdrawal flow
|
||||
productTourEnabled,false,false,Product + Marketing,non-navigable,P9-012
|
||||
pricingDestinationEnabled,false,false,Commercial,informational section only,P9-008
|
||||
loginDestinationEnabled,false,false,Product + Engineering,non-navigable,P9-014
|
||||
|
@@ -0,0 +1,23 @@
|
||||
# Phase 14 Integration Architecture
|
||||
|
||||
```text
|
||||
Approved CTA trigger
|
||||
→ localized native dialog
|
||||
→ shared client/server schema
|
||||
→ POST /api/demo
|
||||
→ request marker + origin + content type + size checks
|
||||
→ strict server validation and normalization
|
||||
→ honeypot check
|
||||
→ idempotency coordinator
|
||||
→ bounded adapter orchestration
|
||||
→ local-discard or blocked adapter
|
||||
→ normalized result
|
||||
→ localized success/failure state
|
||||
→ consent-gated, allowlisted test analytics sink
|
||||
```
|
||||
|
||||
UI code never imports a vendor SDK. The lead adapter interface is the only external-service boundary. The shipping repository contains no CRM, scheduler, email, consent, or analytics network client because none is approved.
|
||||
|
||||
The local adapter is deterministic, server-side, non-production, and discard-only. Production environment validation rejects local adapter activation except for an explicit loopback-only production-like browser test runtime. That escape requires `DEMO_LOCAL_TEST_MODE=true` and a `localhost` or `127.0.0.1` `SITE_ORIGIN`.
|
||||
|
||||
The native dialog does not create browser history. Back navigation therefore remains unchanged. Locale and theme are inherited from the document. Closing is blocked while submission is pending, and focus returns to the initiating control.
|
||||
@@ -0,0 +1,6 @@
|
||||
Capability,Entry_points,Source_specifications,Data_fields,Consent_requirements,Adapter,External_destination,Analytics_events,Tests,Security_controls,Privacy_controls,Open_issues,Status
|
||||
Demo presentation,header; mobile header; hero; final CTA; footer,Phase 9 demo contract; Phase 14 prompt,approved DemoRequest,Final legal text blocked,DemoDialogHost,none,demo_open; demo_close,schema; browser EN/FR/AR; axe; visual,native dialog; focus return,no storage or URL PII,P9-003; P14-002,partially-implemented
|
||||
Submission API,POST /api/demo,Phase 9 contract; server authority rules,DemoRequest plus guard envelope,Production disabled,submission service,local discard only,none server-side,schema; integration; security/privacy validators,origin; request marker; content type; 16 KiB; strict schema; timeout; idempotency,no raw logging or body echo,P9-002; P9-003; P14-001,partially-implemented
|
||||
Lead destination,submission service,typed adapter boundary,approved DemoLead,Production blocked,LocalLeadDestinationAdapter; BlockedLeadDestinationAdapter,none,success/failure client events,adapter and orchestration,server-only selection; timeout,local adapter discards payload,P9-002; P14-001,blocked
|
||||
Analytics,demo lifecycle,Phase 9 analytics spec,allowlisted non-PII context,analytics consent required,disabled/test sink,none,demo_open; validation; attempt; success; failure; close,contract; browser no-PII; privacy validator,strict event schema,consent gate; no network/storage,P9-004; P14-003,blocked
|
||||
Destinations,homepage/header/footer,Phase 13 policy; Phase 14 registry,none,n/a,typed registry,none approved,none activated,destination unit and validator,no external URL/open redirect,no arbitrary query forwarding,P9-008; P9-012; P9-014; P9-015,partially-implemented
|
||||
|
@@ -0,0 +1,9 @@
|
||||
# Phase 14 Performance and Bundle Report
|
||||
|
||||
Phase 14 adds no third-party runtime dependency and no vendor SDK. The new client code consists of the demo trigger, localized dialog/form state, shared Zod schema in the client bundle, and a disabled analytics test adapter. Scheduler, CRM, consent-manager, email, and network analytics libraries contribute zero bytes because they are not approved or implemented.
|
||||
|
||||
The dialog host is mounted once per locale layout. External code is never loaded. The primary CTA remains responsive when integrations are blocked. Submission latency is bounded by a configurable four-second default timeout.
|
||||
|
||||
The optimized build completed in 29 seconds on the available Node 22.16.0 host. The generated standalone tree measured 36,391,835 bytes and `.next/static` measured 1,524,329 bytes. These numbers include framework/runtime files and are an inventory, not a Phase 13 delta. The exact file list is recorded in `docs/quality/logs/phase14/bundle-inventory.log`.
|
||||
|
||||
Lighthouse, main-thread cost, interaction responsiveness, and browser timing were not measured because system Chromium rejects loopback navigation with `net::ERR_BLOCKED_BY_ADMINISTRATOR`. Those results remain Phase 15 gates rather than decorative estimates.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Phase 14 Privacy Review
|
||||
|
||||
The approved lead fields are processed only in the browser DOM, the server request, and the discard-only local adapter. They are not written to URLs, query strings, browser storage, logs, analytics, snapshots, or external systems.
|
||||
|
||||
The analytics contract accepts only route, locale, direction, resolved theme, source, bounded step/error categories, and bounded counts. The shipping adapter is disabled. Its test sink requires an explicit in-page consent marker and sends no network request.
|
||||
|
||||
The data-flow inventory records purpose, source, processing, recipient, storage, retention, deletion, consent status, logging status, owner, and blocker for every field. Production collection remains blocked because legal basis, privacy notice, retention, deletion, recipients, residency, and cross-border transfer decisions are absent.
|
||||
|
||||
No final consent checkbox is rendered. This is intentional: presenting invented legal consent would not become lawful merely because the checkbox is attractively spaced.
|
||||
@@ -0,0 +1,11 @@
|
||||
Gate,Severity,Status,Evidence,Owner,Exit_criteria
|
||||
Approved CRM/lead destination,High,Blocked,EXTERNAL_SERVICE_INVENTORY_v1.0.csv,Sales Ops + Engineering,"Exit P9-002 with vendor, credentials, mapping, duplicate/retry policy and sandbox tests."
|
||||
Approved legal/privacy/consent,High,Blocked,CONSENT_MATRIX_v1.0.csv,Legal,"Exit P9-003 with localized text, legal basis, retention and deletion."
|
||||
Approved analytics provider/consent,High,Blocked,ANALYTICS_EVENT_REGISTRY_v1.0.csv,Analytics + Legal,Exit P9-004 and prove consent gating/no PII.
|
||||
Production demo enablement,High,Blocked by validator,src/lib/integrations/environment.ts,Product + Engineering,Approved production adapter and legal decisions.
|
||||
Security review,High,Partial,SECURITY_REVIEW_REPORT_v1.0.md,Security + Engineering,Dynamic CSRF/replay/dependency/CSP review in pinned CI.
|
||||
Privacy review,High,Partial,PRIVACY_REVIEW_REPORT_v1.0.md,Legal + Privacy,"Approve data flow, recipients, retention, deletion and transfers."
|
||||
Browser/accessibility/visual execution,High,Environment blocked,Authored Phase 14 suites,QA + Accessibility,Run in unblocked pinned-browser CI and approve baselines.
|
||||
Native FR/AR review,High,Open,Mechanical locale parity only,Localization,Native review all form/status/error copy.
|
||||
Exact runtime/install/audit,Medium,Environment blocked,Phase 14 command logs,Engineering + Security,"Node 24.17.0, pnpm 11.9.0 frozen install and audit."
|
||||
Alternate sales contact,Medium,Blocked,DESTINATION_REGISTRY_v1.0.csv,Sales Ops,Approved fallback destination.
|
||||
|
@@ -0,0 +1,25 @@
|
||||
# Phase 14 Security Review
|
||||
|
||||
## Implemented controls
|
||||
|
||||
- Strict allowlisted request and guard schemas with unknown-field rejection.
|
||||
- POST-only route handler with JSON content-type enforcement.
|
||||
- 16 KiB declared and measured request-size limits.
|
||||
- Same-origin or approved-origin validation.
|
||||
- Custom request marker to force non-simple cross-origin requests through browser preflight.
|
||||
- Server-side enum, length, locale, source, and UUID validation.
|
||||
- HTML rendering remains React-escaped; external errors are never rendered.
|
||||
- Adapter calls are bounded by `AbortController` timeout.
|
||||
- Duplicate transport is coalesced by idempotency key.
|
||||
- Production secrets have no public environment variable.
|
||||
- Local/test adapters are blocked in deployed production configuration.
|
||||
- No raw request body, form value, vendor response, or stack trace is logged or returned.
|
||||
- No external URL or redirect destination is active.
|
||||
|
||||
## Deliberately unresolved
|
||||
|
||||
A production-grade distributed idempotency store, rate limiting, retry policy, CRM authentication, webhook verification, replay policy, vendor scopes, email-header defense, scheduler origin policy, and operational alerting depend on the selected service and architecture. They remain release gates rather than fake generic implementations.
|
||||
|
||||
## Residual risk
|
||||
|
||||
The local in-memory idempotency coordinator is process-local and exists only to test the boundary. It is not suitable for horizontally scaled production. The honeypot is proportionate for local testing but is not a complete abuse control. Dynamic security testing, dependency audit, browser CSP validation, and penetration review remain open because dependencies and browsers could not be executed in this environment.
|
||||
@@ -0,0 +1,10 @@
|
||||
State,User_message,Input_preserved,Retryable,Focus_or_announcement,Production_status
|
||||
client validation,localized summary/field errors,Yes,After correction,alert then first invalid,Implemented
|
||||
server validation,localized-safe mapped codes,Yes,After correction,summary/invalid field,Implemented
|
||||
submitting,localized busy label,Yes,Duplicate disabled,aria-busy/polite status,Implemented
|
||||
local success,states no real sales request,Cleared only on new request,n/a,polite success section,Non-production only
|
||||
timeout,localized retry guidance,Yes,Yes,form summary,Implemented
|
||||
integration failure,generic; no vendor detail,Yes,Normalized policy,form summary,Implemented
|
||||
configuration blocked,approval incomplete,Yes,No,summary/disabled trigger,Implemented
|
||||
duplicate transport,same in-flight/result response,Yes,No duplicate,single result,Local boundary only
|
||||
abuse/honeypot,non-revealing rejection,Not promised,No,form summary,Implemented
|
||||
|
Reference in New Issue
Block a user