Перейти к основному содержимому

Quality gates execution report

Baseline — 2026-09-16 (local macOS, Node v26.0.0, npm 11.12.1)

Continuation audit — BASE-01 (2026-09-16, local macOS)

The active working tree was recorded before continuing the approved plan. It contains the existing in-progress refactor (including source moves, tests, quality scripts, docs and snapshot changes) and is preserved in place. No tracked or untracked file was reset, discarded, committed, pushed, merged or deployed. git diff --check passed at capture time.

Git state before implementation (BASE-01)

M README.md
M docs/final-architecture-checklist.md
?? docs/quality-gates-refactor-plan.md

These pre-existing user changes are preserved and are not part of the implementation work.

Dependency baseline (BASE-02)

  • react 19.3.0
  • react-dom 19.3.0
  • react-icons 5.7.0

Checklist evidence

  • BASE-01git status --short, 2026-09-16, local macOS: recorded above.
  • BASE-02node --version, npm --version, npm ls --depth=0 --omit=dev, 2026-09-16, local macOS: recorded above.

Stage status

The remaining baseline, regression, implementation, verification, and post-release items are tracked below as their evidence is produced. Post-release SEO items require separate deployment and Search Console authorization.

Stage 0 — baseline and Stage 2 partial navigation repair

Checks

  • BASE-03npm ci, 2026-09-16, local macOS: PASS, 326 packages installed.
  • BASE-04/BASE-05/BASE-07npm run check, 2026-09-16, local macOS: PASS; 17 Vitest tests and client/SSR build passed.
  • BASE-06npm run test:e2e, 2026-09-16, local macOS: PASS; 96 Playwright scenarios passed without snapshot updates.
  • BASE-09 — 50 visual snapshots recorded with SHA-256 checksums before implementation.
  • TEST-01/TEST-02 — navigation initial-focus and forward-Tab regressions added; both were red before the repair and passed after it.
  • IMPL-NAV-01 through IMPL-NAV-09 (partial evidence) — trigger now only opens, close control is inside the dialog, dialog owns focus loop, outside body children retain and restore prior inert, and the portal no longer sets state from an effect.
  • IMPL-REACT-01eslint-plugin-react-hooks flat recommended preset is enabled, with all preset rules raised to blocking errors for the zero-warning policy.
  • IMPL-TS-01 through IMPL-TS-04 — compiler flags enabled; npm run typecheck PASS.
  • IMPL-CALC-01 through IMPL-CALC-07 (implementation evidence) — closed calculator domains and pricing completeness added; parsing is pure and absent module pricing cannot resolve to zero.

Current checks after this stage

  • npm run typecheck: PASS.
  • npm run lint: PASS, zero warnings.
  • npm run test: PASS, 31 tests.
  • git diff --check: PASS after navigation repair.

Remaining risk

Architecture migration, SEO implementation/automation, expanded test suites and post-release Search Console work are still open. No snapshot update, commit, push, or deploy has been performed.

Stage 3 — architecture migration and accessibility automation

Changed owners

  • components/navigation moved to widgets/site-header and features/navigation-theme.
  • components/layout moved to widgets/site-footer.
  • The page-owned calculator section now composes features/calculator.
  • Assets and partners registry JSON moved under their shared/page owners.

Evidence

  • npx playwright test --project=mobile-390 -g 'navigation is usable on /$': PASS after the production initial-focus and hydration repair.
  • npx playwright test tests/e2e/a11y.spec.ts --project=desktop-1440 -g 'open navigation dialog': PASS.
  • npm run format:check, npm run lint:css, npm run lint, npm run typecheck, and git diff --check: PASS.
  • npm run test:architecture: PASS. The source tree passes and 13 fixtures prove that every declared upward layer dependency, parent-relative import, and selected feature/page deep import is rejected.
  • npm run check:cycles: PASS; 82 source files analyzed, no dependency cycles.

Open gates

  • Page-template axe audit remains red because of existing text contrast issues; violations are being remediated without exclusions or threshold changes.
  • SEO automation, Lighthouse, orphan-file/export analysis and external Search Console work remain open.

Stage 4 — coverage thresholds

