From dae54f014405dd9692c02f957ab4268cad1c8f55 Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Mon, 22 Jun 2026 04:11:04 +0000 Subject: [PATCH] fix(scripts/ops): PRUNE_ZONE_DOMAIN covers staging.moleculesai.app by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #3140 ADDENDUM / Researcher RC 13130: the observed leaked e2e-smoke-* / e2e-tmpl-* records live under staging.moleculesai.app, not the apex moleculesai.app zone. Change the default PRUNE_ZONE_DOMAIN to staging.moleculesai.app and allow a comma-separated list of zone domains so multi-zone sweeps are possible. Also add regression tests proving records under the configured zone domain ARE matched while apex / other-subdomain / near-miss names are kept unless explicitly included. Local: bash tests/ops/test_prune_cf_e2e_dns_fail_closed.sh -> 18/18 pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- scripts/ops/prune_cf_e2e_dns.sh | 25 +++++++++++----- .../ops/test_prune_cf_e2e_dns_fail_closed.sh | 29 ++++++++++++++----- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/scripts/ops/prune_cf_e2e_dns.sh b/scripts/ops/prune_cf_e2e_dns.sh index 309387c64..36f2a83fa 100755 --- a/scripts/ops/prune_cf_e2e_dns.sh +++ b/scripts/ops/prune_cf_e2e_dns.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # prune_cf_e2e_dns.sh — targeted, fail-closed cleanup of disposable E2E DNS -# records that accumulate under the moleculesai.app zone and exhaust the -# Cloudflare DNS record quota (code 81045). +# records that accumulate under the moleculesai.app zone (typically the +# staging.moleculesai.app subdomain) and exhaust the Cloudflare DNS record +# quota (code 81045). # # Why this exists: staging E2E harnesses create DNS records for slugs like # e2e-smoke--- and e2e-tmpl- (see @@ -16,6 +17,8 @@ # - Records whose full name matches # e2e-smoke-*. # e2e-tmpl-*. +# - Multiple zone domains may be supplied as a comma-separated list +# (e.g. "moleculesai.app,staging.moleculesai.app"). # - Records older than --min-age-hours / PRUNE_MIN_AGE_HOURS (default 24) # so in-flight runs are not touched. # - Anything else is kept untouched. @@ -33,7 +36,8 @@ # PRUNE_MIN_AGE_HOURS= — default minimum age in hours (default: 24). # MAX_DELETE_PCT= — refuse to delete more than this percentage of # matched ephemeral records (default: 50). -# PRUNE_ZONE_DOMAIN= — zone domain to anchor matches (default: moleculesai.app). +# PRUNE_ZONE_DOMAIN= — comma-separated zone domain(s) to anchor +# matches (default: staging.moleculesai.app). # # Exit codes: # 0 — dry-run completed or prune executed successfully @@ -45,7 +49,10 @@ set -euo pipefail DRY_RUN=1 MIN_AGE_HOURS="${PRUNE_MIN_AGE_HOURS:-24}" MAX_DELETE_PCT="${MAX_DELETE_PCT:-50}" -ZONE_DOMAIN="${PRUNE_ZONE_DOMAIN:-moleculesai.app}" +ZONE_DOMAIN="${PRUNE_ZONE_DOMAIN:-}" +if [ -z "$ZONE_DOMAIN" ]; then + ZONE_DOMAIN="staging.moleculesai.app" +fi while [ $# -gt 0 ]; do case "$1" in @@ -246,15 +253,19 @@ from datetime import datetime, timezone, timedelta min_age = timedelta(hours=int(os.environ["MIN_AGE_HOURS"])) zone_domain = os.environ["ZONE_DOMAIN"] +zone_domains = [d.strip() for d in zone_domain.split(",") if d.strip()] now = datetime.now(timezone.utc) -# Conservative: only the two known disposable E2E prefixes, anchored to the -# configured zone domain so similarly-named records in other zones never match. +# Conservative: only the two known disposable E2E prefixes, anchored to one +# of the configured zone domains so similarly-named records in other zones +# never match. Multiple zone domains may be supplied as a comma-separated +# list (e.g. "moleculesai.app,staging.moleculesai.app"). # The prefix MUST be followed immediately by a hyphen and then at least one # suffix character, so names like e2e-smokeprod, e2e-smoketest-keep, or # prod-e2e-smoke-x are NEVER matched. +zone_part = r"(?:" + r"|".join(re.escape(d) for d in zone_domains) + r")" EPHEMERAL_RE = re.compile( - r"^(e2e-smoke-[a-zA-Z0-9_-]+|e2e-tmpl-[a-zA-Z0-9_-]+)\." + re.escape(zone_domain) + r"$" + r"^(e2e-smoke-[a-zA-Z0-9_-]+|e2e-tmpl-[a-zA-Z0-9_-]+)\." + zone_part + r"$" ) def parse_iso(s): diff --git a/tests/ops/test_prune_cf_e2e_dns_fail_closed.sh b/tests/ops/test_prune_cf_e2e_dns_fail_closed.sh index 8d7d9b2e6..6eb284361 100755 --- a/tests/ops/test_prune_cf_e2e_dns_fail_closed.sh +++ b/tests/ops/test_prune_cf_e2e_dns_fail_closed.sh @@ -17,7 +17,7 @@ PASS=0 FAIL=0 run_case() { - local name="$1" list_exit="$2" list_body="$3" expect_delete_sentinel="$4" zone_domain="${5:-moleculesai.app}" + local name="$1" list_exit="$2" list_body="$3" expect_delete_sentinel="$4" zone_domain="${5:-}" local tmp tmp=$(mktemp -d -t cf-e2e-prune-fail-closed-XXXXXX) local delete_sentinel="$tmp/delete_reached" @@ -129,9 +129,10 @@ run_case "CF DNS list returns malformed JSON" 0 'this is not json' run_case "CF DNS list returns non-array result" 0 '{"success":true,"result":{"id":"rec1"}}' false-abort # Helper to build a DNS list result with one record, given created_on ISO string -# and optional zone domain (default: moleculesai.app). +# and optional zone domain (default: staging.moleculesai.app, the observed +# domain for leaked e2e-smoke/e2e-tmpl records). make_list() { - local created_on="$1" zone_domain="${2:-moleculesai.app}" + local created_on="$1" zone_domain="${2:-staging.moleculesai.app}" cat <