Skip to content

Grape pill labels, ES pliego sources, newest model defaults, deploy replication wait - #30

Merged
bdevloed merged 9 commits into
mainfrom
fix/grape-labels-es-sources-deploy-replication
Oct 17, 2026
Merged

bdevloed merged 9 commits into
mainfrom
fix/grape-labels-es-sources-deploy-replication

Conversation

@bdevloed

Copy link
Copy Markdown
Contributor

Eight commits, each one change:

  • fix(es) — Pliego links are back on 183 of 185 Spanish cards (the stage-01 manifest had held 2 entries since May). MAPA / regional PDF pliegos are labelled as PDFs, not EUR-Lex single documents. Five pliegos now route their link section. 19 records no longer give "España" as their region.
  • fix(map) — Grape pills read the in-memory record, so national-spec augmentations and IT sottozone are seen. 15,872 pills on 841 cards had shown another record's spelling. Names printed in capitals are folded to the corpus's mixed-case spelling, extraction debris is stripped, and the Latin bracket prefers the record's own transliteration.
  • fix(gr) — "οίνος ερυθρωπός" reads as rosé (+69 GR records).
  • feat(analytics) — MCP Tool / WebMCP Tool events carry the slugs read. Search text is still never sent.
  • feat(llm) — Stage defaults move to Sonnet 5.5 / Opus 5.5, with the back-check on Opus. _lib/model_check.py stops a run whose default has a newer model of its family. "Thinking off" is spelled per model.
  • feat(terroir) — The back-check and translation rules catch NL de/het and gender-agreement errors (_lib/nl_articles.py).
  • fix(deploy) — The deploy waits for the storage replicas to serve the upload before purging, then checks a sample through the CDN. Stale files exit 3.
  • docs(curator) — Visitor-flag triage, 2026-10-05 → 2026-10-10.

Tests

  • pytest tests/ — 1,179 passed
  • npm test in mcp/ — 17 passed
  • ruff check scripts/ tests/ — clean

🤖 Generated with Claude Code

bdevloed and others added 9 commits October 11, 2026 16:50
…link sections, place 19 regions

A visitor flag on Norte de Almería (2026-10-05) exposed four ES defects:

- 183 of 185 ES cards had no pliego link. The stage-01 manifest had held
  2 entries since 2026-05-10 (--refresh reset it before a scoped run, and
  cached pages were never written back). Stage 01 now keeps the manifest
  on --refresh and rebuilds a cached page's missing entry offline
  (reconstruct_entry), checking each EUR-Lex page names the same OJ C
  publication.
- A MAPA / regional PDF pliego was labelled "EUR-Lex single document".
  _sources_for now puts it in national_pliego_url; stage 03 writes
  "Pliego de condiciones (PDF)". 63 records.