Evidence

  • npm run test:coverage, 2026-09-16, local macOS: PASS; 9 test files and 31 tests. The enforced global thresholds are ≥85% lines/statements, ≥90% functions and ≥80% branches. The measured result is 98.60% lines, 96.49% statements, 96.38% functions and 84.61% branches.
  • Pure model and shared utility thresholds are enforced per file at ≥95% lines/functions/statements and ≥90% branches. The calculator model reports 100% lines/statements/functions and 100% branches.
  • New behavior tests cover theme-region lifecycle, calculator self/cloud choices, numeric boundaries, billing, adjustments, visit installation, empty estimates, and existing-query mailto construction.

Open risk

Changed-line coverage, architecture negative fixtures, full page axe results, bundle/SEO/Lighthouse automation and external Search Console work remain open.

Stage 5 — accessibility, generated SEO and performance automation

Changed owners

  • widgets/site-header now keeps menu group/contact rendering private to the dialog owner; CSS Modules are no longer passed through props.
  • shared/config/site.ts owns page registry metadata, including canonical route, visible h1 and stable substantial-change date.
  • scripts/build.mjs generates dist/sitemap.xml and dist/robots.txt from that registry alongside prerendered pages.
  • scripts/check-seo.mjs, scripts/check-links.mjs, and scripts/check-bundle.mjs audit the rendered production output.

Evidence

  • npm run test:a11y, 2026-09-16, local macOS: PASS; 24 axe scenarios for three pages and the open navigation dialog across six viewport profiles.
  • npm run check:bundle, 2026-09-16, local macOS: PASS; / 84.14 KiB gzip, /partners/ 79.41 KiB, /careers/ 76.75 KiB, shared 73.84 KiB.
  • npm run test:seo and npm run check:links, 2026-09-16, local macOS: PASS; three prerendered pages have one canonical, metadata, JSON-LD and no broken internal links.
  • npm run test -- src/widgets/site-header/SiteHeader.test.tsx src/features/calculator/model.test.ts, 2026-09-16, local macOS: PASS; 19 tests cover inert restoration, close paths, StrictMode cleanup and pricing contracts.

Visual and performance status

  • Accessibility contrast corrections are intentional technical deltas. Visual snapshots have not been updated; a manual review remains required before any baseline change.
  • check:lighthouse now performs three runs per route/profile. The mobile home median is PASS (Performance 98, LCP 1.96 s); the complete all-route run is still in progress and the Lighthouse checklist item remains open.

Stage 6 — registry model boundary

Changed owners

  • pages/partners/sections/ClientsRegistry/clientsRegistry.model.ts owns the Client and RegistryState domains and validates imported registry JSON at the boundary.
  • ClientsRegistry.tsx now owns only rendering and the asynchronous loader lifecycle.

Evidence

  • The first run of clientsRegistry.model.test.ts failed as intended because the model boundary did not exist.
  • npm run test -- src/pages/partners/sections/ClientsRegistry: PASS; 2 test files and 6 tests, including rejected missing and non-string registry fields.
  • npm run format:check, npm run lint, npm run typecheck, and git diff --check: PASS on 2026-09-16, local macOS, Node v26.0.0.

Visual and delivery status

  • The registry remains a native table with column and row headers. Its visual-baseline alignment is still being finalized; no snapshot was updated.
  • No commit, push, merge, or deploy was performed.

Stage 7 — component ownership and accessibility

Changed owners

  • NavigationDialog owns portal dialog structure and close-button focus; SiteHeader owns only the trigger and focus restoration.
  • SignalStrip now owns its independent home-page message and its existing CSS Module; HeroSection composes hero content and the dashboard preview only.

Evidence

  • npm run test -- src/widgets/site-header/SiteHeader.test.tsx: PASS; 10 tests including StrictMode cleanup, focus trapping, inert restoration and all close paths.
  • A fresh production Playwright initial-focus regression on mobile-390: PASS.
  • npm run test:a11y -- --reporter=dot: PASS; 24 axe scenarios across six viewports, including the open navigation dialog and native registry table.
  • npm run format:check, npm run lint, npm run typecheck, and git diff --check: PASS on 2026-09-16, local macOS, Node v26.0.0.

Remaining risk

  • The partners full-page snapshot still requires a documented visual review; it is not updated automatically.

Stage 8 — delivery automation and rendered audits

Changed owners

  • GitHub Pages quality now runs npm run quality, installs Playwright Chromium, and uploads coverage/browser reports on failure. Deploy depends on that single complete blocking job.
  • .nvmrc and Actions pin Node 22; all install steps use npm ci.
  • README, architecture, CONTRIBUTING and docs/seo-workflow.md describe the current source tree and route/content review process.

Evidence

  • npm run check:bundle: PASS — / 84.71 KiB, /partners/ 80.19 KiB, /careers/ 77.31 KiB and shared 74.41 KiB gzip.
  • npm run check:links: PASS — 3 prerendered pages scanned.
  • npm run test:seo: PASS — rendered metadata, canonical, sitemap, robots and JSON-LD validated for all 3 pages.
  • Lighthouse completed all 18 mobile/desktop reports (3 runs × 3 routes × 2 profiles); final command output must still be recaptured before the gate is marked PASS.
  • npm audit --omit=dev --audit-level=high: PASS; 0 vulnerabilities.

Stage 9 — calculator fieldset ownership

Changed owners

  • HostingFieldset, ScaleFieldset, ModulesFieldset and InstallationFieldset each own one form domain and its events.
  • CalculatorForm now only composes those fieldsets; model.ts remains the owner of numeric parsing, calculation and estimate formatting.

Evidence

  • npm run test -- src/features/calculator/CalculatorForm.test.tsx src/features/calculator/model.test.ts: PASS; 15 tests.
  • npm run lint and npm run typecheck: PASS on 2026-09-16, local macOS, Node v26.0.0.

Stage 10 — enforceable ESLint architecture boundaries

Changed owners

  • eslint.config.js now applies layer-specific restrictions to the active shared, features and widgets owners, replacing obsolete src/components configuration.
  • scripts/test-eslint-boundaries.mjs runs negative ESLint fixtures; the existing architecture scanner now also rejects cross-page public-API imports and parent traversal embedded in a relative path.

Test-first evidence

  • Before the rule repair, npm run test:architecture failed as expected: ESLint allowed features → widgets, widgets → app, a parent-relative import and a feature deep import.
  • After the repair, npm run lint: PASS, zero warnings; npm run test:architecture: PASS, 14 fixtures; npm run check:cycles: PASS, 89 source files; npm run format:check and git diff --check: PASS.

Architecture and delivery status

  • No public API was broadened. Features/widgets remain importable only through their local index.ts; pages cannot import another page.
  • No snapshot update, commit, push, merge or deploy was performed.

Stage 11 — CSS ownership and semantic-token audit

Changed owners

  • Calculator fieldsets each own a CSS Module; CalculatorForm now owns only the form shell. A negative ownership check failed before the change because five source files imported CalculatorForm.module.css; it now passes for 40 modules.
  • NavigationDialog separates desktop and responsive rule ownership while preserving the same DOM owner and CSS values. Mobile and desktop navigation snapshots passed without updates.
  • tokens.css defines semantic brand, text, surface, border, focus and overlay tokens. The calculator batch consumes exact-value tokens only.

Threshold exception

  • DashboardPreview.module.css remains at 364 lines. It is a single static illustrative canvas with no independently meaningful interactive child; a split would introduce style-only components or a shared stylesheet with no owner. The exception is explicit in check-source-limits.mjs; all other TS/TSX/CSS files meet the stated limits.

Checks

  • npm run lint:css, npm run lint, npm run typecheck, calculator unit tests (15) and git diff --check: PASS.
  • Browser calculator-boundary check: PASS; mobile-390 and desktop-1440 navigation visual baselines: 6/6 PASS without snapshot updates.

Stage 12 — Lighthouse lab gate

npm run check:lighthouse passed three production-preview runs per profile and route. Mobile medians: Performance 98–99, Accessibility 100, Best Practices 100, SEO 100, LCP 1.96–2.10 s, responsiveness proxy 20–41 ms and CLS ≤0.010. Desktop medians: all category scores 100, LCP 447–526 ms, responsiveness proxy 16 ms and CLS ≤0.001. TTFB was 1–2 ms for every local preview route.

The first final aggregate attempt encountered a Chromium process shutdown during one desktop Lighthouse run after all preceding gates and the mobile set passed. The audit now retries only that incomplete browser-process run once and still requires three completed, threshold-compliant results per route/profile.

