provenance:programming:crawler:webxray:random_sample
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| provenance:programming:crawler:webxray:random_sample [2026/09/11 16:12] – Third-sitting fixes from the figures reviewer: absent-set invariant asserted in the kappa estimator, deterministic pe, guard extended to figures that live only in script text output (6 new mutations, 18 total). Authored by Claude karel.kubicek.claude | provenance:programming:crawler:webxray:random_sample [2026/09/17 07:24] (current) – Markup rendering sweep: wrap escapes, CLI flag typography, and heading quotes. Authored by Claude. karel.kubicek.claude | ||
|---|---|---|---|
| Line 7: | Line 7: | ||
| **inter-rater re-adjudication of 2026-09-11** (sections AA–AK), which measured | **inter-rater re-adjudication of 2026-09-11** (sections AA–AK), which measured | ||
| how far a second model reading the same brief reaches the same verdicts. | how far a second model reading the same brief reaches the same verdicts. | ||
| + | |||
| + | The **second pass over the residue**, run later the same day — which | ||
| + | re-adjudicated the 40 domains this sample could not settle, moved 28 of them | ||
| + | into the rates, and changed the content page's headline table and its Fisher | ||
| + | table — has its own appendix, for exactly the reason given below: | ||
| + | [[provenance: | ||
| + | 343 kB, most of it one probe log, and adding them here would have made this page | ||
| + | 628 kB. That page computes both figures when it is generated, from the same file | ||
| + | lists both manifests use. | ||
| Read [[provenance: | Read [[provenance: | ||
| Line 17: | Line 26: | ||
| AF–AK their outputs. | AF–AK their outputs. | ||
| - | **Why this is a separate page.** These blocks are 282 kB, and the parent | + | **Why this is a separate page.** These blocks are 290 kB, and the parent |
| provenance page is already large without them. Raw size alone would not decide | provenance page is already large without them. Raw size alone would not decide | ||
| it — '' | it — '' | ||
| Line 48: | Line 57: | ||
| | C | '' | | C | '' | ||
| | D | '' | | D | '' | ||
| - | | E | '' | + | | E | '' |
| | F | '' | | F | '' | ||
| - | | G | '' | + | | G | '' |
| | H | '' | | H | '' | ||
| | I | '' | | I | '' | ||
| Line 61: | Line 70: | ||
| | P | '' | | P | '' | ||
| | Q | '' | | Q | '' | ||
| - | | R | '' | + | | R | '' |
| | S | '' | | S | '' | ||
| | T | '' | | T | '' | ||
| Line 603: | Line 612: | ||
| s = re.sub(r" | s = re.sub(r" | ||
| return re.sub(r" | return re.sub(r" | ||
| + | |||
| + | |||
| + | def decode(body): | ||
| + | """ | ||
| + | |||
| + | Decoding as UTF-8 with ``errors=" | ||
| + | windows-1251 or shift_jis page into U+FFFD, so a Cyrillic or Japanese quote | ||
| + | can never match and the row is reported NOTFOUND -- a fabrication verdict on | ||
| + | a correct citation. The normaliser was already fixed once for this class of | ||
| + | bug (it used to delete non-Latin letters); this is the same bug one layer | ||
| + | earlier, found on 2026-09-11 when ``help.i.ua/ | ||
| + | page declares ``charset=windows-1251`` and every Ukrainian word in it | ||
| + | decoded to replacement characters. | ||
| + | |||
| + | Sniffed from the bytes rather than from the HTTP header, because the header | ||
| + | is not cached -- the cache holds the body alone. If nothing is declared, or | ||
| + | the declared codec is unknown, the old behaviour is the fallback. | ||
| + | """ | ||
| + | m = re.search(rb""" | ||
| + | if m: | ||
| + | enc = m.group(1).decode(" | ||
| + | if enc.lower().replace(" | ||
| + | try: | ||
| + | return body.decode(enc) | ||
| + | except (LookupError, | ||
| + | pass | ||
| + | return body.decode(" | ||
| Line 623: | Line 659: | ||
| except Exception as e: | except Exception as e: | ||
| return None, f"tls: {e}" | return None, f"tls: {e}" | ||
| + | os.makedirs(cache, | ||
| + | open(path, " | ||
| + | return out, None | ||
| + | if url.startswith(" | ||
| + | # The 2026-09-11 second pass over the residue cites registry and | ||
| + | # registrar WHOIS records, which are not reachable over HTTP: the | ||
| + | # protocol is a port-43 socket. Without this branch every such row | ||
| + | # FETCHFAILs, which reads as an unverifiable citation when in fact the | ||
| + | # checker had no client. The URL is `whois://< | ||
| + | # query is re-issued against the *named server*, not re-resolved | ||
| + | # through IANA, so the row is checked against the record it cites. | ||
| + | rest = url[len(" | ||
| + | server, _, dom = rest.partition("/" | ||
| + | if not dom: | ||
| + | return None, " | ||
| + | sys.path.insert(0, | ||
| + | import time | ||
| + | import whois43 | ||
| + | out = b"" | ||
| + | # Two attempts, 20 s apart. One retry is enough: the observed limit is a | ||
| + | # burst limit, and both stubs in the first run answered correctly 25 s | ||
| + | # later. Retrying forever would turn a registrar' | ||
| + | err = None | ||
| + | for attempt in range(2): | ||
| + | if attempt: | ||
| + | time.sleep(20) | ||
| + | try: | ||
| + | out = whois43.ask(server, | ||
| + | except Exception as e: | ||
| + | # A raised exception is a transport failure too -- a reset or a | ||
| + | # timeout is exactly what a rate limiter does -- so it must take | ||
| + | # the retry as well. It did not until 2026-09-11, when a review | ||
| + | # pass read the comment above ("two attempts, 20 s apart" | ||
| + | # then read the code, which returned on the first exception. | ||
| + | err, out = e, b"" | ||
| + | continue | ||
| + | err = None | ||
| + | if len(out) >= 400 and dom.encode().lower() in out.lower(): | ||
| + | break | ||
| + | if err is not None: | ||
| + | return None, f" | ||
| + | # Registrar WHOIS servers rate-limit. MarkMonitor answers the fourth | ||
| + | # rapid query with a stub that has no registrant block, and caching that | ||
| + | # stub turns a correct citation into a permanent NOTFOUND: it happened | ||
| + | # to ``sa-as.com`` and ``blogblog.com`` in this script' | ||
| + | # 2026-09-11, and both verified on a retry 25 seconds later. A short or | ||
| + | # domain-less answer is a transport failure, not evidence, so it is | ||
| + | # neither returned nor cached. | ||
| + | if len(out) < 400 or dom.encode().lower() not in out.lower(): | ||
| + | return None, (f" | ||
| + | f" | ||
| os.makedirs(cache, | os.makedirs(cache, | ||
| open(path, " | open(path, " | ||
| Line 674: | Line 761: | ||
| " | " | ||
| continue | continue | ||
| - | hay = norm(body.decode(" | + | hay = norm(decode(body)) |
| nq = norm(quote) | nq = norm(quote) | ||
| # A quote the adjudicator elided ("A ... B") is checked fragment by | # A quote the adjudicator elided ("A ... B") is checked fragment by | ||
| Line 686: | Line 773: | ||
| # strip for every row would let a quote match an HTML comment or an | # strip for every row would let a quote match an HTML comment or an | ||
| # attribute it was never on. | # attribute it was never on. | ||
| - | raw_hay = norm(body.decode(" | + | raw_hay = norm(decode(body), strip_tags=False) |
| if not nq: | if not nq: | ||
| status = " | status = " | ||
| Line 785: | Line 872: | ||
| </ | </ | ||
| - | ===== G. scripts/ | + | ===== G. scripts/ |
| Every row a machine flagged and a human then re-checked, with the action taken and why: '' | Every row a machine flagged and a human then re-checked, with the action taken and why: '' | ||
| Line 803: | Line 890: | ||
| quotation marks" failure, and it happened in 4 of 175 rows despite an | quotation marks" failure, and it happened in 4 of 175 rows despite an | ||
| instruction that said verbatim -- which is the argument for verifying every | instruction that said verbatim -- which is the argument for verifying every | ||
| - | citation by machine rather than trusting the adjudicator. | + | citation by machine rather than trusting the adjudicator. A fifth requote, |
| + | ``compass-fit.jp``, | ||
| + | dropped character. It is counted with them because the remedy is the same, | ||
| + | not because it is the same defect. It was | ||
| + | found on 2026-09-11 and applied on 2026-09-17, by re-running a *fixed* | ||
| + | checker over rows the broken one had passed: ``norm()`` used to delete every non-Latin character, | ||
| + | so ``compass-fit.jp``' | ||
| + | letters ``COMPASS-FIT`` it happens to contain. A checker that cannot see a | ||
| + | script cannot police it, and every row it passed in that script is | ||
| + | unverified until it is re-run. | ||
| * ``resource`` -- the cited URL was the wrong page (a 404 template, a | * ``resource`` -- the cited URL was the wrong page (a 404 template, a | ||
| JS-only route, a blocked host). A different primary source for the same | JS-only route, a blocked host). A different primary source for the same | ||
| Line 873: | Line 969: | ||
| " | " | ||
| "error needs a source naming the real owner and there is none." | "error needs a source naming the real owner and there is none." | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | "found 2026-09-11, applied 2026-09-17. The norm() character-class fix " | ||
| + | "of 2026-09-11 was re-run that day over all 175 rows of the first " | ||
| + | " | ||
| + | "Latin letters COMPASS-FIT its Japanese quote happens to contain. The " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | "the operating subsidiary together, which is what owner_today = " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| } | } | ||
| Line 925: | Line 1042: | ||
| </ | </ | ||
| - | ===== H. scripts/ | + | ===== H. scripts/ |
| The methodological correction made during the run, kept rather than smoothed away. Each of the 26 re-scores carries the entity string, the adjudicated owner and the reason. | The methodological correction made during the run, kept rather than smoothed away. Each of the 26 re-scores carries the entity string, the adjudicated owner and the reason. | ||
| Line 2156: | Line 2273: | ||
| ===== R. Unedited output: scripts/ | ===== R. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| - | 10 corrections applied to 175 rows, after machine verification of every cited source: demote=1, requote=4, resource=5 | + | 11 corrections applied to 175 rows, after machine verification of every cited source: demote=1, requote=5, resource=5 |
| twiago.com | twiago.com | ||
| Line 2210: | Line 2327: | ||
| was quote : Condé Nast Entertainment | was quote : Condé Nast Entertainment | ||
| now source: None | now source: None | ||
| + | |||
| + | compass-fit.jp | ||
| + | was source: https:// | ||
| + | was quote : 台湾国内でのネイティブ型広告配信サービス「COMPASS-FIT」の提供を開始致しました。 | ||
| + | now source: https:// | ||
| wrote out/ | wrote out/ | ||
| Line 2216: | Line 2338: | ||
| ===== S. Unedited output: scripts/ | ===== S. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 2317: | Line 2439: | ||
| ===== V. Unedited output: scripts/ | ===== V. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5365: | Line 5487: | ||
| ===== AF. Unedited output: scripts/ | ===== AF. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5389: | Line 5511: | ||
| ===== AG. Unedited output: scripts/ | ===== AG. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5401: | Line 5523: | ||
| ===== AH. Unedited output: scripts/ | ===== AH. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5441: | Line 5563: | ||
| ===== AI. Unedited output: scripts/ | ===== AI. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5457: | Line 5579: | ||
| ===== AJ. Unedited output: scripts/ | ===== AJ. Unedited output: scripts/ | ||
| - | Run as '' | + | Run as '' |
| < | < | ||
| Line 5683: | Line 5805: | ||
| * [[provenance: | * [[provenance: | ||
| * [[programming: | * [[programming: | ||
| + | * [[provenance: | ||
| * [[literature: | * [[literature: | ||
| + | |||
| + | ===== Markup sweep, 2026-09-17 ===== | ||
| + | |||
| + | Mechanical rendering repair only: a fresh live raw/XHTML export of 188 pages was checked with '' | ||
provenance/programming/crawler/webxray/random_sample.1789143147.txt.gz · Last modified: by karel.kubicek.claude
