13 KiB
Focused consultation completion and portal presentation correction
Date: 2026-10-30 UTC. Starting branch faithful-astro-migration, starting HEAD
e97f0ea9b475715a1ea58110a27cdf50a2b3cb19. Tracked tree and index were clean;
no untracked paths were reported at preflight. The checkpoint is the commit
containing this report; no push, deployment, Jotform mutation or real submission
is part of this correction.
Completion contract and implementation
Jotform Support
and its linked screenshot were inspected. The screenshot shows an object
containing action: 'submission-completed' and string formID emitted by the
thank-you document. It is provider documentation, not a captured submission
from AIA Form A. The earlier automated support response on the same thread
does not describe this contract; the later human support reply does.
The receiver is installed only for authorized consultation drawers. It requires:
- Open, non-closing drawer with an activated consultation iframe.
event.sourceequal to that iframe's actualcontentWindow.- Exact origin equal to the trusted server-rendered URL's origin:
https://form.jotform.com. No suffix, substring or wildcard match. - Exact action and string Form A ID
262946078314059matching that fixed URL. - No prior completion for this frame instance.
Object envelopes and JSON strings of at most 4096 characters are supported. Malformed, numeric-ID, unrelated and untrusted envelopes are rejected. Extra fields are neither collected nor logged. The receiver uses the existing gated URL instead of embedding a production ID/origin in a shared off-mode bundle. No cross-origin DOM inspection, message forwarding, tracking or submission handler was introduced. The official resize helper remains absent. This trusted-window UI signal is not an independent server-side receipt audit.
On acceptance, the current global key
aia:service-inquiry:auto-suppressed-until immediately receives a 30-day expiry.
The drawer reveals “Thank you! Your message has been received.” or
“¡Gracias! Hemos recibido su mensaje.” above the iframe and scrolls it into view.
The existing thank-you document remains untouched. The full 5000ms interval
precedes the existing 500ms slide-out; reduced motion removes only the animation.
Focus then returns through the existing close mechanism.
Duplicates do not extend the timer or expiry. Manual close cancels the countdown and retains suppression; navigation removes listeners/timers. Completed state survives lifecycle reinitialization. A subsequent deliberate CTA replaces the completed frame with a fresh node, clears only its fallback/load state, and activates the same fixed URL. Old WindowProxy messages then fail source checks. Incomplete frames remain intact across ordinary close/reopen. Load, validation, clicks and timeout never count as completion.
The four-second/half-scroll opening rules, manual override, shared suppression, bilingual text, no-JS fallback, sandbox, no-referrer and seven-production versus nine-consultation-test route boundaries are unchanged.
Portal presentation and evidence limits
Both streams use the same scoped presentation: blue section/subsection headings,
vertical spacing, list indentation, directories, orange action buttons and
visible focus. Only a narrow compatibility vocabulary maps to a local button
class: hs-button, content-button, portal-resource-button, or an exact
inline AIA orange background (#ffbd59/#ff914d). Styles themselves are never
copied. Contact destinations receive a dark-orange #a94600 underline treatment
for readable contrast against white; buttons retain AIA orange/blue tokens.
Table scope and numeric spans 1–99 preserve directory semantics.
Arbitrary classes, inline style/event handlers, scripts, forms, remote styles, iframes/media and unsafe URLs remain removed. Crypto, access-code handling, ciphertext, resource mapping and publication gates are unchanged.
The legitimate private footer was checked only for unencrypted stylesheet/class semantics; none were available. No real code was supplied and no actual stream was decrypted. Button tokens are narrow compatibility candidates, not verified real-view class inventory. Synthetic staff and management encrypted fixtures exercise both class-based and exact brand-fill mappings. Source-faithful restoration in the actual two views needs owner comparison; do not claim pixel parity or expose decrypted HTML to obtain that evidence. No employee resources, credentials, original HTML or real ciphertext were put in Git, screenshots or public static assets.
Spanish dropdown diagnosis
The owner observed five English service options and seven Spanish options,
including Pregunta general and Programar una visita guiada. Generated URLs:
| Locale | Exact consultation URL |
|---|---|
| EN | https://form.jotform.com/262946078314059?formContext=consultation&language=en |
| ES | https://form.jotform.com/262946078314059?formContext=consultation&language=es |
The three standalone and six drawer mappings use the same fixed form/context; only the locale differs. The parent does not create an extra intent question, preselect services, alter iframe fields or forward page queries. In test mode legacy drawer controls are absent from the active collection surface.
Likely boundary: Jotform multilingual option translations or Update Options / show-hide conditions retaining inquiry choices in Spanish. This is an inference from source and owner observations, not a Builder audit. Owner should open the direct hosted ES consultation URL and compare with EN and the embedded form. If the direct ES version also shows seven choices, review translations of the correct service question and every condition that changes its options. Preserve contact/landing behavior and verify exactly five consultation choices in both languages. No Jotform configuration or client-side workaround was attempted.
Verification
- Focused unit/isolation/artifact suites: 31 passing tests (including two new tests for completion-envelope validation and narrow portal presentation).
- Existing service/portal guarded browser suite: 47 grouped checks, 34 captures,
all six service routes at 320/390/768/1440px plus completion lifecycle checks
in EN/ES and both synthetic portal views. Evidence:
/tmp/aia-service-portal-eqwVDU/evidence.json. - Browser environment: repository Nix browser shell, Playwright 1.61.1,
Chromium
149.0.7827.55(actual executable version, not the earlier report's Chromium 151 baseline). No new npm dependency or environment configuration. - Focused correction rerun: 14 overlapping grouped checks, 10 captures,
/tmp/aia-service-portal-CX1fu8/evidence.json. This rerun adds explicit visible viewport bounds and viewport-only acknowledgment screenshots. CSS-transition time is allowed separately from virtual JavaScript timer time. Both checks passed; overlapping counts are not additional unique route coverage. - Desktop synthetic staff, mobile synthetic management and Spanish completion screenshots were visually inspected. Browser automation is not real screen-reader or fluent-language acceptance.
- The full browser run recorded 37 Jotform GET attempts fulfilled by local fixtures; focused rerun recorded six. All non-loopback requests were intercepted before transmission. Zero POST/DELETE, WebSocket, production API, analytics or advertising requests were attempted. Zero external browser requests were sent.
Reproduction from the existing browser development shell, after the isolated
build, is node tools/service-portal-browser.mjs --correction-only; omit that
flag to include existing timing/scroll/suppression regressions. Every external
request is intercepted, service workers are blocked, and portal ciphertext is
synthetic response injection. Screenshots remain outside Git.
Evidence JSON SHA-256 values:
- Full regression:
5ed8661fdec3a289f43aedeb17113586e4935542cf665ab94759d3aac8794d7a. - Focused correction:
36bc4804e86fe1d59c9547b8a629a45bef8baac10e34799b845fa1e7642e69fd.
Final validation:
| Check | Result |
|---|---|
npm run check (also executed by builds) |
151 files; zero errors, warnings, hints |
node --experimental-strip-types --test --test-concurrency=1 tools/*.test.mjs |
202 passed, zero failed/skipped; includes Markdown, publication, SEO, Library, routes, campaign, Phase 8, form preview/isolation/artifact and service/portal suites |
npm run audit:links |
Zero broken internal links |
npm run audit:images |
Zero missing mapped page images |
npm run audit:blog |
Zero content failures |
git diff --check |
Passed |
Documentation link review covered six changed documents. New links resolve.
One preexisting migration-summary link targets the archived
route-reconciliation-2026-10-20-offline.json; it is a historical reference
already documented by the handoff archive inventory, not an active dependency.
It remains preserved, and no archived report was read or modified.
Every mode ran npm run build and the matching
node tools/phase10-artifact-verify.mjs --mode=...:
| Build | Routes | Sitemap URLs | Hreflang | Immediate Form A frames | Deferred frames |
|---|---|---|---|---|---|
| Isolated test, all consultation flags approved | 128 | 0 | 0 | 10 | 6 |
| Fully approved production artifact (local only) | 127 | 109 | 180 | 7 | 0 |
| Indexing, forms off | 127 | 109 | 180 | 0 | 0 |
| Mock (staging verifier) | 128 | 0 | 0 | 0 | 0 |
| Final restored off staging | 128 | 0 | 0 | 0 | 0 |
All artifact checks passed with zero active native form actions. Final staging
has noindex,nofollow throughout. Production compilation never authorizes
deployment. Temporary review /lp remains absent from indexing artifacts.
Logs and sanitized artifact results are /tmp/aia-correction-*.log and
/tmp/aia-correction-*-artifact.json; no historical reconciliation was overwritten.
During development, the artifact verifier correctly rejected an early shared bundle containing the Form A ID. The receiver now derives expected origin/ID from the already authorized iframe URL; subsequent off/mock and gated artifact checks pass without weakening the verifier. Browser full-page captures were supplemented with viewport acknowledgment captures and visible-bounds assertions.
For consultation testing, set the existing six required values:
PUBLIC_AIA_FORMS_MODE=isolated-test \
PUBLIC_AIA_FORMS_ENVIRONMENT=isolated-test \
PUBLIC_AIA_FORMS_ISOLATED_TEST_APPROVED=true \
PUBLIC_AIA_FORMS_LIVE_APPROVED=false \
PUBLIC_AIA_FORMS_CONSULTATION_TEST_APPROVED=true \
PUBLIC_ALLOW_INDEXING=false npm run build
These settings are command-scoped; no local or deployed environment file changed.
Changed files
Implementation:
src/utils/jotform-completion.ts(new strict completion validator).src/scripts/service-inquiry.ts(completion lifecycle and suppression).src/components/ServiceInquiryDrawer.astro(localized acknowledgment).src/components/JotformIframe.astro(controlled completed-frame reset).src/utils/portal-presentation.ts(new narrow presentation mapper).src/scripts/employee-portal.ts(passive presentation/semantic mapping).src/components/pages/EmployeePortal.astro(scoped styles).
Tests: tools/service-portal.test.mjs, tools/service-portal-browser.mjs.
Documentation: this report, reports/SESSION_HANDOFF.md,
reports/phase-9-form-a-owner-acceptance-2026-10-28.md,
reports/phase-9-two-form-integration-specification-2026-10-28.md,
reports/migration-summary.md, integrations/employee-portal/README.md.
All paths above are relative to www/.
Owner acceptance and remaining blockers
- Perform one real synthetic consultation submission manually on the approved
isolated preview. Confirm actual
action,formIDand sender origin without recording submitted answers; verify five seconds, native confirmation, suppression, focus restoration, and fresh manual reopening. If the provider changes origin/shape, the listener intentionally fails closed. Do not broaden trust based on an unverified message. Check both locales' presentation. - Resolve the Spanish dropdown in Builder after comparing the direct hosted form; confirm five choices, requiredness and language-specific validation.
- Privately unlock both portal views and compare report buttons, directory spacing and focus on desktop/mobile. Supply only sanitized class semantics for any missing style mapping. Real resource access control/cutover remain separate decisions.
Seven production-eligible Form A routes remain unchanged. Production consultation routes, portal cutover and site cutover remain unauthorized. No approval gate is closed by fixtures, static artifacts or this checkpoint.