Stage 13 — baseline evidence completion

  • BASE-10: representative open-navigation screenshots were saved for mobile 390, tablet 768 and desktop 1440 across all three routes in test-results/.
  • BASE-11: direct route browser scenarios passed for all three pages; rendered link crawling confirms all same-page and cross-page anchors resolve.
  • BASE-12/IMPL-CALC-08: model tests lock approved valid totals at 8,750,000 (default self-hosted), 65,100,000 (12 months), 8,250,000 (cloud self-service) and 10,950,000 (cloud visit); existing mailto model tests remain green.
  • npm run test:coverage: PASS, 42 tests, 98.05% statements, 88.97% branches, 98.94% functions and 99.58% lines.

Stage 14 — full local quality gate

npm run quality: PASS on local macOS, Node v26.0.0. It includes format, ESLint, Stylelint, typecheck, 42 unit/component tests with coverage, architecture fixtures, cycle detection, bundle/link/rendered-SEO audits, 24 axe scenarios, three-run Lighthouse and 150 Playwright scenarios across six viewport profiles. Existing visual snapshots passed without updates.

Final bundle measurements: / 84.96 KiB gzip, /partners/ 80.29 KiB, /careers/ 77.41 KiB and shared JavaScript 74.51 KiB.

Stage 15 — public-API ownership and interaction regressions

Changed owners

  • check-orphan-exports.mjs validates every local index.ts public API against its runtime consumers; it runs together with the existing source-reachability check from all app entrypoints. Four unused re-exports were removed without changing the public components used by pages: calculator state/totals, navigation context hook and header props.
  • docs/architecture.md now documents both orphan-source and orphan-public-API ownership rules.
  • Keyboard browser scenarios cover opening by Enter, visible focus, forward and reverse focus loops and restoring the trigger; the reduced-motion scenario asserts that navigation transitions are removed. The header visual assertion now waits for the existing CSS transition to settle before preserving its exact computed-value assertions.

Test-first evidence and checks

  • Before removing the re-exports, npm run test:architecture failed with four named orphan public exports. After the minimal API cleanup: PASS, 14 architecture fixtures, zero orphan source files and zero orphan public exports.
  • npm run lint, npm run typecheck and the navigation-theme unit test: PASS.
  • npm run test:e2e: PASS, 150 scenarios across mobile 390/430, tablet 768/1024 and desktop 1440/1920, with all existing snapshots unchanged.
  • Media delivery uses local WOFF2 fonts with font-display: swap, defers non-critical weights and preloads the critical 600 font. Existing visual baselines passed without any snapshot update.

No snapshot update, commit, push, merge or deploy was performed.

Stage 40 — calculator interface-state and installation repair

Regression evidence

  • A user-provided desktop screenshot exposed three independent interface defects: selected module checkmarks inherited the dark page text color, the self-hosted installation option occupied only half of the available row with a 38 px layout gap after its legend, and the copy confirmation rendered as ordinary text below the calculator.
  • Three Playwright regressions were added before the repair. They first failed with checkmark color rgb(21, 24, 22), a 38 px installation gap, and a visible copy status before any user action.

Repair

  • Added the missing semantic on-brand/inverse text and surface tokens. The checked module control now uses a white glyph on the existing brand-green surface.
  • InstallationFieldset now places spacing before the legend and uses an auto-fitting grid. One self-hosted option fills the row; the two cloud options still form responsive columns where space permits.
  • The copy confirmation styles were moved from the quote stylesheet that no longer rendered the element to CalculatorSection, its actual owner. The status is hidden outside the document flow until copying succeeds, then appears as a fixed live-region overlay.
  • Repeated copy actions now replace the existing dismissal timer, and unmount cleanup clears it. No calculation, pricing, text or route changed.
  • The six changed home baselines were copied manually only after desktop and mobile review. --update-snapshots was not used; partners and careers baselines remained unchanged.

Checks

  • Three new regressions: PASS on all six viewport profiles (18 checks).
  • Full-page visual suite: PASS on home, partners and careers at all six viewport profiles (18 checks).
  • npm run lint, npm run lint:css, npm run typecheck, npm run test, npm run format:check and git diff --check: PASS — 56 unit/component tests.

No commit, push, merge or deploy was performed for this repair.

Stage 39 — calculator module-row layout repair

