diff --git a/STATUS.md b/STATUS.md index 7194b5eb..225bda18 100644 --- a/STATUS.md +++ b/STATUS.md @@ -14,6 +14,28 @@ - **The Cloudflare token recipe is in the install runbook** (S31): two permissions, one zone, nothing else. - **What remains of the sheet, in order:** the four DooPlex changes (I ask you in chat before each), one hub release (you present for the deploy), one box release, Glance behind the family gate, the capability map, the notification-settings design, and last the six hub readers. +## Monday 2026-10-12 (review round): a page-by-page review, and its findings fixed + +- **The contact form showed its red warning before anyone pressed anything** — on both contact + pages, from the moment the page opened. Fixed; the warning now waits for a send attempt. +- **The contact page promised an answer within 24 hours** while the test terms promise no reply + time at all. It now says 1–2 days usually, and that no reply time is promised during the test. +- **You speak in the first person now, everywhere a person speaks** (your answer): the contact, + tester and FAQ pages, and the home and services pages that repeat their promises, in both + languages. The legal texts are untouched, and „we” stays where it means you and me together. +- **The home page's „Mit tud a doboz ma?” has its content back**: three cards, each with 2–3 of the + services page's own points. +- **The two services pages were missing from the sitemap** — Google was never told they exist. + Added, and a new check now refuses any push that leaves a public page out of it. +- **The laptop clip was rebuilt**: your photos are the first scene, so the still a visitor sees + before it loads is a wall of real photographs. The film inside it is credited (Creative Commons, + attribution required — yesterday's note calling it public domain was wrong), and the demo + library's poster wall is cut. +- Also: a dead script that logged a warning on every inner page is gone, the tester button in the + menu is the proper blue, and the footer has a plain Facebook link (no script, nothing loaded). +- **Still waiting on someone else:** the server still sends everything uncompressed (R-931). That is + a change in the manifests repository, not here. + ## Monday 2026-10-12 (night): the laptop on the home page is playing - **Six apps, filmed by you, now run on the laptop's screen** on and the English diff --git a/scripts/site_gates.py b/scripts/site_gates.py index d52c88b7..2db01128 100644 --- a/scripts/site_gates.py +++ b/scripts/site_gates.py @@ -37,6 +37,10 @@ Gates (all must pass; non-zero exit on any failure): The sidebar's five category links pointed at #fajlkezeles-irodai and friends while the page's ids are #fajlkezeles and friends: 100 dead links across 20 pages, live, found by the operator clicking one + 24. sitemap — sitemap.xml lists every public page once, with its twin's hreflang pair, and lists + nothing else. /szolgaltatasok and /en/services existed, were linked from the home + page and answered 200 for a day without being in it: nothing here was checking + (operator's reviewer, 2026-10-12) 22. shell leak — MEDIA-AWARE: no declaration in site.css reaches a shell page on a selector that shell.css also styles. site.css loads FIRST, so a property shell.css never sets survives — „later wins” is per PROPERTY, not per rule. Earned live 2026-10-11: @@ -800,8 +804,48 @@ for _p in PAGES: if not _anchor_bad: print(" anchors: %d in-site #fragment(s), every one resolves" % _anchor_n) +# --------------------------------------------------------------------------------------------- +# gate 24 (2026-10-12): the sitemap lists every public page, and only public pages. +# A page can be live, linked and indexable while Google never hears of it - which is exactly what +# /szolgaltatasok and /en/services were for a day. The sitemap is a hand-maintained file next to a +# generated site, so it drifts silently; this is the check that was missing. +# The legal pages have no twin (R-813) but ARE public, so they are listed here by name. +_LEGAL_URLS = {"/adatkezeles", "/feltetelek"} +_SITEMAP = os.path.join(W, "sitemap.xml") +if not os.path.exists(_SITEMAP): + fail("sitemap.xml is missing — every public page is invisible to search engines") +else: + _sm = io.open(_SITEMAP, encoding="utf-8-sig").read() + _locs = [re.sub(r"^https?://felhom\.eu", "", u) for u in re.findall(r"([^<]+)", _sm)] + _want = set(URL.values()) | _LEGAL_URLS + _have = set(_locs) + for _u in sorted(_want - _have): + fail("sitemap.xml: %s is a public page and is NOT listed — search engines are told the site " + "has no such page" % _u) + for _u in sorted(_have - _want): + fail("sitemap.xml: %s is listed but is not a public page of this site (NO_TWIN pages and the " + "404 are deliberately not indexed)" % _u) + for _u in sorted(_u for _u in _locs if _locs.count(_u) > 1): + fail("sitemap.xml: %s is listed more than once" % _u) + # every twin pair carries BOTH alternates, in the same block, on both of its entries + _blocks = dict() + for _b in re.findall(r"(.*?)", _sm, re.S): + _m = re.search(r"([^<]+)", _b) + if _m: + _blocks[re.sub(r"^https?://felhom\.eu", "", _m.group(1))] = _b + for _hu, _en in TWINS.items(): + _hu_url, _en_url = URL[_hu], URL[_en] + for _u in (_hu_url, _en_url): + _b = _blocks.get(_u, "") + for _lang, _target in (("hu", _hu_url), ("en", _en_url)): + if 'hreflang="%s" href="https://felhom.eu%s"' % (_lang, _target) not in _b: + fail('sitemap.xml: the entry for %s does not name its %s twin ' + '(hreflang="%s" -> %s)' % (_u, _lang, _lang, _target)) + if not [f for f in fails if "sitemap.xml" in f]: + print(" sitemap: %d URL(s), every public page once, every twin pair cross-named" % len(_locs)) + if fails: print("\nSITE GATES FAILED: %d problem(s)" % len(fails)) sys.exit(1) print("site gates OK — BOM, emoji=0, nav/footer per language, analytics, no CDN, no legacy tokens, no