v0.297.0: burn-down round 2 — 24 small rows (R-591 R-568 R-567 R-363 R-547 R-10 R-552 R-251 R-104 R-619 R-362 R-675 R-256 R-257 R-240 R-365 R-425 R-565 R-564 R-603 R-454 R-208 R-457-swept) + the banner countdown and deepCopyStack twins; MinAgent 0.131.0
gates / gates (push) Failing after 50s
gates / gates (push) Failing after 50s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -17,6 +17,7 @@ Gates, in order (all must pass; **non-zero exit on any failure**):
|
||||
7. docker-v every `docker … -v` mount is a named volume or a proven host path
|
||||
8. debug-routes every debug-page control resolves to a handler, and back (R-400)
|
||||
9. reuse-refs every path cited by this repo's REUSE.md still resolves
|
||||
… gofmt every Go file is gofmt-clean (R-454)
|
||||
|
||||
WHY THIS FILE EXISTS (2026-08-02, closing R-29 leg (a) and half of leg (b)).
|
||||
|
||||
@@ -93,6 +94,9 @@ GATES = [
|
||||
# byte for byte. The template half of parity is proved by rendered fixtures; Go-side copy cannot
|
||||
# be, so it is proved structurally here. Fast: stdlib file reads.
|
||||
("go-parity", os.path.join(SCRIPTS, "i18n_go_parity.py"), [], True, True),
|
||||
# R-454 — every Go file is gofmt-clean. `go vet` does not check formatting; nothing did. Fast:
|
||||
# the toolchain's own formatter, no network, no container runtime.
|
||||
("gofmt", os.path.join(SCRIPTS, "gofmt_gate.py"), [], True, True),
|
||||
# R-404 — ADVISORY. Reports the golden debt where it is created; never refuses.
|
||||
("golden-notice", GOLDEN_NOTICE, [REPO], True, False),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""gofmt_gate.py — every Go file in this module is gofmt-clean (R-454).
|
||||
|
||||
MEASURED 2026-09-02: five internal/web test files had been gofmt-unclean for an unknown length of
|
||||
time and nothing noticed — `go vet` does not check formatting and no gate did. By 2026-10-05 the five
|
||||
were clean and TWELVE others were not: the count only grows while nothing looks, and every `gofmt -l`
|
||||
someone runs by hand is then noise that hides a real one.
|
||||
|
||||
Run from controller/: python3 scripts/gofmt_gate.py
|
||||
Exit 0 clean · 1 convicted (lists the files) · 2 inconclusive (gofmt not found — never a pass).
|
||||
|
||||
gofmt is the Go toolchain's own formatter (not a shell utility), found on PATH or under
|
||||
`go env GOROOT`/bin. Decoy: scripts/test_gate_decoys.py ("gofmt").
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
CTRL = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
ROOTS = ["cmd", "internal"]
|
||||
|
||||
|
||||
def find_gofmt():
|
||||
p = shutil.which("gofmt")
|
||||
if p:
|
||||
return p
|
||||
go = shutil.which("go")
|
||||
if go:
|
||||
try:
|
||||
root = subprocess.check_output([go, "env", "GOROOT"], text=True).strip()
|
||||
cand = os.path.join(root, "bin", "gofmt")
|
||||
if os.path.isfile(cand):
|
||||
return cand
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
gofmt = find_gofmt()
|
||||
if not gofmt:
|
||||
print("gofmt gate INCONCLUSIVE: gofmt not found on PATH or under `go env GOROOT`/bin")
|
||||
return 2
|
||||
roots = [r for r in ROOTS if os.path.isdir(os.path.join(CTRL, r))]
|
||||
if not roots:
|
||||
print("gofmt gate INCONCLUSIVE: none of %s exists under %s" % (ROOTS, CTRL))
|
||||
return 2
|
||||
p = subprocess.run([gofmt, "-l"] + roots, cwd=CTRL, capture_output=True, text=True)
|
||||
if p.returncode != 0:
|
||||
print("gofmt gate INCONCLUSIVE: gofmt exited %d: %s" % (p.returncode, p.stderr.strip()[:400]))
|
||||
return 2
|
||||
bad = [l for l in p.stdout.splitlines() if l.strip()]
|
||||
if bad:
|
||||
for f in bad:
|
||||
print(" not gofmt-clean: %s" % f)
|
||||
print("GOFMT GATE FAILED: %d file(s) — run `gofmt -w <file>` (formatting only, no behaviour change)" % len(bad))
|
||||
return 1
|
||||
print("gofmt gate OK — every Go file under %s is gofmt-clean" % ", ".join(roots))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -149,7 +149,13 @@
|
||||
"family_gate.msg.signed_in": "BORN AS A KEY, v0.287.0 (the family gate, decisions 63/64) -- a NEW sentence, never a Go literal. Pinned in both languages by TestFamilyGate_MessagesFollowTheReader.",
|
||||
"family_gate.msg.signed_out": "BORN AS A KEY, v0.287.0 (the family gate, decisions 63/64) -- a NEW sentence, never a Go literal. Pinned in both languages by TestFamilyGate_MessagesFollowTheReader.",
|
||||
"family_gate.msg.store_unreadable": "BORN AS A KEY, v0.287.0 (the family gate, decisions 63/64) -- a NEW sentence, never a Go literal. Pinned in both languages by TestFamilyGate_MessagesFollowTheReader.",
|
||||
"family_gate.msg.wrong": "BORN AS A KEY, v0.287.0 (the family gate, decisions 63/64) -- a NEW sentence, never a Go literal. Pinned in both languages by TestFamilyGate_MessagesFollowTheReader."
|
||||
"family_gate.msg.wrong": "BORN AS A KEY, v0.287.0 (the family gate, decisions 63/64) -- a NEW sentence, never a Go literal. Pinned in both languages by TestFamilyGate_MessagesFollowTheReader.",
|
||||
"note.offsite.fail_locked": "BORN AS A KEY (R-104) -- the cause line for a repository lock that survived the self-heal; a NEW sentence, never a Go literal. Pinned in both languages by TestR104_SurvivingLockIsNamed.",
|
||||
"err.backup.restore_drive_gone": "BORN AS A KEY (R-362) -- names the drive a restore could not reach instead of a raw permission error; a NEW sentence, never a Go literal. Pinned in both languages by TestR362_DetachedDriveIsNamed.",
|
||||
"restore.refuse.files.second_drive_whole": "BORN AS A KEY (R-675) -- the unit-restore refusal names the second drive's WHOLE restore (decision 26); a NEW sentence, never a Go literal. Pinned in both languages by TestR675_RefusalNamesTheWholeCopy.",
|
||||
"flash.offbox.mgr_unavailable": "R-256 -- REWORDED on purpose: the old „A mentéskezelő nem …\" named an internal component and no route; it now says what is wrong in plain words and where to go (try again, then support), so byte parity with the base literal cannot hold. Pinned in both languages by TestR256_R257_OffboxRefusalsNameARoute.",
|
||||
"flash.offbox.mgr_unreachable": "R-256 -- REWORDED on purpose: the old „A mentéskezelő nem …\" named an internal component and no route; it now says what is wrong in plain words and where to go (try again, then support), so byte parity with the base literal cannot hold. Pinned in both languages by TestR256_R257_OffboxRefusalsNameARoute.",
|
||||
"flash.offbox.not_orphaned": "R-257 -- REWORDED on purpose: the old sentence put an English loanword and the internal state name „elárvult\" in front of the household; it now says why the action does not apply and where to go, so byte parity with the base literal cannot hold. Pinned in both languages by TestR256_R257_OffboxRefusalsNameARoute."
|
||||
},
|
||||
"flash.share.already_on": "A megosztás már be van kapcsolva.",
|
||||
"flash.share.enable_failed": "A megosztás bekapcsolása nem sikerült.",
|
||||
@@ -190,7 +196,6 @@
|
||||
"flash.tier2.saved": "A 2. mentés beállítása elmentve.",
|
||||
"flash.tier2.app_email_off": "Email-küldés kikapcsolva ennél az alkalmazásnál.",
|
||||
"flash.tier2.app_email_on": "Email-küldés bekapcsolva ennél az alkalmazásnál.",
|
||||
"flash.offbox.mgr_unavailable": "A mentéskezelő nem elérhető.",
|
||||
"flash.offbox.fields_required": "A cél címe, a felhasználó és a tárhely útvonala kötelező.",
|
||||
"flash.offbox.path_absolute": "A tárhely útvonalának abszolútnak kell lennie (/-rel kezdődjön).",
|
||||
"flash.offbox.config_invalid": [
|
||||
@@ -220,13 +225,11 @@
|
||||
"flash.offbox.waiting_for_escrow": "A távoli mentés a kulcs letétbe helyezésére vár.",
|
||||
"flash.offbox.repo_orphaned": "A távoli tároló elárvult — előbb indíts új távoli mentést a kártyán látható módon.",
|
||||
"flash.offbox.run_started": "A távoli mentés elindult — az állapot itt frissül.",
|
||||
"flash.offbox.not_orphaned": "Az offsite tároló nincs elárvult állapotban.",
|
||||
"flash.offbox.needs_confirmation": "A visszaállításhoz megerősítés szükséges.",
|
||||
"flash.offbox.restart_started": "Új távoli mentés indítása folyamatban — a régi előzmény félretéve (nem törölve).",
|
||||
"flash.offbox.restore_started": "A távoli visszaállítás elindult — az állapot itt frissül.",
|
||||
"flash.offbox.full_needs_confirmation": "A teljes visszaállítás megerősítés nélkül nem hajtható végre.",
|
||||
"flash.offbox.full_restore_started": "A teljes visszaállítás elindult — az állapot itt frissül.",
|
||||
"flash.offbox.mgr_unreachable": "A mentéskezelő nem érhető el.",
|
||||
"flash.offbox.scratch_missing": "Hiányzó ellenőrző másolat.",
|
||||
"flash.offbox.delete_needs_confirmation": "A törlés megerősítés nélkül nem hajtható végre.",
|
||||
"flash.offbox.delete_failed": [
|
||||
@@ -1155,5 +1158,9 @@
|
||||
"update.phase.starting": "Indítás az új verzióval…",
|
||||
"update.phase.verifying": "Működés ellenőrzése…",
|
||||
"update.phase.done": "Frissítve",
|
||||
"update.phase.failed": "A frissítés nem sikerült"
|
||||
"update.phase.failed": "A frissítés nem sikerült",
|
||||
"restore.refuse.files.head": "Ez a mentés nem tartalmazza az alkalmazás fájljait, ezért nem állítjuk vissza az adatbázist föléjük — a fájlok így a helyükön maradnak. ",
|
||||
"restore.refuse.files.offsite": "A fájlok a távoli másolatból állíthatók vissza: Biztonsági mentés → Visszaállítás, „Teljes visszaállítás (fájlok + adatbázis)”.",
|
||||
"restore.refuse.files.second_drive": "A fájlok a második meghajtó másolatából állíthatók vissza: „Fájlok visszaállítása”.",
|
||||
"restore.refuse.files.none": "Ezekről a fájlokról jelenleg nincs másolat — kapcsold be a távoli mentést, vagy csatlakoztass egy második meghajtót."
|
||||
}
|
||||
|
||||
@@ -4,20 +4,45 @@ customer-facing: the productized target is the Storage Box and the tier concept
|
||||
so "NAS-mentés"-style branding must not reappear in the offbox feature's customer strings.
|
||||
Python, not grep: Hungarian multibyte (the Windows-grep false-negative rule).
|
||||
|
||||
Scope: ONLY the offbox feature's files. The "Hálózati tárhely" NAS network-storage feature is a
|
||||
Scope: ONLY the offbox feature's files — discovered by pattern since R-425, see scoped_files(). The "Hálózati tárhely" NAS network-storage feature is a
|
||||
DIFFERENT feature and keeps its device-truthful NAS wording (its files are not scanned). Allowed
|
||||
by construction (no banned token): the intro's "saját NAS vagy Felhom offsite tárhely" and the
|
||||
manual-target form's "NAS vagy SFTP-kiszolgáló" mentions, comments, code identifiers/routes.
|
||||
|
||||
Run from controller/: python scripts/offbox_rename_gate.py
|
||||
"""
|
||||
import io, os, sys
|
||||
import glob, io, json, os, re, sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import i18n_bundle # noqa: E402
|
||||
|
||||
# R-425 — THE SCOPE IS DISCOVERED, NOT LISTED. The gate used to scan a fixed three-entry FILES list,
|
||||
# correct when written, and narrower every time the feature grew a file: measured 2026-09-01, a
|
||||
# `NAS-mentés` in a new `backups_offbox_extra.html` passed. And since localisation the customer copy of
|
||||
# the listed template lives in the i18n bundle, which no entry named — so the gate had become largely
|
||||
# hollow, not only narrow. The scope is now, by pattern:
|
||||
# * every backup-surface template (`templates/**/backups*.html`, `recovery.html`), judged AS IT
|
||||
# RENDERS in Hungarian (bundle markers expanded), so copy that moved into hu.json is still seen;
|
||||
# * every off-site Go file (`internal/web/offbox*.go`, `internal/backup/offbox*.go`, not tests);
|
||||
# * every hu.json value whose KEY one of those Go files names (flash/note/err keys travel by key).
|
||||
# A new file matching the patterns is scanned the day it is added. Decoys: test_gate_decoys.py.
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_CTRL = os.path.dirname(_HERE)
|
||||
TEMPLATE_GLOBS = ["internal/web/templates/**/backups*.html", "internal/web/templates/**/recovery.html"]
|
||||
GO_GLOBS = ["internal/web/offbox*.go", "internal/backup/offbox*.go"]
|
||||
TEMPLATE_COMMENT = re.compile(r"\{\{/\*.*?\*/\}\}", re.S)
|
||||
KEY_LIT = re.compile(r'"([a-z][a-z0-9_]*(?:\.[a-z0-9_\-]+)+)"')
|
||||
|
||||
|
||||
def scoped_files():
|
||||
out = []
|
||||
for pats in (TEMPLATE_GLOBS, GO_GLOBS):
|
||||
for pat in pats:
|
||||
for f in glob.glob(os.path.join(_CTRL, pat), recursive=True):
|
||||
if not f.endswith("_test.go"):
|
||||
out.append(f)
|
||||
return sorted(set(out))
|
||||
|
||||
FILES = [
|
||||
os.path.join("internal", "web", "templates", "backups.html"),
|
||||
os.path.join("internal", "web", "offbox_handlers.go"),
|
||||
os.path.join("internal", "backup", "offbox.go"),
|
||||
]
|
||||
|
||||
BANNED = [
|
||||
"NAS-mentés",
|
||||
@@ -37,20 +62,39 @@ def is_comment(line):
|
||||
|
||||
|
||||
def main():
|
||||
files = scoped_files()
|
||||
if not files:
|
||||
print("OFFBOX RENAME GATE INCONCLUSIVE: no offbox file matched %s" % (TEMPLATE_GLOBS + GO_GLOBS))
|
||||
sys.exit(2)
|
||||
hu = json.load(io.open(os.path.join(_CTRL, "internal", "i18n", "locales", "hu.json"), encoding="utf-8"))
|
||||
sources = [] # (label, text)
|
||||
named = set()
|
||||
for path in files:
|
||||
rel = os.path.relpath(path, _CTRL)
|
||||
raw = io.open(path, encoding="utf-8").read()
|
||||
if path.endswith(".html"):
|
||||
raw = TEMPLATE_COMMENT.sub("", i18n_bundle.expand(raw, "hu"))
|
||||
else:
|
||||
named.update(k for k in KEY_LIT.findall(raw) if k in hu)
|
||||
sources.append((rel, raw))
|
||||
for key in sorted(named):
|
||||
if isinstance(hu[key], str):
|
||||
sources.append(("hu.json[%s]" % key, hu[key]))
|
||||
total = 0
|
||||
for path in FILES:
|
||||
for lineno, line in enumerate(io.open(path, encoding="utf-8"), 1):
|
||||
for label, text in sources:
|
||||
for lineno, line in enumerate(text.splitlines(), 1):
|
||||
if is_comment(line):
|
||||
continue
|
||||
for tok in BANNED:
|
||||
if tok in line:
|
||||
total += 1
|
||||
print("%s:%d [%s] %s" % (path, lineno, tok,
|
||||
print("%s:%d [%s] %s" % (label, lineno, tok,
|
||||
line.strip()[:100].encode("ascii", "backslashreplace").decode()))
|
||||
if total:
|
||||
print("OFFBOX RENAME GATE FAILED: %d customer-facing NAS-branding string(s) remain" % total)
|
||||
sys.exit(1)
|
||||
print("offbox rename gate OK — Tier-3 is 'Tavoli mentes' everywhere customer-facing")
|
||||
print("offbox rename gate OK — Tier-3 is 'Tavoli mentes' everywhere customer-facing "
|
||||
"(%d file(s) + %d bundle value(s) named by them)" % (len(files), len(named)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -53,6 +53,16 @@ GO_SOURCES = [
|
||||
# records what happens when the guard chases words instead of claims — it misses the next one.
|
||||
STEMS = ["visszaállíthat", "visszaszerezhet", "visszahozhat", "visszanyit"]
|
||||
|
||||
# R-564 — THE SPLIT VERB. Hungarian moves the particle after the verb when something is stressed:
|
||||
# „csak akkor ÁLLÍTHATÓK VISSZA", „csak a hiányzó fájlokat HOZOD VISSZA". The joined stems above never
|
||||
# see that form, so seven Hungarian sentences went unscanned until their English translations were
|
||||
# caught by EN_PATTERNS (slice 1 release B). The same claim, the same registration rule.
|
||||
SPLIT_PATTERNS = [
|
||||
r"állíth\w* vissza",
|
||||
r"(?:hoz|szerez|nyit)\w* vissza",
|
||||
]
|
||||
HU_RE = re.compile("|".join([re.escape(s) + r"[a-záéíóöőúüű]*" for s in STEMS] + SPLIT_PATTERNS))
|
||||
|
||||
# (template, substring that identifies the occurrence) -> why it is allowed.
|
||||
# The substring must be specific enough that a DIFFERENT claim in the same file does not match it.
|
||||
ALLOWLIST = {
|
||||
@@ -94,6 +104,28 @@ ALLOWLIST = {
|
||||
("recovery.html", "a mentéseid visszaszerezhetők, és a törlés elmarad;"):
|
||||
"the abandon CONFIRMATION screen, shown at the moment of the decision. True by construction "
|
||||
"there: the package the hub holds right now is the one about to be pinned. Left alone.",
|
||||
# R-564 — the split-verb occurrences, found the day SPLIT_PATTERNS learnt them. Each one's English
|
||||
# twin was registered in slice 1 release B (ALLOWLIST_EN below), with the same reason.
|
||||
("backups_escrow.html", "ezzel a kóddal állíthatók vissza"):
|
||||
"a PRECONDITION, not a promise: it says the remote backups need THIS code, on the page that "
|
||||
"creates it. It narrows what is possible; it claims nothing about the old store.",
|
||||
("backups_remote.html", "A távoli mentések csak akkor állíthatók vissza egy teljes meghibásodás után"):
|
||||
"a PRECONDITION: remote backups are restorable after a total failure ONLY if the recovery "
|
||||
"code exists. It is the reason to create the code, not a claim that a store is retrievable.",
|
||||
("backups_restore.html", "utána hozhatod vissza az adatait"):
|
||||
"the order of two actions on the restore page for an app that is not installed: reinstall "
|
||||
"first, then restore its data from the copy listed on that same row.",
|
||||
("backups_restore_wizard.html", "csak a hiányzó fájlokat hozod vissza"):
|
||||
"describes the CHOICE the wizard offers next (missing files only, or a full restore) for a "
|
||||
"verification copy that is already on the box.",
|
||||
("backups_restore_wizard.html", "Az alkalmazás beállításait és adatbázisát hozza vissza"):
|
||||
"describes what the verification restore DOES, into a separate folder, on the page where it "
|
||||
"is pressed. Nothing about a recovery code.",
|
||||
("backups_restore_wizard.html", "<strong>nem</strong> hozza vissza"):
|
||||
"a NEGATIVE: says the verification restore does NOT bring back the household's own files.",
|
||||
("recovery.html", "melyik alkalmazás mit hozzon vissza"):
|
||||
"points to the restore page, where the household picks what each app brings back from a "
|
||||
"store the box has just opened. A route, not a promise.",
|
||||
}
|
||||
|
||||
# ── ENGLISH (localisation slice 1, R-556) ─────────────────────────────────────────────────────────
|
||||
@@ -131,9 +163,9 @@ ALLOWLIST_EN = {
|
||||
"= backups_remote.html 'Hogy ezek még visszaszerezhetők-e': the QUESTION branch.",
|
||||
("recovery.html", "your backups can be retrieved, and the deletion is cancelled;"):
|
||||
"= recovery.html 'a mentéseid visszaszerezhetők, és a törlés elmarad;': the confirmation screen.",
|
||||
# slice 1 release B — English claims whose HUNGARIAN escapes the Hungarian stems (split verbs:
|
||||
# „állíthatók vissza", „hozod vissza"). The English gate saw them first; the Hungarian blind spot
|
||||
# is a register row (R-564). Each is registered on its own merits:
|
||||
# slice 1 release B — English claims whose HUNGARIAN escaped the Hungarian stems (split verbs:
|
||||
# „állíthatók vissza", „hozod vissza"). The English gate saw them first; since R-564 the Hungarian
|
||||
# scan sees them too (SPLIT_PATTERNS) and registers each one above. Each is registered on its own merits:
|
||||
("backups_remote.html", "Remote backups can be restored after a complete failure only if you create the recovery code."):
|
||||
"a PRECONDITION, not a promise: restorable only IF the code exists — true by the escrow design (hu: "
|
||||
"'csak akkor állíthatók vissza … ha létrehozza').",
|
||||
@@ -184,8 +216,8 @@ def scan():
|
||||
# in 10-localisation.md; the English bundle covers three pages today.
|
||||
raw = open(path, encoding="utf-8").read()
|
||||
text = stripper.sub("", i18n_bundle.expand(raw, "hu") if path.endswith(".html") else raw)
|
||||
for stem in STEMS:
|
||||
for m in re.finditer(re.escape(stem) + r"[a-záéíóöőúüű]*", text):
|
||||
if True:
|
||||
for m in HU_RE.finditer(text):
|
||||
line = text[: m.start()].count("\n") + 1
|
||||
# SPAN-based, not window-based. The promise and the cautious disclaimer sit within a
|
||||
# hundred characters of each other in the same paragraph, so a proximity window matches
|
||||
|
||||
@@ -47,6 +47,9 @@ COVERS = {
|
||||
"i18n": "an undefined marker key, a pleading English value, a shrinking/growing gap (v0.247.0)",
|
||||
"go-parity": "a Go-side key REWORDED, a key citing text no base literal has, and a converted "
|
||||
"key left out of the map (v0.252.0, R-557)",
|
||||
"gofmt": "R-454: a planted unformatted .go file in internal/ is convicted; the clean tree passes",
|
||||
"offbox-rename": "R-425: NAS branding in a NEW backups*.html, and in a bundle value an offbox Go file "
|
||||
"names; control: the same token in the network-storage feature's copy is accepted",
|
||||
}
|
||||
|
||||
fails = []
|
||||
@@ -172,9 +175,49 @@ swapped("retrieval-promise/en", "retrieval_promise_gate.py", EN_JSON,
|
||||
swapped("retrieval-promise/en-ok", "retrieval_promise_gate.py", EN_JSON,
|
||||
_one('"launcher.link_masolasa": "Copy link"', '"launcher.link_masolasa": "Your old backups are listed on the restore page."'),
|
||||
expect="accept")
|
||||
# R-564: the Hungarian SPLIT verb („állíthatók vissza") is the same claim as the joined stem; a planted
|
||||
# split-verb promise must convict, and a plain „Vissza" (a back link, no claim) must not.
|
||||
swapped("retrieval-promise/split-verb", "retrieval_promise_gate.py", HU_JSON,
|
||||
_one('"launcher.link_masolasa": "Link másolása"', '"launcher.link_masolasa": "A régi mentéseid a kóddal bármikor állíthatók vissza."'))
|
||||
swapped("retrieval-promise/split-ok", "retrieval_promise_gate.py", HU_JSON,
|
||||
_one('"launcher.link_masolasa": "Link másolása"', '"launcher.link_masolasa": "Vissza a listához"'),
|
||||
expect="accept")
|
||||
swapped("secret-markup/bundle", "secret_in_markup_gate.py", EN_JSON,
|
||||
_one('"launcher.link_masolasa": "Copy link"', '"launcher.link_masolasa": "Copy {{.RetrievalPassword}}"'))
|
||||
|
||||
# --- offbox-rename (R-425): the scope is discovered by pattern, and bundle copy is judged. ---------
|
||||
ran += 1
|
||||
_extra = os.path.join(TPL, "backups_offbox_extra.html")
|
||||
io.open(_extra, "w", encoding="utf-8").write(u"<p>A NAS-mentés beállítása</p>\n")
|
||||
try:
|
||||
_rc, _out = gate("offbox_rename_gate.py")
|
||||
finally:
|
||||
os.remove(_extra)
|
||||
if _rc == 0:
|
||||
fails.append("offbox-rename/new-file: NAS branding in a NEW backups*.html PASSED — the scope is a "
|
||||
"fixed list again (R-425)\n%s" % _out[-400:])
|
||||
else:
|
||||
print(" ok %-20s decoy rejected" % "offbox-rename/new-file")
|
||||
swapped("offbox-rename/bundle", "offbox_rename_gate.py", HU_JSON,
|
||||
_one('"flash.offbox.run_started": "', '"flash.offbox.run_started": "Mentés a NAS-ra: '))
|
||||
swapped("offbox-rename/other-feature-ok", "offbox_rename_gate.py", HU_JSON,
|
||||
_one('"storage_network.mit_kell_beallitani_a_nas": "Mit kell beállítani a NAS-on?"',
|
||||
'"storage_network.mit_kell_beallitani_a_nas": "Mit kell beállítani a NAS-on? Ez a NAS-ra vonatkozik."'),
|
||||
expect="accept")
|
||||
|
||||
# --- gofmt (R-454): an unformatted Go file anywhere under internal/ is convicted. ----------------
|
||||
ran += 1
|
||||
_gf = os.path.join(CTRL, "internal", "zz_gofmt_decoy_tmp.go")
|
||||
io.open(_gf, "w", encoding="utf-8").write(u"package internal\nfunc decoy( ) { }\n")
|
||||
try:
|
||||
_rc, _out = gate("gofmt_gate.py")
|
||||
finally:
|
||||
os.remove(_gf)
|
||||
if _rc != 1 or "zz_gofmt_decoy_tmp.go" not in _out:
|
||||
fails.append("gofmt: an unformatted planted file was not convicted (rc=%d)\n%s" % (_rc, _out[-400:]))
|
||||
else:
|
||||
print(" ok %-20s decoy rejected" % "gofmt")
|
||||
|
||||
# --- go-parity (v0.252.0, R-557): a Go-side message key may only carry base-commit text. ---
|
||||
# --- Three shapes, because the gate makes three different claims. ---
|
||||
GO_KEYS = os.path.join(HERE, "i18n_go_keys.json")
|
||||
|
||||
Reference in New Issue
Block a user