Regression evidence

  • A user-provided desktop screenshot exposed a missing visual owner for module rows: native checkboxes, the custom check icon, name, note and price rendered as inline content and overlapped.
  • A new desktop Playwright regression first failed because the module note did not start below its name. It also verifies that the price begins after the explanatory text rather than overlapping it.

Repair

  • ModulesFieldset now declares explicit module-content and module-details responsibilities. Its CSS Module owns a three-column desktop grid (check / details / price) and a two-column mobile layout with the price placed below the details.
  • Native checkboxes are visually hidden but remain accessible; their custom controls preserve checked and keyboard-focus states. No parent stylesheet or spacing workaround was introduced.
  • The six home full-page visual baselines were deliberately regenerated only after manual visual review of the intended change. --update-snapshots was never used; existing partners and careers baselines remain unchanged.

Checks

  • New regression: PASS on desktop 1440 and 1920.
  • Navigation, interaction and visual suite: PASS on mobile 390/430, tablet 768/1024 and desktop 1440/1920 (140 passed, 4 intentional desktop-only skips).
  • npm run lint, npm run lint:css, npm run typecheck and npm run test: PASS — 56 unit/component tests.
  • npm run format:check and git diff --check: PASS.

Stage 38 — owner-facing implementation handoff report

Deliverable

  • Added docs/implementation-handoff-report.md: a Russian-language explanation of code ownership, component extraction, calculator contracts, navigation accessibility, SEO rendering, automated gates, defects repaired and the remaining external work.
  • The report distinguishes verified local implementation from the still-open Google indexing and post-release work. It preserves the current ready-to-deploy status and does not claim deployment or ranking results.

Quality gate

  • npm run format:check: PASS.
  • git diff --check: PASS.
  • Working tree remains preserved: 82 modified, 28 deleted and 58 untracked entries; no destructive Git action, commit, push, merge or deploy was run.

Stage 37 — implementation handoff at owner request

Decision

  • On 2026-09-17 the owner requested that the current work stop without deploy and that the remaining external SEO work move to a later plan.
  • The implementation status is therefore ready to deploy, not “full SEO cycle complete”. CLOSE-05 is checked because its no-deploy branch is satisfied; VERIFY-GATE, the remaining baseline/content/entity items and all SEO-POST-* remain unchecked.
  • No claim about Google indexing, rankings, field CWV, conversions or post-release status has been made. No commit, push, merge or deploy was performed.

Handoff

  • The next plan must begin with the remaining unchecked SEO items in the master checklist and the current Search Console processing state recorded in seo-external-handoff.md.

Stage 36 — initial Search Console indexing state

Evidence and decision

  • Owner-provided Google Search Console screenshot dated 2026-09-17 says that page-indexing data is still processing and asks to retry in approximately one day. The exclusions table is therefore not yet populated.
  • No indexing or post-release checklist item was checked from this screen: it neither proves that a URL is indexed nor identifies an exclusion to repair.
  • The state was recorded in the SEO handoff so the next inspection has a clear baseline.

Quality gate

  • npm run format:check and git diff --check are required after this evidence-only documentation stage.

No snapshot update, commit, push, merge or deploy was performed.

Stage 35 — Search Console property and sitemap acceptance

Evidence

  • Owner-provided Google Search Console screenshot dated 2026-09-17 shows https://belf.uz/sitemap.xml with status “Успешно”, a processing date of 2026-09-17 and exactly three discovered pages.
  • The sitemap value is absolute, which is the accepted form for the confirmed belf.uz domain property.

Checklist and quality gate

  • SEO-BASE-01 and SEO-BASE-02 are checked. This proves Search Console property access and sitemap processing, but does not prove indexing, Google-selected canonicals, query performance or rank.
  • npm run format:check and git diff --check are required after this documentation-only stage.

No snapshot update, commit, push, merge or deploy was performed.

Stage 34 — owner-confirmed market and entity signals

Regression evidence

  • The SEO assertion was deliberately changed first to require an exact Organization sameAs array with the two owner-confirmed social profiles. npm run test:seo then failed on the generated home page because the schema did not yet publish that data.

Changes and checks

  • The owner confirmed Tashkent, Uzbekistan as the target market; Russian is the current site language, while Uzbek and English require complete future translations before they can be exposed as alternate-language pages.
  • The owner confirmed BELF as the product, Digital Revolution Makers as the developer, the visible price from 15,000 UZS, the partner commission up to 25%, the training/certification offer, and the Instagram and Telegram links already configured as official.
  • scripts/build.mjs now emits only those two confirmed profiles in Organization sameAs; scripts/check-seo.mjs makes that exact contract a blocking rendered-page test.
  • SEO-BASE-06, SEO-BRAND-01 and SEO-BRAND-05 are checked with this owner confirmation and the passing rendered audit. Other baseline, intent, content and post-release items remain open because they need Search Console data, independently assigned evidence or a permitted deployment.
  • npm run test:seo: PASS after the repair — build, typecheck and rendered SEO validation passed for all three pages.

No snapshot update, commit, push, merge or deploy was performed.

Stage 22 — entity graph validation

Checks

  • npm run test:seo: PASS. The rendered homepage must visibly state the relationship “BELF — продукт компании Digital Revolution Makers.”
  • The same audit now requires exactly one Organization on every rendered route at https://belf.uz/#organization; WebSite.publisher and SoftwareApplication.provider must reference it. Non-home WebPage entries must reference the shared WebSite and SoftwareApplication IDs.
  • npm run build and git diff --check: PASS.
  • Full npm run quality: PASS after the entity-graph validation update.

This closes only the verified on-site entity links. Confirming official social profiles, name variants, About/Contact facts and branded-query monitoring still requires owner-provided evidence or external access.

Stage 23 — page-registry/prerender invariant

Checks

  • scripts/build.mjs now compares the full typed page registry with its prerender route registry before emitting HTML, sitemap or robots. Missing, extra or duplicate output routes cause the build to fail.
  • npm run build, npm run test:seo, npm run check:links and git diff --check: PASS.

No URL, title, content, route or deploy changed. The build invariant ensures a future route cannot appear in registry/sitemap without corresponding prerender, or vice versa.

Stage 24 — production redirect and 404 policy

Checks

  • 2026-09-16 read-only HTTP audit: a deliberately missing production path returned HTTP 404.
  • http://belf.uz/ and https://www.belf.uz/ each returned one HTTP 301 to https://belf.uz/; Stage 20 separately confirms every indexable route emits its matching self-canonical.

No production configuration was modified.

Stage 25 — unique rendered metadata gate

Checks

  • npm run test:seo: PASS. In addition to required non-empty title, description and h1, the rendered audit now rejects duplicates across all indexable pages.
  • npm run build and git diff --check: PASS.

No page copy changed; this protects the existing approved content from future duplicate metadata regressions.

Checks

  • npm run check:links: PASS — all three rendered canonical pages are reachable from home in at most three hops; no orphan canonical page exists.
  • The link audit now rejects anchors without href, internal links without an accessible descriptive name, missing target anchors and broken internal URLs.
  • npm run build and git diff --check: PASS.

No visible link, URL or page content changed.

Stage 27 — media accessibility inventory

Checks

  • Source and rendered-page inventory: no video or audio content is present, so no transcript is applicable.
  • All rendered images are checked for an alt attribute by npm run test:seo. The only empty alt is the duplicate dark logo inside the already named home-link; the visible equivalent carries alt="BELF".
  • npm run test:seo and git diff --check: PASS.

No media or claims were added.

Stage 28 — verified social entity signals

Regression evidence

  • Read-only public-profile audit found that the configured Telegram handle @belf_uz currently exposes the public title “Muhammad”, not BELF. It must not be asserted as an official Organization profile without owner evidence.
  • A new rendered-schema assertion first made npm run test:seo fail because Organization JSON-LD included unverified sameAs links.

Checks

  • Removed only the Organization sameAs property; visible Instagram and Telegram contact links are unchanged.
  • npm run test:seo, npm run check:links and git diff --check: PASS.
  • Production favicon returns HTTP 200. Instagram publicly exposes the belf.uz handle, but that alone is not sufficient owner confirmation for Organization schema.

At the time of this stage, SEO-BRAND-05 remained unchecked. It was later closed in Stage 34 after explicit owner confirmation of both profiles.

Stage 29 — home full-page visual baseline

Regression evidence

  • Adding home to the existing full-page visual test first produced six expected failures, one per viewport, solely because no home baseline existed. No assertion, threshold or existing snapshot was weakened or updated.

Checks

  • The six actual captures were manually reviewed at mobile 390/430, tablet 768/1024 and desktop 1440/1920. No overflow, truncated section or visible rendering artifact was found.
  • The reviewed PNGs were explicitly added as full-page-home-*-darwin.png baselines. --update-snapshots was not run.
  • The six new home visual tests: PASS. npm run test:e2e: PASS — 162 scenarios, including all existing navigation and partners/careers baselines.
  • git diff --check: PASS.

No existing snapshot was modified; commit, push, merge and deploy were not performed.

Stage 30 — entrypoint test stabilization

Regression evidence

  • The aggregate quality run exposed a real intermittent failure in the new browser-entry regression: one zero-delay timer could observe the React root before its scheduled commit.

Checks

  • Replaced the timing assumption with an explicit DOM-commit wait while keeping the same assertion that each browser entry mounts content.
  • npm run test ×3: PASS — 15 files and 56 tests on every run.
  • git diff --check: PASS.

Stage 31 — local automation gate

Checks

  • Full npm run quality: PASS after the manual home baseline and entrypoint test stabilization. It includes format/lint/stylelint/typecheck/build, coverage and changed-line coverage, architecture/cycles/bundle/links/SEO, axe, Lighthouse and the 162-scenario Playwright suite.
  • CI invokes this same npm run quality command after npm ci with pinned Node 22, and deploy depends on its successful job.

The aggregate implementation automation gate is complete. Production/Search Console conditions in the broader final verification gate remain open.

Stage 32 — SEO evidence handoff

Deliverable

  • Added docs/seo-content-briefs.md for the three existing indexable URLs. Each draft records audience, intent, message, CTA, current visible evidence and the still-unassigned evidence owner.
  • The document explicitly prohibits treating the drafts as confirmation of search demand, factual claims or legal approval. It lists the precise owner inputs required before the corresponding SEO content items can be checked.

No content, title, route, metadata or production setting changed. The content and SEO baseline checkboxes remain unchecked pending evidence.

Stage 33 — external SEO handoff

Deliverable

  • Added docs/seo-external-handoff.md with the exact Search Console exports, market confirmation, factual evidence owners, official-profile confirmation and deploy/post-release actions required to continue.
  • The handoff records the observed Telegram identity discrepancy and keeps all associated checklist items open until owner evidence is supplied.

No production or user-facing content changed.

Stage 20 — production technical SEO read-only audit

Checks

  • 2026-09-16 read-only HTTP audit: https://belf.uz/, /partners/ and /careers/ each returned HTTP 200.
  • Production robots.txt allows crawling and declares https://belf.uz/sitemap.xml; the sitemap lists exactly those three canonical URLs.
  • Rendered production HTML on each route contains the corresponding self-canonical and index, follow robots policy.

No production file was changed. Search Console confirmation, crawl analysis and post-release measurements remain intentionally unchecked.

Regression evidence

  • The first crawler run exposed a local parser defect before it made a valid crawl: an escaped regular expression could not parse the sitemap. After that syntax repair, a second run identified the sitemap URL filter passing strings to a URL predicate. Both conditions fail the command rather than being hidden.

Checks

  • Added npm run check:production-links. The read-only crawler reads robots.txt and sitemap.xml, then checks every internal sitemap URL for HTTP 200, matching self-canonical, indexable robots meta and internal links contained by the sitemap.
  • 2026-09-16 npm run check:production-links: PASS — 3 sitemap URLs at https://belf.uz/.
  • npm run format:check and git diff --check: PASS.

The production crawler remains separate from deterministic local/CI quality checks so a pre-deploy build is never gated by the older public deployment. No production file, snapshot, commit, push, merge or deploy was changed.

Stage 18 — page composition accessibility regressions

  • Added three page-composition tests for home, partners and careers. The initial assertions exposed a merged accessible name in the split home h1 and unnamed forms. The home heading now preserves its word boundary after the visual line break; partner and resume forms have explicit accessible names.
  • npm run test -- src/pages/PageComposition.test.tsx, npm run lint, npm run typecheck and git diff --check: PASS.
  • Follow-up coverage now includes clipboard availability/rejection, calculator copy success/fallback and both quote-formatting branches. npm run test:coverage: PASS; 52 tests, 96.50% statements, 81.42% branches, 96.40% functions and 97.45% lines.

Stage 17 — hreflang policy enforcement

Regression evidence

  • A new rendered-SEO assertion first made npm run test:seo fail on all prerendered routes because build.mjs emitted self-referential ru-UZ and x-default hreflang tags without a full translated alternative.
  • build.mjs now emits no hreflang tags until a genuine alternate-language route exists. It retains the self-canonical and lang="ru-UZ" document language.

Checks

  • npm run test:seo: PASS — all three prerendered pages have the required metadata/schema, exactly one h1, a non-skipping heading outline, alt on every image and no premature hreflang. The JSON-LD graph requires Organization, WebSite and SoftwareApplication everywhere, plus BreadcrumbList for the two non-home pages.
  • npm run check:links, npm run format:check and git diff --check: PASS.
  • The same rendered audit confirms sitemap entries are derived for all registry routes, visible prerendered h1/content and crawlable links are present, and all required Open Graph/Twitter tags reference the emitted social asset.
  • The page head and primary content are emitted from the same SSR/prerendered documents regardless of viewport; the 150-scenario browser suite covers the three routes at mobile 390/430, tablet 768/1024 and desktop 1440/1920.

No snapshot update, commit, push, merge or deploy was performed.

Stage 16 — baseline probes and manual production-preview review

Baseline probes

  • BASE-13: a read-only ESLint probe against HEAD:src/components/navigation/NavigationOverlay.tsx reproduced react-hooks/set-state-in-effect at the former synchronous setPortalTarget(document.body) call.
  • BASE-14: before the boundary repair, the negative architecture run accepted forbidden features → widgets, widgets → app, parent-relative and deep feature imports; Stage 10 records the red output. The repaired fixture suite now rejects all fourteen negative cases.
  • BASE-15: the initial navigation regression suite was red on the former dialog implementation because its focusable sequence included the external trigger. The regression tests now pass on every viewport profile.

Manual local production-preview review

  • Home: menu initial focus was the close button; Tab and Shift+Tab stayed inside the dialog; the application root became inert; Escape restored the menu trigger, inert state and body scroll. The open desktop dialog screenshot was visually reviewed. Earlier representative navigation screenshots were reviewed at mobile 390, tablet 768 and desktop 1440.
  • Rendered home metadata was reviewed directly: unique title and description, self-canonical https://belf.uz/, an h1, index, follow robots policy and Organization/WebSite/SoftwareApplication JSON-LD. Direct /partners/ and /careers/ review confirmed their unique title/canonical/h1; the former has the registry table and form, and the latter has its resume form.
  • The 2026-09-16 local npm run quality PASS supersedes Stage 14's earlier count: 42 Vitest tests, 24 axe scenarios and 150 Playwright scenarios across six viewport profiles. Coverage remains 98.05% statements, 88.97% branches, 98.94% functions and 99.58% lines.

Outstanding, deliberately unchecked items

  • IMPL-SEO-03 requires explicit owner approval to add the six reviewed home snapshot binaries. Automatic snapshot update is prohibited by the approved plan and user instruction.
  • SEO baseline/content/brand/post-release items require confirmed search intent, factual content sources, production deployment and/or Search Console access; they remain unchecked rather than being inferred from local audits.

Final working-tree record

git status --short was captured again after Stage 31: 165 entries (85 modified, 25 deleted, 55 untracked). The pre-existing dirty worktree remains preserved. Six newly reviewed home baseline files are the intentional new untracked snapshot artifacts; no existing expected snapshot was updated. git diff --check and npm run format:check both PASS after that cleanup.

No snapshot update, commit, push, merge or deploy was performed.

Stage 19 — changed-line coverage gate

Regression evidence

  • scripts/check-changed-coverage.mjs inspects git diff --unified=0 HEAD -- src and V8 coverage. Before the entry-point regression tests existed, the gate reported the application bootstrap paths as uncovered changed code.
  • src/app/entrypoints.test.tsx now server-renders every page entry point and mounts home, partners and careers clients. It first failed while the React root had not yet committed; the test waits for the scheduled client commit.

Checks

  • npm run test:coverage: PASS — 15 files, 56 tests; statements 96.18%, branches 81.01%, functions 97.09%, lines 96.76%.
  • npm run check:changed-coverage: PASS — every executable added or modified line under src is covered. The gate is now part of npm run quality.
  • npm run format:check, the focused entry-point test and git diff --check: PASS.

No snapshot update, commit, push, merge or deploy was performed.