- Five pliegos never routed their link section ("VINCULACIÓN CON EL
  MEDIO GEOGRÁFICO", a page-number-only parent, lost parent headings).
- 19 single-CCAA records read "España": derive_ccaa reads the longest
  known name, counts a bracketed province, lets the area text decide
  first; the residue is pinned in CCAA_OVERRIDES with its evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A grapes flag on Kos (2026-10-10): the roster was right, the labels were
not ("Αθήρι Β", "Cabernet- Sauvignon"). emit_html read grapes.details
from the on-disk record, but a national-spec augmentation (IT MASAF,
GR ΥΠΑΑΤ, BG IAVV, …) or a synthesized IT sottozona exists only in
memory, so 15,872 pills on 841 cards fell back to the corpus-wide
spelling — often another country's (HU "Kékfrankos" read "Frankovka").

- main() snapshots each record's details where it derives its grapes
  (_GRAPE_DETAILS_BY_SLUG); the panel phase reads the snapshot.
- _lib/grape_labels.py: a name printed in capitals takes the corpus's
  mixed-case spelling of it, else its lower case; a Greek one keeps its
  capitals (lower-casing would drop the tonos). clean_name strips the
  extraction debris (private-use glyphs, page headers, trailing
  conjunctions from a closed list, list punctuation).
- The pill bracket prefers the record's own grape_names_latin over the
  corpus-wide name_latin (app.js renderAocCard, content_block _grape_pill).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ΥΠΑΑΤ specs name the rosé type by its legal term ("Γ. ΟΙΝΟΣ
ΕΡΥΘΡΩΠΟΣ", "Ο ερυθρωπός ξηρός οίνος"); the style table knew only
"ροζέ". The new STYLE_MARKERS entry matches the masculine ερυθρωπός /
ερυθρωποί within a few words of οίνος / οίνοι, never the feminine hue
("ερυθρωπές αποχρώσεις") nor the CY alcohol rule ("για λευκούς και
ερυθρωπούς οίνους"). 69 GR records gain rosé (14 retsinas among them);
no style is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`MCP Tool` now carries `slug` (get_appellation) or `slugs` + `count`
(show_on_map: known slugs in call order, cut at a slug boundary to
Plausible's 2,000-character limit); `WebMCP Tool` carries `slug` for
get_appellation / show_appellation. Unknown slugs are left out and a
search's query text is still never sent. The server resolves the
locale context before reporting the call (callProps), so an
unavailable context still reports the tool. docs/analytics.md lists the
props and the dashboard's property allow-list step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tale default

STAGE_DEFAULTS moves to Sonnet 5.5 (02d, 02e, 02c) and Opus 5.5 (gate,
audit, back-check). The back-check moves to Opus: on the bullets a
corpus-wide Sonnet 5.5 back-check made worse, Opus left 22 of 30 alone
and fixed the French agreement errors Sonnet missed; its MAX_TOKENS goes
to 16,000 because Opus always thinks.

- providers.effective_thinking spells "thinking off" per model:
  "disabled" (Sonnet 5, Opus 5), "between_tools" (Sonnet 5.5, which
  answers "disabled" with a 400), no thinking field plus effort "low" on
  the models that always think (Opus 5.5, Fable). effective_effort pins
  Opus 5.5 to effort "high", the level the gate was calibrated on.
- _lib/model_check.py: before any job, a stage default is checked
  against the account's Models API list (cached a day); a newer model
  of its family stops the run with what to bump — never a silent switch.
  An explicit --model is not checked; OWM_SKIP_MODEL_CHECK=1 turns it
  off (set by tests/conftest.py).
- Batch prices for Opus 5.5 / Sonnet 5.5; docstrings point at
  STAGE_DEFAULTS instead of naming retired models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A translation copies the source noun's gender onto the target noun: FR
"le vignoble" came out as NL "Het wijngaard" (42 bullets in 36 records
on 2026-10-09), FR "un arôme" as ES "una aroma".

- _lib/nl_articles.py lists NL de/het mismatches; the back-check feeds
  the model its hits as a DETECTOR line, and
  detect_untranslated_terroir_facts.py reports them as `article:`.
- The back-check prompt flags agreement errors (fix only the words that
  disagree); a fix may now be up to 115 % of the bullet it replaces,
  360 characters at least (an article fix to a 499-character bullet had
  been refused as too long).
- translation_rules adds a target-language agreement rule with examples
  for nl / fr / es (none for English); the NL glossary carries the
  articles and "climat" ≠ "klimaat".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On 2026-10-11 the origin shield pulled from the UK storage replicas,
which served the previous copy of each file for ~40 minutes after the
upload; the purge at the end of the deploy let the shield re-cache stale
copies of stable-URL files (panel JSON, HTML) for the 30-day max-age —
the Kos panel data among them. Hashed bundles are new paths and were
never affected.

deploy.py now probes up to eight just-uploaded stable-URL files through
the CDN (purge the URL, fetch it, compare sha256) until they match or
--replication-timeout passes (default 90 min), purges the zone, then
checks a random --verify-sample (default 60) and settles any straggler
the same way. Files still stale are named and the deploy exits 3 after
IndexNow and the config steps. IndexNow runs after the checks, so a
crawler is never sent to a stale copy. --no-replication-wait keeps the
old behaviour. Runbook in docs/deploy.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Norte de Almería (ES sources, fixed), Colli dell'Etruria Centrale (DOC is
right), Corton-Charlemagne and Irouléguy (no defect), Kos (grape labels
and Greek rosé, fixed). Open: a fresh GR 02f run drifts the grapes of
14 sidecars (για → giro-negre, ρετσίνα → ritino); Pafos' Moschato Samou
folds to muscat-ottonel; GR semi-dry / semi-sweet not mapped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, About dialog sections

Portugal: area texts are read clause by clause and drawn at freguesia
precision from CAOP 2025 (scripts/_lib/pt/area_units.py, freguesias.py,
freguesia_overrides.json); Vinho Verde's nine sub-regiões come from
Portaria n.º 668/2010 Anexo I as republished by Portaria n.º 152/2015
(subregiao_areas.{py,json}, fetched sha-pinned by pt/00); the card cites
the act (geom_src_national_act, src_area_act) and lists units drawn in
part (geom_units_partial). The CAOP RAA zip's second gpkg (Flores, Corvo)
is extracted; Madeira drops the offshore Desertas / Selvagens.

Switzerland: Basel-Landschaft's Anhang 1 roster is read as a table and
applied by reference to Basel-Stadt and Solothurn (ROSTER_BY_REFERENCE,
cantonal_roster_* sources); nine cantonal AOCs are no longer drawn as
their capital town (CANTON_CAPITAL); Heida / Païen fold to savagnin.

Map UI: the About dialog is restructured into titled sections with a
source list; the landing request (/<lang>/<slug>, ?aoc=, ?aocs=) is read
once and turns on the gates that would hide the landed record for that
page view only.

Also: geometry outlier / overlap overrides and empty-grapes review from
the 2026-10-13 visitor flags, curator notes, locale catalogs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bdevloed
bdevloed merged commit eff2bf7 into main Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant