Skip to content

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

Draft
Copilot wants to merge 1 commit into
mainfrom
copilot/analyse-improve-agentic-workflows
Draft

fix(calendar): surface degraded get_calendar_events sentinel so web fallback fires#2833
Copilot wants to merge 1 commit into
mainfrom
copilot/analyse-improve-agentic-workflows

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 29, 2026

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

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-m Medium change (50-250 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants