Runbook: Manual Social-Media Event Scan
Purpose: Find and verify Terceira events across official calendars, organizer websites, search, Instagram, and Facebook, then update the data through a PR. Cadence: Run once a week (or whenever you notice the upcoming-events list is getting thin). Time required: ~30–60 minutes depending on how active venues have been. Source status last verified: 2026-10-10; see the dated coverage ledger.
Context
Several event sources are not fully covered by the automated ingest workflows. The manual scan has three jobs:
- Check that the official automated sources are not lagging behind the live public agendas.
- Fill the gap for event flyers that only appear on social accounts.
- Discover organizers outside the existing culture/nightlife list, especially parish, sport, nature, science, and community activities.
This covers both Angra do Heroísmo and Praia da Vitória. The manual scan is especially useful for:
- Venue-specific nightlife events (Havanna Club, Porta 42, Tasca do Camões, The Texan / Garden Club)
- Bookshop/cultural events (Lar Doce Livro)
- City-council Instagram/Facebook posts that pre-announce events before they appear in the feeds
- Praia cultural events shared through Agenda Praia Cultural or the municipal Facebook page
The canonical list of venue social handles lives in _data/venues.yml. The canonical list of other resources is at eventosterceira.pt/resources/.
Use the source-discovery playbook and dated audit for reusable queries, newly tested sources, and unresolved leads. This runbook describes the procedure, not proof that every source was reached in a particular run.
Source Inventory
Use this as a maintained starting list for Angra and Praia scans. It is not a guarantee of comprehensive social coverage: private groups, stories, login walls, bot protection, and short-lived posts can all hide events. Record any inaccessible source in the scan report instead of silently treating it as checked.
| Source | Area | Role and current scan action |
|---|---|---|
CMAH events (angradoheroismo.pt/eventos) |
Angra | Primary first-party calendar. Compare the page and iCal with the repo. The iCal is live, but imported descriptions and all-day times still need manual verification. |
@angradoheroismo |
Angra | Primary municipal social account. Scan recent posts and every slide in carousels. |
| Teatro Angrense / CCCAH | Angra | Use CMAH and the venue/ticket seller as primary evidence. Do not rely on unofficial or empty Facebook profiles. |
Museu de Angra do Heroísmo + @museu.angra |
Angra | Read the events archive, both exhibition pages, dated categories, monthly programme, and Facebook/Instagram corrections. Native pages are readable in Chrome; automated HTTP returned 403 on 2026-10-10 and reports degraded status. Use native details and official government mirrors for manual verification. |
BPARLSR (bparlsr.azores.gov.pt/destaques/) |
Angra | First-party library calendar and monthly BiblioAgenda. The site is Cloudflare-protected, so scan it in a browser and use its calendar/iCal export when available. |
Casa do Sal / Oficina d’Angra (@oficinadangra) |
Angra | Primary source for Casa do Sal. Read the linked monthly Boletim da Oficina, including dates in poster images; it supplies sessions absent from the social grid. |
Lar Doce Livro (@livraria_lardocelivro) |
Angra | Scan every slide of the pinned monthly agenda carousel and individual corrections. Do not infer a weekly recurrence from one month’s dated programme. |
AMIT (@amit.academiamusical, @espacoamit, @cjazzamit) |
Angra | Check the academy, event-space, and jazz-course accounts. The former @auditorioamit handle is unavailable. |
AAIP (@aaipazores) |
Angra | Independent arts source. Cross-check ticketed events on Shotgun when its search is accessible. |
| Tasca do Camões, Havanna, Porta 42, Texan, Garden Club, Twins, Wine Not?, Sala 319 | Angra/Praia nightlife | Scan recent grids, reels, and highlights. Revalidate _data/weekly.yml against current posts before treating a recurring night as already covered. |
CMPV agenda (cmpv.pt/index.php?op=agenda), @cmpraiadavitoria, @agendapraiacultural |
Praia | Primary municipal sources. Read the direct agenda and social programmes; Agenda Praia Cultural supplies the October cinema and Concertos Únicos 2027 posters. |
| Auditório do Ramo Grande | Praia | Cross-check CMPV, Agenda Praia Cultural, and Ticketline. |
| Casa Museu Vitorino Nemésio / Biblioteca Municipal Silvestre Ribeiro | Praia | Check CMPV and Agenda Praia Cultural directly. |
Cultura Açores (culturacores.azores.gov.pt/agenda/) |
All islands | Current official culture agenda, readable in Chrome. Select Terceira and an overlapping date range, then read every results page. Its 2026-10-10 search returned 36 records on 4 pages, including ongoing exhibitions. Publications and virtual tours are not physical events. |
| What’s On Azores | All islands | The public website data query was readable on 2026-10-10. Paginate every advertised page, require an explicit Terceira reference, and use Portuguese displayed dates rather than administrative CMS timestamps. |
| byAçores Terceira agenda | Terceira | Discovery-only cross-check. The Portuguese /terceira/ page showed September/October 2026 listings in a browser on 2026-09-04; the previously checked English route appeared stale. Check the exact route and year, then follow original sources. agendacores.pt redirects here. |
AIR Centre (aircentre.org/pt/events) |
Regional/international | Primary source for citizen science and marine activities. Inspect event location and registration eligibility; the Terceira headquarters address does not make every event local. |
Azores Bravos Trail (azoresbravostrail.com) |
Terceira | Primary organizer programme for races and walking. Check the current edition, actual start locations, and registration deadlines, not just a tourism summary. |
Clube de Golfe da Ilha Terceira (terceiragolf.com/atividade-desportiva/) |
Terceira | First-party sporting calendar. Read the full dated table, including individual and pairs competitions beyond the 90-day social-post window. |
Festing (festingapp.com/en/events) |
Portugal/all islands | Secondary discovery source with current local listings. Use browser pagination and place search, then follow organizer links; do not treat all results as Terceira events. |
| PortugalEvents.eu | Portugal/all islands | Secondary discovery lead source. Filter by Terceira and follow the organizer or public-institution page before publishing. It can surface workshops omitted by the automated feeds. |
| Ticketline | Angra + Praia | Useful for paid shows. Multi-session event pages can be assigned the wrong city/date by the current parser, so verify the Terceira session manually before adding it. |
| Songkick + Bandsintown | Angra/Terceira | Secondary music discovery. Bandsintown exposed more current local listings than Songkick on 2026-09-04. Confirm the date and venue with the artist, promoter, or venue. |
| Eventbrite + Shotgun | Terceira | Discovery for organizer-posted workshops, festivals, and independent arts. Expect bot/rate limits and verify local venue details. |
| Visit Azores | All islands | The configured /en/events URL returned 404 on 2026-09-04. Do not count it as scanned until a replacement endpoint is found. |
| Touradas à corda | Terceira | Covered by ingest-touradas.yml. Do not transcribe manually unless the workflow is broken. |
| Ilha Terceira - Eventos Facebook group | Terceira | Community discovery only. Report explicitly when the group feed could not be scanned completely. |
Cine-Clube da Ilha Terceira (@cineclubedailhaterceira) |
Angra | First-party cinema source. Use its season announcement plus the CMAH season page; enter the actual dated screenings rather than a generic every-Sunday recurrence. |
Sabores da Horta (@sabores_dahort_a) |
Praia | First-party source for strawberry-picking hours and family activities. Recheck the profile because hours can be seasonal. |
Earlier checks on 2026-09-04 found @fullrange_rave, @auditorioamit, and the direct Casa do Sal Facebook page unavailable; Agenda da Terceira had not posted a current agenda since February 2026; Explore Terceira was a business directory rather than an event calendar; Songkick had substantially fewer current listings than Bandsintown; the old Cultura Açores domain failed DNS; and the configured Visit Azores endpoint returned 404. These are dated, route-specific observations, not permanent closures. The later browser check recovered a useful Portuguese byAçores route.
Finding and qualifying new sources
Do not limit discovery to the static account list. During each scan:
- Inspect co-authors, tagged accounts, venue tags, promoters, and recurring collaborators on confirmed local posts.
- Search the next 90 days using the geographic/category query matrix in the discovery playbook. Include ongoing events and verified announcements beyond that horizon, not just weekend nightlife.
- Promote a candidate to the maintained list only when it has a clear first-party role or at least two recent, dated, Terceira-specific event posts.
- Use aggregators to find leads. Prefer the organizer, venue, artist, municipality, or ticket page for the final event details.
- Follow calendar pagination and detail pages. Try the site’s linked Portuguese route or browser view when a cached/translated page is stale. Do not invent feed endpoints or call an inaccessible source empty.
- Record the exact URL, access method, date checked, observed date range, useful leads, access failures, redirects, and parser errors in the PR body. Use the source-status template in the discovery playbook.
Deep-scan completion controls
A deep scan is complete only when the following controls have evidence in the tracking issue or PR:
- Open every pinned monthly or seasonal programme and inspect every carousel page, PDF page, calendar row, and pagination page. A partially read programme is an incomplete source, not a checked source.
- Maintain a candidate ledger with source URL, event date, title, venue, evidence class, deduplication result, and one of
accepted,held, orrejected, including the reason. - Run the automated ingesters in dry-run mode and record fetched, parsed, local-candidate, duplicate, and missing-event counts. A successful process that parses zero events after a 403, 404, non-calendar response, or schema change is degraded, not healthy.
- Compare each candidate against the complete YAML by date, normalized title, venue, and source identity. Repeat an exact-title web/social search for held or ambiguous candidates.
- Audit each recurring venue’s complete current monthly programme, not only its newest grid posts. Record the last page or date reached when access stops.
- Keep licence notices, cached snippets, and aggregators as leads until public attendance and the date, venue, and organizer are corroborated. Never turn a municipal noise licence alone into a public event listing.
- Follow organizer-linked newsletters and public bulletins. Read both text and embedded posters: a newsletter heading can omit a date printed in its image. An accessible cover is not an inspected programme.
- Record date/weekday conflicts and source-side duplicate venues. Hold conflicting dates; do not select one by guessing. A future course session needs a published date, not a manufactured sequence through holidays.
Maintaining recurring-event data
Treat _data/weekly.yml as a current schedule, not a permanent catalogue:
- Recheck each affected venue’s most recent first-party post or profile before changing a weekly record.
- Record the evidence URL where available and the date and scope of verification. A dated YAML comment can distinguish organizer evidence from a maintainer’s local confirmation. Never make
verified_onimply that an unconfirmed start time was rechecked. - Add a weekly event when the organizer states a recurring day, recent first-party history demonstrates a stable cadence, or a maintainer explicitly confirms the current recurrence. A single dated poster is not sufficient by itself.
- Remove or pause a weekly listing only with affirmative evidence of cancellation, closure, an expired seasonal programme, or a maintainer’s correction. Sparse posts, login failures, and unsuccessful searches do not demonstrate cancellation. Preserve the existing listing and report what remains uncertain. The 2026-09-04 maintainer confirmations of Camões Thursday Latin night and ongoing Texan karaoke must not be undone merely because a fresh flyer is unavailable.
- Put monthly agendas, seasonal cinema programmes with skipped weeks, rotating concerts, and other specifically dated schedules in
_data/special_events.yml. - Update the matching summary in
_data/venues.ymlwhenever a weekly schedule changes so the venue and weekly pages do not contradict one another.
Prerequisites
- You are logged into Instagram in the browser (the account that follows all the venue accounts).
- You are logged into Facebook in the same browser session.
- You have a GitHub account with write access to this repo (or can open a PR from a fork).
- Today’s date is noted — you will need it to distinguish upcoming vs already-past events.
Step 1 — Check what’s already in the file
Before scanning, read all of _data/special_events.yml, including entries whose start date has passed but whose end_date is still upcoming. Also inspect _data/weekly.yml and its evidence notes.
Quick way: https://github.com/TerceiraEvents/EventosTerceira.pt/blob/main/_data/special_events.yml
The file contains appended scan sections and is not globally chronological. The last entry or maximum date is not a coverage watermark. Search the whole file by date, distinctive title, venue, and source_url/source_uid; compare alternate-language titles too.
Also check the live site for the current upcoming-events list: https://eventosterceira.pt/
Step 2 — Check open issues for an existing scan
Before starting, inspect open issues and PRs at https://github.com/TerceiraEvents/EventosTerceira.pt for overlapping scans and submission-worker entries. Read their findings and avoid duplicating pending additions.
Use an overlapping publication window: start at least 14 days before the last successful scan, or inspect at least the last 14 days of posts on a first pass. Also inspect pinned programmes, future-dated calendar pages, and corrections to existing upcoming events. Search events from today through the next 90 days, retaining any verified later announcements you find. Never start after the previous scan’s event-date range: late announcements can concern dates that were already searched. Record publication and event windows separately.
Step 3 — Scan official web agendas first
Start with official web agendas before social media. They are faster to scan and they prevent duplicate manual entries.
| Source | URL | What to check |
|---|---|---|
| CMAH official events | https://www.angradoheroismo.pt/eventos | Angra municipal events, Teatro Angrense, CCCAH, Casa do Sal, Museu, Biblioteca, Cinefreguesias |
| Praia da Vitória municipal events | https://www.cmpv.pt/index.php?op=agenda | Praia municipal events, Auditório do Ramo Grande, Biblioteca Municipal, Casa Museu Vitorino Nemésio, and the dedicated touradas category |
| What’s On Azores | https://whatson.azores.gov.pt/agenda/ | Filter or scan for Terceira; use Portuguese place names and compare against the repo because the feed can lag or miss items |
| BPARLSR highlights | https://bparlsr.azores.gov.pt/destaques/ | First-party library calendar, BiblioAgenda, and calendar exports |
| Cultura Açores Agenda Cultural | https://culturacores.azores.gov.pt/agenda/ | Filter to Terceira; useful for cultural listings and public institutions |
| byAçores Terceira | https://byacores.com/terceira/ | Portuguese island page and its agenda links; verify absolute dates and original sources |
| Clube de Golfe da Ilha Terceira | https://terceiragolf.com/atividade-desportiva/ | Read the complete first-party tournament calendar and deduplicate by date and competition name |
| AIR Centre | https://www.aircentre.org/pt/events | Citizen science and marine activities; check local venue and whether attendance/registration is open |
| Azores Bravos Trail | https://azoresbravostrail.com/ | Current organizer programme, walking/race start locations and registration status |
| Festing | https://www.festingapp.com/en/events | Browser-based secondary discovery; paginate and confirm actual event geography |
| Ticketline | https://ticketline.sapo.pt/ | Paid shows at Angra/Praia venues |
| Songkick / Bandsintown | https://www.bandsintown.com/c/angra-do-heroismo-portugal | Touring concerts; also check Songkick, then cross-check artist and venue sources |
| Eventbrite / Shotgun | https://www.eventbrite.pt/d/portugal–terceira/events/ | Organizer-posted workshops and independent ticketed events |
For each upcoming event not already in special_events.yml, note:
- Event name (PT and EN if bilingual)
- Date(s) and time(s)
- Venue name
- Any ticket/price information visible
- Source URL
- Publication date/year, whether registration is open, and any eligibility restrictions
Priority targets:
- Teatro Angrense performances
- CCCAH (Centro Cultural e de Congressos) concerts and shows (the “Angra Convida” series in particular)
- Casa do Sal and Museu de Angra do Heroísmo cultural events
- Biblioteca Pública events
- Cinefreguesias outdoor cinema series (recurring summer programme)
- Auditório do Ramo Grande shows in Praia
- Casa Museu Vitorino Nemésio and Biblioteca Municipal Silvestre Ribeiro events in Praia
- Parish associations, sports organizers, and nature/science groups from the discovery playbook; cover both municipalities, not only Angra’s established venues
Note: Many of these are auto-ingested by daily workflows. Cross-check before adding. If the live official agenda has an upcoming event that the repo does not, add it as a manual backfill and mention the source in the PR.
Step 4 — Scan Instagram accounts
Navigate to each account below and scroll the grid looking for event flyers. Read captions, every carousel slide, pinned programmes, highlights, and later corrections. Use Step 2’s overlapping publication window, and record the actual publication date where available rather than treating search-result freshness as the event date.
Priority accounts (most likely to have new events)
| Account | Platform | What to look for |
|---|---|---|
@angradoheroismo |
CMAH-sponsored concerts, exhibitions, festival announcements | |
@museu.angra |
Official Museu de Angra do Heroísmo account; exhibitions, family programs, outdoor museum events | |
@amit.academiamusical |
Academy concerts, showcases, auditions | |
@espacoamit, @cjazzamit |
AMIT event-space programme and jazz-course events | |
@oficinadangra |
Instagram + Facebook | Primary Casa do Sal programme, workshops, concerts, and community projects |
@aaipazores |
Independent arts events and Shotgun-ticketed programmes | |
@livraria_lardocelivro |
Pinned monthly agenda carousel, concert/workshop/poetry posts; scan every slide | |
@havannaangra |
Weekend DJ/live-act schedule posts (Fri/Sat/Sun) | |
@porta_42 |
Saturday night DJ/theme nights | |
@tascadocamoes |
Instagram + Facebook | Live music acts (check both — Facebook often has more detail) |
@thegardenclub.angra |
Periodic special nights (less frequent) | |
@thetexanbar |
Check “Eventos” story highlight; grid posts rare | |
@twinstheclub |
Major nightclub; skip recurring weekly nights, add one-off guest DJ/special events | |
@cineclubedailhaterceira |
First-party season announcements and individual cinema screenings | |
@sabores_dahort_a |
Seasonal strawberry-picking schedule and family activities |
Secondary accounts (check if time permits)
| Account | Platform | Notes |
|---|---|---|
@winenot.terceira |
Occasional live music nights | |
@sala.319 |
Primarily daily lunch menus; skip unless something unusual | |
@caes.do.mar, @ruadireita.azores |
Seasonal independent culture and festival programmes | |
@cmpraiadavitoria, @agendapraiacultural |
Praia municipal and cultural programmes; note stale posting periods |
For each event post found
- Read the full caption (scroll within the post modal if needed).
- Note: name, date, time, venue, any ticket/price info, and the post URL.
- Check whether it is a genuinely recurring weekly event or a dated special event. Revalidate any matching
_data/weekly.ymlrecord before relying on it. - Skip only an exact current duplicate. If the new source changes a day, time, status, or cadence, update the weekly data or add the dated event.
Tips for reading Instagram posts efficiently
- The pinned monthly agenda carousel from
@livraria_lardocelivrois a multi-slide post. Swipe through every slide and enter dated items individually unless the agenda explicitly demonstrates a weekly cadence. - Havanna Club often posts a single reel listing 3 nights at once (Fri/Sat/Sun) — one post, three events.
- Even official accounts publish recaps. Confirm the event year and full date before adding anything.
- Resolve “Amanhã” (tomorrow) or “Este sábado” (this Saturday) from the post’s publication date, in
Atlantic/Azores, not the date of the scan. A repost date may differ from the original. If the original timestamp/year is unavailable or contradictory, keep the item as an unresolved lead instead of guessing.
Step 5 — Scan Facebook pages
Some venues post events primarily or exclusively on Facebook. Check these pages:
| Page | What to look for |
|---|---|
Tasca do Camões (facebook.com/tascadocamoes) |
Live music acts — the Photos tab often shows flyers most clearly |
Oficina d’Angra / Casa do Sal (facebook.com/oficinadangra) |
Casa do Sal cultural events and workshop flyers |
Lar Doce Livro (facebook.com/livrarialardocelivro) |
Book launches, poetry nights, weekly agenda cross-posts |
Havanna Terceira (facebook.com/p/Havanna-Terceira-100059128671983/) |
Weekend nightlife flyers when Instagram lacks detail |
Município Praia da Vitória (facebook.com/MunicipioPraiaVitoria) |
Praia municipal programs, exhibitions, family activities |
Agenda Praia Cultural (facebook.com/agendapraiacultural) |
Praia-specific cultural events and venue posts |
| Ilha Terceira - Eventos (community group) | Community-shared events from sources not otherwise covered |
Note: The direct Casa do Sal page (
facebook.com/casadosal.angra) and an apparent Teatro Angrense Facebook profile were still not useful on 2026-09-04. Use CMAH, Ticketline,@oficinadangra, and venue websites instead.
For Facebook, the Photos tab of a page is often the fastest way to spot event flyers. Click a flyer photo to open it and read the post caption.
Step 6 — Deduplicate against special_events.yml
Search the complete file for each candidate’s date, distinctive title, venue, and source identity. Account for Portuguese/English titles, date ranges, and alternative names. Compare detail fields, not just presence: a matching event may need its time, location, race distance, cancellation, or registration information corrected. Check open PRs as well. Run the duplicate validator in Step 8d after editing.
Raw file URL for fast Ctrl+F: https://raw.githubusercontent.com/TerceiraEvents/EventosTerceira.pt/main/_data/special_events.yml
Step 7 — Open a tracking issue
Create a new GitHub issue titled:
[MONTH/YEAR] event-source scan: [N] additions and source-health findings
Use this template (matches the pattern of issues #141, #161):
## Summary
Checked [actual sources and access methods] on **[DATE, TIMEZONE]**.
Publication lookback: [range]. Event horizon: [range, plus any later announcements].
List new events, corrections to existing entries, unresolved leads, and access gaps separately.
---
## Events to Add
### 1. [Event Name]
- **Date:** YYYY-MM-DD ([Day of week])
- **Time:** HH:MM
- **Venue:** [Venue name]
- **Address:** [Full address]
- **Description:** [English description]
- **Description PT:** [Portuguese description]
- **Source:** [URL] (@account)
- **Tags:** [comma-separated tags]
### 2. ...
---
## Already in the file (confirmed)
- [Event name] — [Date], [Venue] ✅
---
## Sources Scanned
| Source URL | Method | Observed date range | Status | New / corrected / duplicate / held |
|---|---|---|---|---|
| [Exact route or account] | [browser/feed/search] | [range] | [reachable/partial/blocked/empty-with-window/untested/stale] | [counts and evidence links] |
This issue serves as both a paper trail and a checklist. Check off each event as you add it to the YAML.
Step 8 — Write the YAML entries
Each new special event goes as a new list item in _data/special_events.yml. The schema is:
- date: YYYY-MM-DD # required
id: "<assigned opaque ID>" # required publication output; omit for new records until assignment
end_date: YYYY-MM-DD # inclusive; required for exhibitions and multi-day events
kind: event # required for multi-day exhibition-tagged records; otherwise optional
visiting_hours: "Mon–Fri 16:00–18:30" # optional, only when stated by the source
visiting_hours_pt: "Seg–Sex 16h00–18h30" # optional Portuguese wording from the source
name: "Portuguese name" # required
name_en: "English name" # add if different from Portuguese
venue: Venue Name # required; must match the name in venues.yml if the venue is listed there
address: "Full address, postcode Angra do Heroísmo"
map_url: https://www.google.com/maps/search/?api=1&query=...
time: "HH:MM" # 24-hour, quoted string
description: "English description prose."
description_pt: "Portuguese description prose."
source_url: https://... # original organizer/venue event detail, when available
instagram: https://www.instagram.com/p/... # source post URL (use 'facebook:' key for FB sources)
tags:
- live-music # see _data/event_tags.yml for valid tags — canonical only
- free
For each new record, omit id while drafting, then run
ruby scripts/assign_event_ids.rb followed by
ruby scripts/validate_event_data.rb _data/special_events.yml before committing.
Remove an empty or null id key instead of leaving a blank placeholder; assignment rejects null keys without writing. Keep every existing ID when correcting metadata. Do not copy the schema’s ID
placeholder. A duplicate-record merge retains the older persisted ID; record both
IDs and the retained ID in the PR body.
kind accepts only event or exhibition; records without it are events. An exhibition is a visitable display whose date and inclusive end_date describe the display period. It must have an end_date strictly after date and the canonical exhibition tag. Every record tagged exhibition with a multi-day range must declare kind explicitly, including records that remain dated events. A single-day opening, talk, or guided tour tagged exhibition is a dated event and does not need kind. The time field on an exhibition is legacy information and is never an attendance time. Provide visiting_hours and visiting_hours_pt together for a source-stated schedule, translating faithfully and preserving every date restriction; leave both absent otherwise. Older readers ignore these optional fields and continue to read the existing event fields.
An opening reception, artist talk, or guided tour is a separate dated kind: event record that names its exhibition. Keep the long display period in its own kind: exhibition record; do not duplicate one occurrence as both listings.
Valid tags — canonical only
These are the only valid tag slugs (source of truth: _data/event_tags.yml). Unknown tags fail the tag-vocabulary CI check and do not work correctly with calendar filtering.
kid-friendly · live-music · cinema · theater · dance · nightlife · karaoke · food-drink · exhibition · literature · workshop · free · outdoor · bullfighting
Common mistakes (do not use; map to the canonical slug instead):
| Looks intuitive | Use this canonical slug |
|---|---|
concert |
live-music |
theatre (UK spelling) |
theater |
comedy |
theater |
film |
cinema |
talk / lecture |
literature |
sports |
outdoor |
art (static) |
exhibition |
art (hands-on) |
workshop |
festival |
(split between live-music, theater, outdoor, etc. — pick what actually describes it) |
Ordering
Keep new entries chronological within their existing month or dated scan section. Do not reorder the entire file just to add an event; older scan sections are not globally sorted.
Addresses for common venues
| Venue | Address |
|---|---|
| Lar Doce Livro | Rua de São João 22-24, 9700-182 Angra do Heroísmo |
| Tasca do Camões | Rua Da Rocha 64, 9700-169 Angra do Heroísmo |
| Havanna Club | Av. Infante D. Henrique, 9700-098 Angra do Heroísmo |
| Teatro Angrense | Rua da Esperança 48-52, 9700-073 Angra do Heroísmo |
| CCCAH | Rua Conselheiro Dr. José Pereira, 9700-040 Angra do Heroísmo |
| Casa do Sal | Estrada Gaspar Corte-Real, 9700-030 Angra do Heroísmo |
| Museu de Angra do Heroísmo | Ladeira de São Francisco, 9700-181 Angra do Heroísmo |
| Centro Interpretativo | Rua da Rosa, Angra do Heroísmo |
| Biblioteca Pública | Rua do Morrão 42, 9700-054 Angra do Heroísmo |
| Porta 42 | Rua de São João, Angra do Heroísmo |
Step 8b — Re-host any images before linking them
If you want a flyer to render on the event card, you cannot reference the raw Instagram / Facebook / CDN URL directly — those image URLs rot within days (sometimes hours). The site repo has a re-hosting workflow that fetches the bytes once and stores them as a permanent GitHub release asset:
- Script:
scripts/rehost_image.py - Workflow:
.github/workflows/rehost-image.yml(trigger via the Actions tab → Rehost image → Run workflow, paste the source URL + a slug)
The output is a https://github.com/.../releases/download/... URL. Use that as the image: field on the event entry. If you skip this step, the image will work for a few days and then 404 — and the daily-rebuild won’t catch it.
Background: the mobile-app submission worker does this automatically (it re-hosts before opening the PR). For manual scans you have to do it by hand or your flyers will silently die.
Step 8c — Check the submission-worker PR queue before you write your PR
The mobile app’s Suggest button and the website’s /suggest/ form both open PRs via event-submit-worker. Before you stack a manual scan PR on top of main, glance at:
https://github.com/TerceiraEvents/EventosTerceira.pt/pulls
If open auto-submission PRs touch _data/special_events.yml, inspect them and avoid overlapping additions. Note dependencies or likely conflicts in your PR. Do not merge another PR or incorporate its unrelated changes without authorization; the maintainer handles merging.
Step 8d — Pre-flight: run the repository validators
Run the actual checks from the repo root before committing. These validate the complete event file, not just a fragile extraction of added diff lines:
bundle exec ruby scripts/tests/test_tag_vocabulary.rb
bundle exec ruby scripts/tests/test_special_event_duplicates.rb
python3 scripts/validate_image_hosts.py _data/special_events.yml
bundle exec jekyll build --trace
bundle exec ruby scripts/tests/test_built_site.rb
git diff --check
Use the repository’s documented Ruby/Bundler environment. Record actual results and any local environment limitations; do not claim a build passed unless it ran. After publishing, inspect both validate event data and validate templates and structured data in GitHub Actions.
Step 9 — Open a PR
Once you’ve added your entries to the YAML, open a pull request:
- Title:
Add [N] new events: [brief description] (#ISSUE_NUMBER) - Body: Reference the tracking issue with
Closes #NNNorSee #NNN - Branch: Create from
main, name it something likeevents/may-22-scan
Request review after the CI checks finish. The repository maintainer decides when to merge; this runbook must not merge its own PR into main.
After merging, the daily-rebuild.yml workflow will rebuild and deploy the site within ~5 minutes.
Step 10 — Close the tracking issue
Once the PR is merged, close the tracking issue (or it closes automatically if you used Closes #NNN in the PR body).
What NOT to add
- Recurring weekly events (karaoke nights, Noche Latina, DJ resident nights) → these belong in
_data/weekly.yml, notspecial_events.yml. Checkweekly.ymlbefore adding. - Events that have already passed by the time you’re writing the PR.
- Events with no confirmed date (e.g. “coming soon” posts with no date).
- Events already represented in the repo, whether manually entered or auto-ingested. A configured workflow is not proof that its current source is healthy. Use the status table below and backfill missing events from verified sources.
- Inferred exhibition classifications or hours. Use
kind: exhibitiononly for a visitable display with a verified inclusive display period; classify multi-dayexhibition-tagged programmes aseventwhen they represent attendance days. Declarekindexplicitly for every multi-day record with theexhibitiontag. Do not turn an exhibition’stimeinto an attendance time or add hours the source does not state. Provide both language fields together, translating the same published schedule faithfully and retaining date restrictions. - A combined opening and display listing. Record an opening reception, artist talk, or guided tour as its own dated event naming the exhibition, and keep the display period on the exhibition record.
Automated ingest coverage (spot-check, but do not duplicate)
These sources have configured daily GitHub Actions workflows. Configuration or a green run does not prove successful coverage: some ingesters return successfully after fetching no usable events. Spot-check the live source against _data/special_events.yml; backfill verified omissions with the original source URL.
| Source | Workflow file | Latest verified status |
|---|---|---|
| CMAH iCal feed | ingest-cmah.yml |
Live dry-run produced current candidates, but the source contains duplicate records with title/venue variation; manually deduplicate against the full YAML |
| Ticketline (Angra + Praia) | ingest-ticketline.yml |
Reachable; the 2026-10-08 dry-run found candidates and parse failures, and multi-session pages still require manual city/date verification |
| Museu de Angra do Heroísmo | ingest-museu-angra.yml |
2026-10-10: dated native archives verified in Chrome; unattended HTTP 403. The tested repair reports degraded status and exits 1 without editing YAML |
| Câmara Municipal Praia da Vitória | ingest-cmpv.yml |
2026-10-10: repaired adapter reads the real public agenda, all linked pages, details, and calendar IDs; 16 cards and 4 upcoming cultural duplicates in the live dry-run |
| Visit Azores | ingest-visit-azores.yml |
Configured events URL returned 404 |
| Whatson Azores (government) | ingest-whatson-azores.yml |
2026-10-10: repaired adapter reads all 11 advertised website-data pages; 208 records, 24 Terceira records, 25 sessions; 22 duplicates and 2 candidates before manual reconciliation |
| Touradas à corda | ingest-touradas.yml |
Keep as the canonical automated source and spot-check Actions |
If an automated workflow is producing errors or missing events, check the Actions tab: https://github.com/TerceiraEvents/EventosTerceira.pt/actions and mention the backfill in the PR body.
The implementation and CI evidence for the Museu, CMPV, and What’s On source-health contracts are in the ingester repair PR. Check its merged state before relying on scheduled production coverage. Their repaired workflows attach source-health.json and publish counters in the Actions job summary; incomplete discovery must fail before changing YAML.
For source-health checks, distinguish fetch status, parsed event count, Terceira candidate count, duplicates, corrections, deferred additions, and missing verified events. A failed/blocked/non-calendar response is degraded, not empty. A healthy zero-addition run requires recognized source markup, complete pagination, and full-YAML reconciliation. Use the ingestion commands and source contracts for repeatable dry-runs. Inspect date and eligibility warnings as well as the exit code, and treat changed-time reports as review work. Do not assume an event is in Angra merely because its page mentions Terceira, or that a healthy feed contains every current social programme.
Kicking off with an AI assistant
This whole workflow can be handed off to Claude (or another AI with browser access) with a single prompt:
“Run
docs/runbook-social-scan.mdand its linkeddocs/event-source-discovery.mdplaybook. Check official calendars, organizer programmes, Instagram, Facebook, and discovery services. Use the geographic/category query matrix, overlapping publication window, ongoing events, and future announcements; do not stop at the existing venue list. Follow tagged organizers and collaborators to qualify new sources. Cross-check every candidate against all of_data/special_events.yml,_data/weekly.yml, and open PRs. Preserve maintainer-confirmed recurrences unless there is affirmative evidence of a change. Prefer first-party details, resolve relative dates from the original post timestamp, and report blocked/partial sources without claiming comprehensive coverage. Use canonical tags from_data/event_tags.yml. Skip touradas à corda unless its workflow is broken. Re-host any flyer before using it asimage:. Create a feature branch from current main, add verified events and source-documentation changes, run repository validations, open a PR, and request review. Never merge the PR.”
For an authorized implementation, the assistant follows this runbook and the linked discovery playbook, updates the data/docs on a fresh branch, validates locally, and opens the PR. It reports verified additions, corrections, source improvements, unresolved leads, and CI status. It does not merge. For a research-only request, return findings and suggested changes without publishing or changing the repository.
Prompt for just the issue:
“Write an internal GitHub issue detailing all the new events found, following the format of issue #141.”
Prompt for the PR YAML only:
“Format all new events as YAML entries for
_data/special_events.ymlusing the schema in that file. Use only canonical tags from_data/event_tags.yml(kid-friendly, live-music, cinema, theater, dance, nightlife, karaoke, food-drink, exhibition, literature, workshop, free, outdoor, bullfighting).”