Skip to content

fix(calendar): surface degraded get_calendar_events sentinel so web fallback fires#2833

Merged
pethers merged 2 commits into
mainfrom
copilot/analyse-improve-agentic-workflows
May 30, 2026
Merged

fix(calendar): surface degraded get_calendar_events sentinel so web fallback fires#2833
pethers merged 2 commits into
mainfrom
copilot/analyse-improve-agentic-workflows

Conversation

Copilot AI commented May 29, 2026

Copy link
Copy Markdown
Contributor

Analysis of the last 5 agentic-workflow PRs (#2819, #2821, #2822, #2823, #2824) for degraded datasources surfaced a client masking bug: when data.riksdagen.se/kalender/ serves an HTML error page, the riksdag-regering MCP get_calendar_events tool returns a successful result wrapping a sentinel {count:0, events:[], error, rawHtml}. The clients read the empty events:[] as a legitimate zero-event window, so scripts/calendar-fetch.ts reported a false status:ok, path:mcp-primary and the web-scraper fallback never fired — masking the outage as a real zero-sitting week.

Client code

  • scripts/fetch-calendar/mcp/errors.ts — new isDegradedKalenderSentinel() detector; triggers only on a non-empty error string or rawHtml, so a clean {count:0, events:[]} stays a valid empty window.
  • scripts/fetch-calendar/mcp/client.ts — detect the sentinel in both the content-wrapped and direct-result paths and throw CalendarMcpError(..., 'html', rawHtml); orchestrator.ts already breaks the retry loop on kind:'html' and falls straight to the public-page scraper.
  • scripts/mcp-client/methods/calendar.ts — mirror the detection (throw instead of returning []).
  • scripts/fetch-calendar.ts — re-export the new detector.
if (isDegradedKalenderSentinel(inner)) {
  throw new CalendarMcpError(
    `MCP kalender API degraded: ${String(inner['error'] ?? 'upstream HTML error')}`,
    'html',
    typeof inner['rawHtml'] === 'string' ? inner['rawHtml'] : undefined,
  );
}

With the fix, the CLI now reports status:error, path:none during the outage instead of a fabricated zero-event success.

Agentic config / prompts / instructions

  • analysis/templates/session-baseline.md — added a 📅 Calendar sourcing degraded-source guard and pointed the 3 inline get_calendar_events references at the resilient data/runtime/calendar-status.json / scripts/calendar-fetch.ts.
  • .github/prompts/02-mcp-access.md — added a data-sourcing rule: fetch the calendar via the resilient CLI / pre-warm artifact (never the raw tool); record [DATA GAP: calendar source degraded] when both paths fail.

Tests

  • Regression coverage across tests/fetch-calendar/mcp/errors.test.ts, tests/fetch-calendar/mcp/client.test.ts (content + direct sentinel → kind:'html'), tests/fetch-calendar/orchestrator-integration.test.ts (sentinel → web-fallback), and tests/mcp-client/methods/calendar.test.ts (sentinel → throws).

Out of scope (documented)

The public fallback page moved from /sv/kalendarium/ (now 404) to a Next.js /sv/aktuellt/kalendersida/ serving data in __NEXT_DATA__; repointing the HTML scraper needs a parser rewrite plus markup fixtures. The now-honest status:error/path:none ensures the degradation is no longer silently masked in the meantime.

IMF (no change)

The other degraded source flagged in the manifests is already mitigated by the 3-tier WEO pipeline and data/imf-context.json degraded/unavailable handling.

…llback fires

The riksdag-regering MCP get_calendar_events tool returns a "successful"
empty events:[] result with an error/rawHtml sentinel when upstream
data.riksdagen.se/kalender/ serves HTML. The client read this as a
legitimate zero-event window, masking the outage and suppressing the
web-scraper fallback. Add isDegradedKalenderSentinel detection in both
calendar clients (throw CalendarMcpError 'html' so orchestrator falls
back), plus regression tests and agentic guidance steering agents to the
resilient scripts/calendar-fetch.ts CLI / data/runtime/calendar-status.json.

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copilot AI requested a review from pethers May 29, 2026 23:14
@github-actions github-actions Bot added documentation Documentation updates testing Test coverage refactor Code refactoring size-m Medium change (50-250 lines) labels May 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🏷️ Automatic Labeling Summary

This PR has been automatically labeled based on the files changed and PR metadata.

Applied Labels: documentation,testing,refactor,size-m

Label Categories

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers

pethers commented May 30, 2026

Copy link
Copy Markdown
Member

@copilot analyse

TypeScript & JavaScript Testing / Build Test (Vite) (pull_request)
TypeScript & JavaScript Testing / Build Test (Vite) (pull_request)Failing after 11m

and improve code quality and test coverage

…xpand test coverage

- Refactored scripts/mcp-client/methods/calendar.ts to import and use the
  shared isDegradedKalenderSentinel() from fetch-calendar/mcp/errors.ts
  instead of duplicating the detection logic inline.
- Added 9 new test cases across 3 test files:
  - errors.test.ts: both fields present, rawHtml-only, empty object,
    additional non-string type variants
  - client.test.ts: malformed JSON content, rawHtml in responseText,
    error message propagation, rawHtml-only sentinel
  - calendar.test.ts: rawHtml-only sentinel, error message verification

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>

Copilot AI commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot analyse

TypeScript & JavaScript Testing / Build Test (Vite) (pull_request)
...

The CI failure was a runner timeout/shutdown during the prebuild step (render-articles.ts --all --lang all rendering 237 articles × 14 languages) — not related to the calendar code changes.

I've made the following improvements in commit c22ecda:

Code quality:

  • Refactored scripts/mcp-client/methods/calendar.ts to import and reuse the shared isDegradedKalenderSentinel() function instead of duplicating the detection logic inline.

Test coverage (50 → 59 tests, all passing):

  • errors.test.ts: both error + rawHtml present, rawHtml-only sentinel, empty object, additional non-string type variants (undefined, true, [])
  • client.test.ts: malformed JSON content → kind:'json', rawHtml propagation to responseText, error message propagation in thrown error, rawHtml-only sentinel without error field
  • calendar.test.ts: rawHtml-only sentinel (no error field), error message verification in thrown error

@github-actions github-actions Bot added the size-l Large change (250-1000 lines) label May 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers marked this pull request as ready for review May 30, 2026 06:37
Copilot AI review requested due to automatic review settings May 30, 2026 06:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes calendar outage handling so degraded get_calendar_events MCP responses are surfaced as failures instead of being interpreted as legitimate empty calendars, allowing fallback/error reporting paths to behave honestly.

Changes:

  • Adds degraded calendar sentinel detection for error/rawHtml MCP payloads.
  • Wires detection into both the resilient calendar fetcher and generic MCP calendar method.
  • Updates prompt/template guidance and adds regression tests for sentinel handling and fallback behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
scripts/fetch-calendar/mcp/errors.ts Adds isDegradedKalenderSentinel() detector.
scripts/fetch-calendar/mcp/client.ts Throws CalendarMcpError('html') for degraded sentinel payloads.
scripts/fetch-calendar.ts Re-exports the new detector.
scripts/mcp-client/methods/calendar.ts Makes generic MCP calendar calls throw on degraded sentinel results.
tests/fetch-calendar/mcp/errors.test.ts Covers sentinel detection positives and negatives.
tests/fetch-calendar/mcp/client.test.ts Covers content-wrapped/direct sentinel handling and error propagation.
tests/fetch-calendar/orchestrator-integration.test.ts Verifies sentinel-triggered web fallback.
tests/mcp-client/methods/calendar.test.ts Covers generic MCP client sentinel failures.
analysis/templates/session-baseline.md Documents resilient calendar sourcing guidance.
.github/prompts/02-mcp-access.md Instructs workflows to use the resilient CLI/prewarm artifact instead of raw calendar tool output.

@pethers pethers merged commit deb3263 into main May 30, 2026
18 checks passed
@pethers pethers deleted the copilot/analyse-improve-agentic-workflows branch May 30, 2026 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Documentation updates refactor Code refactoring size-l Large change (250-1000 lines) size-m Medium change (50-250 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants