Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
# datacentre address, listings and product pages answered HTTP 200 to a plain
# `curl`, to `python-requests` and to a request with no User-Agent header at
# all, with no challenge of any kind. A GitHub runner is a datacentre address
# too, so this workflow re-measures that claim every morning.
# too, so this workflow re-measures that claim every Monday.
#
# **A canary that CAN pass without a credential must never be gated on one.**
# If Kosé ever puts its catalogue behind a key or a bot manager, this badge
# goes red the next morning and the README's claim is retested without anyone
# remembering to.
#
# The last job exercises the PAID path (the Scraping Browser API over CDP),
# which cannot run without a secret, and bills a session, so it runs on the
# weekly (Monday) schedule and on a manual dispatch only. It does not pass by skipping: with no
# which cannot run without a secret. It does not pass by skipping: with no
# secret it FAILS with an ::error:: naming the secret, because a green check
# that tested nothing reads exactly like one that tested something.
#
Expand All @@ -32,9 +31,6 @@ on:
schedule:
# 05:40 UTC. Not on the hour: every scheduled workflow on GitHub fires at
# :00 and the queue there is long.
- cron: "40 5 * * *"
# Mondays only: the paid job (scraping_browser) runs on this
# schedule (each run bills); the free jobs keep the daily one above.
- cron: "40 5 * * 1"
workflow_dispatch:

Expand Down Expand Up @@ -381,8 +377,6 @@ jobs:

scraping_browser:
name: Scraping Browser API (needs the KOSE_CDP_ENDPOINT secret)
# Paid path: weekly schedule or a manual dispatch only.
if: github.event_name != 'schedule' || github.event.schedule == '40 5 * * 1'
runs-on: ubuntu-latest
timeout-minutes: 20
env:
Expand Down
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ existing user would notice, the release notes lead with it.

### Changed

- CI only: the canary's paid `scraping_browser` job now runs weekly (Mondays
05:40 UTC) and on a manual dispatch; the free `listing`, `http_vs_browser` and
`product` jobs still run daily.
- CI only: the whole canary, free and paid jobs alike, now runs weekly (Mondays 05:40 UTC) and on a manual dispatch; the daily schedule is removed.

## [0.3.0] — 2026-10-15

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ So until this repo had a browserless engine, every long title came back
short — **10 of 72 rows** on one live 3-page run — and nothing could see it,
because there was nothing to disagree with. The parser now recovers the full
name from the thumbnail's `alt`, which the rewrite does not touch and which
is present on 171 of 171 measured tiles. The canary runs both engines daily
is present on 171 of 171 measured tiles. The canary runs both engines weekly (Mondays)
and fails if any field differs.

**The brand in a URL selects nothing.** `/site/xyz/c/c15/` returns
Expand Down
4 changes: 2 additions & 2 deletions smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2156,14 +2156,14 @@ def check_captcha_capability_claims_match_the_code():
# rots the moment the site switches a bot manager on.
#
# So the claim has to be PAIRED with the thing that would retest it — the
# daily canary — rather than left as a sentence nobody re-measures.
# scheduled canary — rather than left as a sentence nobody re-measures.
claims_no_key = ("no, and it would be dishonest" in low
or "do i need a 2captcha account" in low)
if claims_no_key:
check("README pairs 'no key needed' with the canary that retests it",
"canary" in low,
"a claim that the site is ungated goes stale silently; the "
"daily canary is what turns it back into a measurement")
"scheduled canary is what turns it back into a measurement")
check("...and dates the measurement it rests on",
re.search(r"20\d\d-\d\d-\d\d", readme) is not None,
"a number describing a living thing needs its moment")
Expand Down
Loading