Repository navigation
release 1.41.8: CF staging fix + event-app improvements - #2964
Merged
Merged
Conversation
architecture-sap-com-fetcher derived the live-site URL purely from the
GitHub file path (.../RA0029/readme), but the Architecture Center
(Docusaurus) routes docs by their `slug:` frontmatter under /docs
(e.g. /docs/ref-arch/98efa0). ~87% of docs carry a slug, so the
path-derived URLs 404 — this is why every "Doc ↗" Architecture Center
link on /concepts/agent-gateway (all 16 RA0029 docs) was broken.
Parse `slug:` from frontmatter and build `${SITE_BASE}/docs${slug}`
when present; keep the path-derived URL as fallback for the no-slug
minority. Verified against the live site: /docs/ref-arch/98efa0 → 200.
Note: stored HelpDocs rows keep their old URLs until a help-docs
re-fetch/re-ingest repopulates them — code fix is forward-correct.
…lug-urls fix(help-docs): honor Docusaurus slug for Architecture Center URLs
Brotli C decoder out-of-bounds write (CWE-787/CWE-252). Node 22.x is vulnerable below 22.23.4. Raise engines.node floor so the CF nodejs_buildpack installs a patched 22.x at staging; cap <23 to stay on the buildpack-supported 22 line. Reachable only via undici auto-decompression of Content-Encoding: br from outbound fetches (all trusted SAP/GitHub hosts over TLS), so this is a defense-in-depth runtime bump, not an active-exploit hotfix.
…1497) srv-qa deploys as a separate CAP module from its own package.json + lockfile; dep-parity guard requires engines.node to match root.
…1497) The separate tutorials-mcp MTA stages tutorials-srv-mcp from gen/srv-mcp, whose package.json is copied from committed srv-mcp/. Raise its Node floor to match so a patched 22.x is installed at staging. No tracked lockfile; not an npm workspace member, so package.json alone is authoritative.
Navigating into a track only mutated local state, so a page refresh reset to the track list and the browser back/forward buttons did nothing. Reflect the selected track in a `track` query param via history.pushState, restore it on load, and listen for popstate so back/forward move between the list and a track. Unknown/stale ids fall back to the list. Existing eventId/theme params are preserved.
fix(app-space): persist selected track in URL for refresh + back/forward
fix(security): pin Node runtime floor to 22.23.4 (CVE-2026-111497 Brotli)
Reduces .hero padding from 2.5rem 2rem 1.5rem to 0.75rem 2rem so that missions in the lower row are visible without scrolling on the external monitors used at TechEd app-space workstations. Also trims .hero-instructions margin-top from 1.5rem to 0.75rem and updates the mobile (<640px) override to match. Closes #2941
…nner-padding fix(app-space): reduce hero banner padding to surface more missions (#2941)
…andarin (#2943) Arabic: fix hundreds spelling (مية→مائة for 300/400/500/600/700/800/900), fix 2000 dual (الفا→ألفان), fix 5000 spacing (خمسةالاف→خمسة آلاف). Hebrew: fix 2000 dual (אלפים→אלפיים), fix ו-connector spacing so it prefixes the next element rather than appending to the current one (אלף ו אחת→אלף,ואחת). English: remove stray comma from thousands separator (one thousand, one→one thousand,one). Mandarin: eliminate stray space after 零 by joining zero-suffixed elements with their following token (一千零 一→一千零一).
…they self-heal The event display seeded bucket counts once from getEventBuckets, then only ever incremented them from socket completionTick/tutorialCompleted events. Any missed socket event — reconnect gap, multi-instance session flap, dropped long-poll cycle — was lost permanently, so an all-day kiosk drifted below the true total and only a full page refresh (which re-runs getEventBuckets) resynced it. This is the 'numbers do not update live / have to keep refreshing the kiosk' report. Root cause is client-side: the display had no reconciliation path. The Redis adapter, Gorouter JSESSIONID/__VCAP_ID__ affinity, and the WS transport are all working; they just cannot guarantee zero missed events over hours, and the client had no safety net. Add reconcileBuckets() (pure, unit-tested) and a 15s periodic getEventBuckets re-fetch that heals drift WITHOUT rewinding counts the live socket already advanced past (monotonic merge, avoids visible backward jumps). Socket deltas keep the display snappy; reconciliation guarantees it converges to truth. No infra change. Verified: reconcile unit tests (3) + existing event-stream/ display suites (14) green; display-app build clean.
…track completions The per-hour rate was ALWAYS ZERO at events whose completions didn't resolve to a mission CompletionPath. Root cause (observed by running the app): the rate (messageTimestamps -> speedApproximation) was fed ONLY from tutorialCompleted, which the server emits only for completions that map to a track. completionTick — emitted for EVERY completion, track or not — did not feed the rate. So when completions were off-track, tutorialCompleted never fired and per-hour stayed 0 for the whole event, even though the hero total (completionTick) ticked up. Feed the rate from completionTick instead (every completion); remove the duplicate feed from applyUpdate to avoid double-counting track completions that fire both events. Extract completionsPerHour() as a pure, unit-tested function and lower the compute threshold from 3 to 2 samples. Verified live: 4 untracked completions now show per-hour=4225 (was 0).
…-2943 fix(display-app): correct number-words for Arabic, Hebrew, English, Mandarin
fix(display): kiosk live updates + per-hour — two root causes found by running the app
When client_payload.slugs contains N tutorials and all of them 404 on fetch, the guard step was passed the full slug list via PUBLISH_SLUGS but none of the tutorials rendered (fetch-tutorials skips them and exits 0). check-approuter-assets.cjs die()s with "no rendered page for slug(s):..." causing a false infra failure instead of a recoverable author warning. Root cause: Detect author source errors only checked client_payload.slug (singular). The multi-slug path (client_payload.slugs) was never filtered against errors.json, so all 5 unrendered slugs reached the guard. Fix: - Extend the detection step to also filter client_payload.slugs against errors.json, producing good_slugs (rendered) and bad_slugs (failed). - Guard, publish, and verify steps use good_slugs instead of the raw client_payload.slugs, so they only process slugs that actually rendered. - All three steps share a new skip condition that covers both the single-slug all-fail case (bad_slug != '') and the multi-slug all-fail case (good_slugs == '' && client_payload.slugs != ''). - Partial failures (some slugs render, some don't) proceed on the good slugs only, with ::warning annotations for the bad ones. Single-slug (#2384) path is unchanged — bad_slug/source_repo/issue-filing flow preserved exactly.
…arcode (#2952) The App Space track page loaded progress only once on mount, so a contestant who completed a tutorial had to do a full browser refresh to see the track update and unlock their prize barcode. The WebSocket realtime path fires confetti/toasts but never re-fetches progress or flips the barcode gate. Add a Refresh button in both the overview and track-detail headers that re-calls /api/getAppSpaceProgress, re-applies the payload, and reveals the checkpoint barcode in place. A refresh nonce cache-busts the barcode PNG so a newly-unlocked code is re-pulled, the open track is preserved across the refresh, and a "Progress updated" toast confirms the action.
…g-source-errors fix(ci): handle multi-slug source errors in QA rebuild (#2951)
…h-2952 feat(app-space): Refresh button to re-check completion & show barcode (#2952)
) - Add isIrrelevant : Boolean default false and irrelevantReason : String(500) to ims.TutorialFeedback entity in db/schema.cds - TutorialFeedbackAggregate: exclude flagged rows via where isIrrelevant is null or isIrrelevant = false - AuthorSurveyDistribution: extend all 7 UNION ALL legs with the same isIrrelevant exclusion predicate alongside existing null guards - Add isIrrelevant filtering describe block to tutorial-feedback-aggregate.test.js Note: CDS compiler v7 does not support IS NOT TRUE predicate; used (isIrrelevant is null or isIrrelevant = false) which is semantically equivalent and handles pre-migration NULL rows correctly.
1. TechEd fixture date-rot: sessions in teched-feed.json were dated 2026-10-27, now in the past — ?upcoming=true correctly filtered them out, breaking the endpoint and all-day tests. Bump dates to 2026-12-15 (actual TechEd Berlin date). Update matching test comments. 2. Task 11 duplicate describe block: reset-tutorial-progress.test.js had two Task 11 blocks — the first (lines 504-524) correctly unit-tests computeBuckets() directly. The second block tested getEventBuckets() via DisplayService expecting the old per-user histogram shape, which was replaced by computePathBuckets() track-bar grouping in commit 17a3035. The stale second block tested a contract that no longer exists and had no startDate/endDate on the fixture event, so computePathBuckets() exited early returning []. Remove it; the SUPERSEDED behavior is already covered by the first block.
…magpie feat(feedback): mark entries as irrelevant/inappropriate (#2947)
…ures fix(test): repair 3 CI unit test failures
When XSUAA session expires, every API call returns 401. Rather than displaying a cryptic "HTTP 401" or garbled barcode-parse error, detect the 401 in all three fetch paths (getContestant, getEventStats, claimPrizeForContestant + its CSRF-token probe) and call window.location.reload() — the AppRouter then redirects the unauthenticated request to the IDP login page.
…-redirect fix(scanner-vue): redirect to login on XSUAA session expiry (401)
…atibility CF nodejs_buildpack v1.9.6 rejects compound semver ranges (>=x.y.z <n) with "improper constraint" — it only accepts simple ranges like 22.x or exact versions. The >=22.23.4 <23 range (set in the CVE-2026-111497 fix) caused BuildpackCompileFailed on all three deployed modules during the 2026-11-01 DEV deploy. Exact pin 22.23.4 satisfies the CVE floor requirement and is accepted by the buildpack resolver. Updated: package.json, srv-qa/package.json, srv-mcp/package.json.
fix(staging): pin engines.node to exact 22.23.4 for CF buildpack compatibility
…h fails When CAP_BASE_URL is unreachable (e.g. tutorials-srv is stopped during a recovery deploy), fetch-advocates now reads from .tutorial-cache/advocates- roster.json instead of hard-failing. Only exits 1 if neither the live endpoint nor the cache is available. This unblocks deploys where the previously-deployed srv is down due to a prior staging failure — the exact scenario hit during the 2026-11-01 DEV recovery deploy after the CVE-2026-111497 engine pin broke staging.
fix(build): fall back to cached roster when fetch-advocates live fetch fails
Release the fixes + event-app improvements merged to DEV since 1.41.7: - #2961 pin engines.node to exact 22.23.4 so the CF buildpack stages cleanly (the >=22.23.4 <23 range was rejected as "improper constraint") - #2962 fetch-advocates falls back to cached roster when the live srv is down - #2949 raise Node runtime floor for CVE-2026-111497 (Brotli) - #2959 feat: flag tutorial feedback as irrelevant/inappropriate - #2957 feat: event-app Refresh button to re-check completion + show barcode - #2960/#2955/#2954/#2953/#2950/#2948/#2956/#2958 scanner, kiosk-display, number-words, app-space, Architecture Center, and CI fixes Bumps .deploy/mta.yaml 1.41.7 → 1.41.8 (the version in `cf mtas` and the mtar filename) and refreshes hugo/data/whats_new.json with the merged-PR digest for this window (15 entries). mta-mcp.yaml intentionally not bumped (no MCP MTA changes this release).
chore(release): bump MTA version to 1.41.8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promote DEV → main for the 1.41.8 production release.
The triggering change is the CF buildpack staging fix (#2961): the CVE-2026-111497 Node pin used a
>=22.23.4 <23range that the CF nodejs buildpack rejects as "improper constraint", which broketutorials-srvstaging on DEV. This release pins the exact runtime and adds a build-time cache fallback so a down srv can't deadlock a redeploy.Highlights
Fixes
engines.nodeto exact22.23.4(CF buildpack staging fix)fetch-advocatescache fallback when the live srv is unavailableFeatures
Deploy plan (after merge)
main(deploy-mta Step 0 refuses a worktree); blue-green, operator-gated swapChatSettings.enabledstaystruepost-deployTest plan
tutorials-srvstaged + smoke 342 passed / 0 failed)