Website: the machine estimator (/gepigeny, /en/sizing), live but unlisted; SIZING.md §5 in three verdicts; R-997 filed
gates / gates (push) Successful in 6m42s
gates / gates (push) Successful in 6m42s
A household ticks apps and sees, for an 8, 16 and 32 GB box: fits well / fits, but tight / does not fit, the totals, and the apps that burst on CPU. One rule in assets/sizing.js, every number from assets/sizing-data.json (built by scripts/build_sizing_web.py from the 2026-10-13 N100 measurement; test: 7 cases, red-proofed). Unlisted: noindex, robots Disallow, not in the sitemap, linked from nowhere — site_gates.py gate 25 enforces it (UNLISTED twin pairs keep every twin check). SIZING.md §5 corrected: the 8 GB line contradicted its own x1.5 rule; guest sizes 4.0/11.4/27.4 GB with the measured 612 MiB MemTotal shortfall. R-993 gains the fact that the installer accepts a host below any minimum.
This commit is contained in:
+44
-6
@@ -109,6 +109,15 @@ URL = {"index.html": "/", "alkalmazasok.html": "/alkalmazasok", "technologiak.ht
|
||||
# English twin is written then, as a twin.
|
||||
NO_TWIN = {"szolgaltatasok-nonpublic.html", "404.html", "adatkezeles.html", "feltetelek.html"}
|
||||
|
||||
# UNLISTED (2026-10-13, the machine estimator) — a twin pair that is LIVE but deliberately unlisted until the
|
||||
# operator says "list it" (R-997). It gets every twin check (hreflang, globe, canonical, lang, no Hungarian on the
|
||||
# English page), and gate 25 adds what unlisted means: `noindex` on both pages, a `Disallow:` line for each URL in
|
||||
# robots.txt, absent from sitemap.xml, and linked from no other page. To LIST it: move the pair into TWINS, drop
|
||||
# noindex and the Disallow lines, add both URLs to the sitemap and a link from the menu — in one commit.
|
||||
UNLISTED = {"gepigeny.html": os.path.join("en", "sizing.html")}
|
||||
URL.update({"gepigeny.html": "/gepigeny", os.path.join("en", "sizing.html"): "/en/sizing"})
|
||||
ALL_TWINS = dict(TWINS, **UNLISTED)
|
||||
|
||||
MOCKUPS = set() # the design studies were deleted with website/preview/ at the M3 switch
|
||||
|
||||
# SHELL (2026-10-11, M3) — every public page now wears the controller's frame instead of the
|
||||
@@ -138,10 +147,12 @@ SHELL = {
|
||||
os.path.join("en", 'testing.html'),
|
||||
os.path.join("en", 'contact.html'),
|
||||
os.path.join("en", 'download.html'),
|
||||
'gepigeny.html',
|
||||
os.path.join("en", 'sizing.html'),
|
||||
}
|
||||
|
||||
PAGES = list(TWINS) + list(TWINS.values()) + sorted(NO_TWIN) + sorted(MOCKUPS) + sorted(SHELL)
|
||||
EN_PAGES = set(TWINS.values())
|
||||
PAGES = list(ALL_TWINS) + list(ALL_TWINS.values()) + sorted(NO_TWIN) + sorted(MOCKUPS) + sorted(SHELL)
|
||||
EN_PAGES = set(ALL_TWINS.values())
|
||||
HU_PAGES = set(PAGES) - EN_PAGES - MOCKUPS - SHELL
|
||||
ANALYTICS_EXEMPT = {"szolgaltatasok-nonpublic.html"} | MOCKUPS
|
||||
|
||||
@@ -425,7 +436,7 @@ def check_globe(p, lang, urls=None):
|
||||
|
||||
|
||||
ALT_RE = re.compile(r'<link rel="alternate" hreflang="([^"]+)" href="([^"]+)">')
|
||||
for hu, en in TWINS.items():
|
||||
for hu, en in ALL_TWINS.items():
|
||||
if hu not in pages or en not in pages:
|
||||
fail("twin pair %s <-> %s: a page of the pair is missing" % (hu, en))
|
||||
continue
|
||||
@@ -438,7 +449,7 @@ for hu, en in TWINS.items():
|
||||
canon = re.search(r'<link rel="canonical" href="([^"]+)">', pages[p])
|
||||
if not canon or canon.group(1) != SITE + URL[p]:
|
||||
fail("%s: canonical %r — it must point at the page itself (%s)" % (p, canon and canon.group(1), SITE + URL[p]))
|
||||
print(" twins: %d pairs checked both ways (hreflang, globe, canonical)" % len(TWINS))
|
||||
print(" twins: %d pairs checked both ways (hreflang, globe, canonical), %d of them unlisted" % (len(ALL_TWINS), len(UNLISTED)))
|
||||
for p in sorted(NO_TWIN): # no twin: the globe's structure, current mark and label still hold
|
||||
if p in pages:
|
||||
check_globe(p, lang_of(p))
|
||||
@@ -546,7 +557,7 @@ for p in sorted(x for x in pages if is_en(x)):
|
||||
if BEG.search(t):
|
||||
fail("%s: the site does not beg — no \"please\"/\"kindly\": %r" % (p, t[:120]))
|
||||
# the retrieval promise: the English page may make it no more often than its Hungarian twin does
|
||||
hu = next((h for h, e in TWINS.items() if e == p), None)
|
||||
hu = next((h for h, e in ALL_TWINS.items() if e == p), None)
|
||||
if hu and hu in pages:
|
||||
en_n = sum(len(re.findall(rx, t, re.I)) for t in visible_strings(s) for rx in _RET_EN)
|
||||
hu_n = sum(fold(t).count(fold(st)) for t in visible_strings(pages[hu]) for st in _RET_HU)
|
||||
@@ -817,7 +828,8 @@ if not os.path.exists(_SITEMAP):
|
||||
else:
|
||||
_sm = io.open(_SITEMAP, encoding="utf-8-sig").read()
|
||||
_locs = [re.sub(r"^https?://felhom\.eu", "", u) for u in re.findall(r"<loc>([^<]+)</loc>", _sm)]
|
||||
_want = set(URL.values()) | _LEGAL_URLS
|
||||
_unlisted_urls = {URL[_p] for _pair in UNLISTED.items() for _p in _pair}
|
||||
_want = (set(URL.values()) - _unlisted_urls) | _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 "
|
||||
@@ -844,6 +856,32 @@ else:
|
||||
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))
|
||||
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
# gate 25 (2026-10-13): an UNLISTED pair stays unlisted until the operator lists it (R-997). Live and reachable by its
|
||||
# link, but: noindex on the page, Disallow in robots.txt, absent from sitemap.xml, and no other page links to it —
|
||||
# each of the four is what "unlisted" means, and losing any one of them quietly publishes the page.
|
||||
_ROBOTS = os.path.join(W, "robots.txt")
|
||||
_robots = io.open(_ROBOTS, encoding="utf-8-sig").read() if os.path.exists(_ROBOTS) else ""
|
||||
_sm_locs = set(re.sub(r"^https?://felhom\.eu", "", u) for u in re.findall(r"<loc>([^<]+)</loc>", io.open(_SITEMAP, encoding="utf-8-sig").read())) if os.path.exists(_SITEMAP) else set()
|
||||
_unl_pages = {p for _pair in UNLISTED.items() for p in _pair}
|
||||
for _p in sorted(_unl_pages):
|
||||
_s = pages.get(_p, "")
|
||||
_u = URL[_p]
|
||||
_m = re.search(r'<meta name="robots" content="([^"]*)">', _s)
|
||||
if not _m or "noindex" not in [x.strip() for x in _m.group(1).split(",")]:
|
||||
fail("%s: an UNLISTED page without <meta name=\"robots\" content=\"noindex\"> — search engines may show it" % _p)
|
||||
if not re.search(r"(?m)^Disallow:\s*%s\s*$" % re.escape(_u), _robots):
|
||||
fail("robots.txt: no 'Disallow: %s' — the UNLISTED page %s is open to crawlers" % (_u, _p))
|
||||
if _u in _sm_locs:
|
||||
fail("sitemap.xml: %s is listed — an UNLISTED page must not be in the sitemap" % _u)
|
||||
_link = re.compile(r'href="(?:https?://felhom\.eu)?%s(?:[#?"])' % re.escape(_u))
|
||||
for _q in sorted(pages):
|
||||
if _q in _unl_pages:
|
||||
continue # the pair's own globe, canonical and alternates point at each other
|
||||
if _link.search(pages[_q]):
|
||||
fail("%s links to the UNLISTED page %s — it is published by that link" % (_q, _u))
|
||||
print(" unlisted: %d page(s) — noindex, robots Disallow, not in the sitemap, linked from no other page" % len(_unl_pages))
|
||||
|
||||
if fails:
|
||||
print("\nSITE GATES FAILED: %d problem(s)" % len(fails))
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user