Repository navigation
Release 1.43.0: DEV to main promotion - #3044
Merged
Merged
Conversation
…not ON (#2909/#2993) The Top Gotchas entry described draft_admin_integrity as ON with DB-level cascade delete. That's stale: #2909 disabled the flag for all profiles after it caused the 2026-11-02 PROD outage (flag on + no cascade constraints → orphaned drafts → un-editable missions), and #3003 removed the constraint migration. Rewrite to reflect reality: flag OFF, pre-10.2 delete hooks in use, real table names (ADMINSERVICE_*_DRAFTS), the orphan-sweep script, and that re-enabling the dad strategy is blocked on the unresolved HDI make-graph problem (#2993). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…urls (#757 regression) fix-archcenter-urls.cjs called cds.entities() after cds.connect.to('db') with no cds.load(), tripping the #757 guard and failing the unit suite. Under 'cds bind --exec' this throws 'cds.entities is not a function' at runtime. Prime via cds.linked(await cds.load('*')) before connect and resolve the namespace off the linked model, mirroring backfill-categories.cjs.
…hcenter fix(script): prime CDS model before cds.entities() in fix-archcenter-urls (#757 regression)
…ix nudge (#2998) The concept re-render delta phase keyed its digest on *ConceptLinks tables (incl. HelpDocConceptLinks) but not on HelpDocs itself. The archcenter <a href> is read live from HelpDocs.url at publish time, so a bare HelpDocs.url/title change never bumped the digest -> concept pages phase-skipped and the corrected URL never re-baked into the served BLOB. - Add a HelpDocs probe (max(modifiedAt)+count(*)) to computeConceptInputDigest. - Retire the manual HelpDocConceptLinks 'digest nudge' workaround in scripts/fix-archcenter-urls.cjs — the HelpDocs.url UPDATE now bumps the digest directly via managed modifiedAt. - Add a unit test proving a HelpDocs-only probe change moves the digest.
…elpdocs fix(concepts): observe HelpDocs in concept-input-digest (#2998)
…torials (#3007) Track 'average time to complete' summed every tutorial across all segments, double-counting branching (fork / parallel-any) paths — a two-lane fork reported the combined time of both branches. Extract trackTotalTime into app-space-time.ts: linear segments sum as-is, fork segments average their per-lane totals, parallel-any clusters average their per-tutorial times (sum of optional paths / number of paths). Legacy flat items[] payloads still sum.
…bined-branches test Code-review follow-up: removing [key: string]: unknown from TimeItem makes AppSpaceTrack cleanly assignable to TimeTrack (fixes a tsc TS2345 at the trackTotalTime call site). Add a test covering multiple branch segments in one track (linear + fork + parallel-any).
…ng-3007 fix(app-space): average branching-path time instead of summing all tutorials (#3007)
…ag (#3011) community.sap.com's Cloudflare bot management now 403-challenges the Khoros LiQL API path (/api/2.0/search) that the default 'khoros' transport relies on, breaking community-blogs-fetch in PROD (all 3 sources errored, fetched=0) and degrading homepage RSS silently. The raw /rss/ feeds remain open, and the curl transport (TLS-fingerprint bypass) still reaches them. Previously the only switch was the RSS_TRANSPORT env var, which reverts on any redeploy that doesn't re-set it. Move the khoros-vs-curl choice into the feature-flags registry as COMMUNITY_RSS_USE_CURL (kind:'db', ImsConfig key flag.community.rss.useCurl, default true -> curl) so operators can flip it from the Admin UI Feature Flag viewer and it survives deploys. - New shared srv/lib/rss-transport-mode.js rssMode(): env RSS_TRANSPORT wins when set (operator override + test seam; 'fetch' stays test-only), else the DB flag. Replaces the two drifted copies in the fetchers. - Covers both community-blogs-fetcher and homepage-rss-fetcher. - Default curl because the khoros path is currently dead. Verified in PROD: after cf set-env RSS_TRANSPORT curl + restart, the next fetch ran fetched=60 inserted=10 updated=47 errored=0. Refs #3011
…ansport-flag feat(community): admin-toggleable RSS transport feature flag (fixes Khoros 403 outage) (#3011)
…json-reject fallback test (#3009)
…ate-test determinism (#3009) C1: Add player-driven movement in renderer.ts (ArrowRight/ArrowUp/Space keyboard; pointer-right-half=run, pointer-left-half=tap=jump). attach/detachPlayerInput called by setPlayerControl so listeners are always cleaned up in stop(). Add [data-game-close] button + Escape key handler in AppSpaceGame.vue so the player can always exit the overlay (closeGame: hide overlay, game.stop(), restart idle timer, no URL change). C2: Add appSpaceGameEnabled:Boolean to getAppSpaceProgress return type in CDS. Import isFlagEnabled from ./lib/feature-flags/db-flags.js in developer-service.js; read APP_SPACE_GAME_ENABLED flag (default OFF, ImsConfig-backed) inside a try/catch->false wrapper and return it on the payload. Remove the isGameEnabled() reachability probe from feature.ts; AppSpaceGame.vue gates on data.appSpaceGameEnabled===true instead. Eliminates extra heavy query. M2: Add dispose() to GameHandle interface and implementation; call game?.dispose?.() in onUnmounted to free WebGL contexts + geometries/materials. M3: Add TextureLoader onError callback for Kasimir texture (silent console.warn, no throw, scene already survives missing texture). Tests: remove 3 isGameEnabled probe tests (function removed); add tests for flag-OFF gate, close button, and Escape key. 37/37 pass on Node 22.23.1.
…esign feat: Kasimir Arcade attract-mode game for App-Space (#3009)
The GitHub Pages build (predocs:build -> check-docs-sidebar.cjs) fails because docs/developers/operations/draft-integrity-reenable.md exists on disk but is not registered in the VitePress sidebar. Add the entry.
fix(docs): register draft-integrity-reenable runbook in sidebar
…0px off-page) The App-Space game island mounts into an empty, zero-height <div id="app-space-game"> placed after the grid in the Hugo layout. The canvas used position:relative and the Demo trigger position:absolute, so both laid out in normal flow ~1740px down the page (below the fold) while the attract overlay (position:fixed, 92% opaque) covered the viewport. Net effect: the renderer drew correctly (1830 draw calls/s, valid level model, healthy WebGL2 context, all verified live) but onto a canvas nobody could see, and the manual Demo trigger was unreachable. Fixes: - Canvas to position:fixed, inset:0, 100vw/100vh so it anchors to the viewport over the overlay dim while attract mode is active (the actual "nothing renders" bug). - Demo trigger to position:fixed bottom-right (was absolute, landing at y~1748). - startAttract() awaits nextTick before game.start() so the fixed canvas is laid out at its real size before the initial resizeToCanvas() bakes the camera aspect (prevents a stretched first frame). - Add a window resize listener (armed in start(), removed in stop()/dispose()) so the full-viewport canvas keeps a correct aspect when the window resizes mid-attract. Verified live on DEV: applying the fixed canvas CSS made Kasimir, coins, pillars and the track flag render immediately; Demo button confirmed visible bottom-right. Note: the app-space-game unit suite was already red on origin/DEV (VTU "ref on hoisted vnodes" happy-dom issue, unrelated to this change).
…een-canvas fix(app-space-game): render Kasimir arcade on-screen (canvas was ~1740px off-page)
… snippetKey→slug map
…ntry
- Add scripts/vendor-asciinema.mjs: ESM download script for asciinema-player
v3.18.0 JS + CSS from GitHub releases; idempotent via versioned sentinel
file (.asciinema-vendored-3.18.0); guarded against test import side-effects
via process.argv[1] check
- Add scripts/__tests__/vendor-asciinema.test.mjs: offline unit tests using
vi.stubGlobal + vi.spyOn(fs); two cases: non-ok fetch exits 1, sentinel
present skips download; fixed vi.stubGlobal return-value quirk by capturing
mock fn before passing to stubGlobal (documented in test comment)
- Update vitest.config.ts: extend unit include patterns from {js,ts} to
{js,mjs,ts} so .mjs test files are picked up
- Update package.json: add vendor:asciinema script; prepend to build:apps;
append to setup
- Update REUSE.toml: add Apache-2.0 annotation for asciinema-player.css
…ro; exclude unknown emails from SAP split
…sk 3) Adds rewriteSnippetImages() to include.ts which rewrites relative image paths inside snippet markdown to absolute GitHub raw URLs pointing to the snippet's own repo/branch, not the including tutorial's. - shared/<name> snippets → tutorial-snippets/main - <repo>/_snippets/<name> snippets → <repo>/main - Absolute URLs and parent-relative (../) paths are left untouched - snippetRepoMap in ExpandDirectivesContext allows explicit override
…pipeline - Imports fetchSnippets from github.ts in fetch-tutorials.ts - Adds snippet pre-fetch block after help-titles (gated by SNIPPETS_ENABLED_REPOS) - Passes real snippetMap to every composeTutorial() call (replaces new Map() stub) - buildSnippetDeps now receives real snippetMap + disk-cached rawMd per slug - Removes TODO comments for Task 6/8; all fetch-tutorials.ts stubs are now wired - Adds backward-compat integration test (empty snippetMap = byte-identical runs)
…th include source context When expandDirectives() throws inside a snippet's content, the error message is now augmented with: "<original message> (included from <tutorialSlug>:<line> via <snippetKey>)" Avoids double-wrapping when the message already contains "included from". Also adds gate regression tests confirming: - empty snippetMap → directive/include-not-found (behavior unchanged for non-opted-in repos) - tutorials with no ::include are unaffected (no error, identical output)
…or:asciinema into build:apps
… undefined local var The token variable in main() scope was undefined at runtime (it's only defined inside fetchMarkdown()). fetchSnippets() uses the token for GitHub auth headers, so passing undefined would skip auth and fail on private repos' _snippets/ dirs. Use process.env.GITHUB_TOKEN ?? process.env.TUTORIALS_GITHUB_TOKEN directly at the call site (stored as snippetToken) to avoid the scope issue.
…ude regex Three bugs found in code review: 1. CRITICAL: fetchSnippets() stored shared snippets as 'shared/cf-cli.md' but resolveSnippetKey() normalizes ::include[shared:cf-cli] to 'shared/cf-cli' (no extension). Every shared snippet include threw directive/include-not-found. Fix: strip .md from the key when building shared/ keys. Per-repo keys keep .md since ::include[step.md] labels include the extension and suffix-match works. 2. MEDIUM: Same mismatch caused buildSnippetDeps to emit 'shared/cf-cli' keys while the rebuild workflow would compare against 'tutorial-snippets/...cf-cli.md' paths — shared-snippet changes never triggered targeted rebuilds. Fix: same as above (key consistency). 3. LOW: INCLUDE_RE in buildSnippetDeps used /:?:include/ matching one-colon :include[x] (not valid directive syntax) and producing false-positive dep entries. Fix: /::include/ (require two colons, matching actual leaf directive syntax). Also updates tests: - github-snippets.test.ts: assert 'shared/cf-cli' (not 'shared/cf-cli.md') - github-snippet-deps.test.ts: add comment clarifying key convention; add test confirming :include (single colon) is not matched - include-images.test.ts: shared snippet test uses 'shared/setup' key + label (no .md extension), matching the actual fetchSnippets output convention
…ds bind --exec context
chore(tutorials): CLI-deprecation rules + promotion lint + OS-fallback doc fix + MCP slicer import fix
feat(code-block): {diff} fence attribute for unified-diff blocks (code-block Task 2.3)
feat(content-reuse): wire ::include snippet pre-fetch + dependency manifest (content-reuse Task 6/8)
…ath regardless of sentinel state
…nes it (#3029 regression)
…p-pattern summary, %-through, org-domain rollup, engagement callout
…arsers-bundle fix(mcp-slicer): static-import renderDirectivesAsText — unblock DEV unit-tests bundle step
feat(rich-media): asciinema player for ::cast recordings (rich-media Task 4.1/4.2)
…report-skill feat: event-app-space-report skill (per-event completion report)
1. hugo/layouts/shortcodes/tut-menu.html: `contains` is not a Hugo function; the operands are strings → use `strings.Contains`. The bad token broke the Hugo build (exit 1), cascading to 4 hugo-homepage-partials failures (#8c2028daa). 2. package.json prebuild:parsers-bundle: align esbuild banner with the aliased `createRequire as __cjsBundleRequire` convention already used by bundle-shared.cjs. The bare `createRequire` collided with esbuild-emitted createRequire imports (from directives/ui.ts + reference-links.ts), throwing SyntaxError at module-load for 5 srv-qa test files. 3. Update 3 stale test assertions to match the intentional callout refactor (#18e713de5, #71a8d70bc): alerts now render as <aside>/<details> via the tut-alert partial and the CSS sibling rule broadened to `~ :is(blockquote, aside, details)`. Tests, not source, were behind.
The full-tree safe-HTML lint flagged 11 occurrences in hugo/layouts: - 2 real safeHTML pipes missing a security-reviewed: marker (render-codeblock.html diff-rejoin branch, option-tabs.html panel emit) - 9 false positives: prose comments containing the literal "safeHTML" token, which the line-level regex matches Add security-reviewed: justifications to the two real calls (both assemble HTML only from Goldmark-escaped input + constant scaffolding) and reword the prose comments to drop the literal token. No behavioral change.
…akages fix(ci): repair 3 pre-existing DEV unit-test breakages
fix(hugo): satisfy check-hugo-safe-html gate (#797)
…eak test
Follow-up after the first round fixed B/C/E but left A and D red.
A (5 srv-qa suites, 'Cannot find module ./icon-allowlist.json'):
directives/ui.ts and reference-links.ts loaded icon-allowlist.json /
api-libs.json via createRequire('./x.json') at runtime, but neither
parsers bundle (srv-qa/lib + srv/lib/_shared, both built from
scripts/parsers/*) ships the JSON beside the .mjs, so the runtime require
fails. Switch to static default JSON imports (tsconfig has
resolveJsonModule) — esbuild/vite/tsx all inline the JSON into the bundle,
removing the sidecar-file dependency for BOTH bundles and also removing the
createRequire imports that caused the earlier banner collision.
D (option-tail-leak.test.ts, 'Hugo build failed exit 1'):
render-blockquote.html now delegates alerts to the tut-alert
partial (#2595/#71a8d70bc), but the test's temp Hugo site never copied
tut-alert.html, so was unresolvable and the
build died. Copy tut-alert.html into the temp layouts/partials/ dir.
Verified by reproducing the real Hugo pipeline: build now exits 0 and
renders exactly 2 <aside class="alert alert-tip">.
…-and-alert-partial fix(ci): inline parser JSON assets + copy tut-alert partial in option-tail-leak test
Bumps .deploy/mta.yaml 1.42.0 -> 1.43.0 and refreshes hugo/data/whats_new.json (+56 entries) for the PRs merged to DEV since 1.42.0. Highlights since 1.42.0: - Tutorial directive-grammar authoring system (directive grammar foundation, callout/code-block enhancements, rich media + asciinema ::cast, synced OPTION tabs, ::include content reuse + smart references, UI instruction directives, per-step time/optional + interactive checklists) - Kasimir Arcade attract-mode game for the event App-Space page - Admin-toggleable RSS transport feature flag (fixes Khoros community-feed outage) - Scheduler + /health/ready deploy-reliability hardening (blue-green readiness gate, cds.flush() self-heal, singleton outbox row fix) - draft_admin_integrity remains OFF (reverted after the 1.42.0 incident)
release 1.43.0 prep: version bump + whats-new refresh
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.
Release 1.43.0 — DEV → main promotion
Promotes the accumulated DEV work to
mainfor the production deploy of release 1.43.0.What's shipping
Tutorial authoring — directive grammar system (new generic directive grammar + callouts, code-block/
{diff}, rich media + asciinema::cast, synced OPTION tabs,::includecontent reuse & smart references, UI instruction directives, per-step pacing + interactive checklists).Features — admin-toggleable RSS transport (fixes Khoros community-feed outage); Kasimir Arcade attract-mode game for event App-Space; per-event completion-report skill; mission completion-path ordering.
Deploy reliability —
/health/readyblue-green readiness gate; schedulercds.flush()self-heal + singleton-outbox fix; draft-orphan cleanup ops script.Full developer-facing list on
/whats-new/(refreshed in #3043).cds.fiori.draft_admin_integrityis OFF in this release (reverted after the 1.42.0 incident). No pre-deploy HANA cascade-constraint step required.Post-merge
Merging to
maindoes not redeploy CF — the MTA deploy is a separate manual step. Deploy from a freshorigin/mainonce this lands (confirm scope +cf targetfirst).Pre-merge checklist
cf targetconfirms intended space before any subsequent deploy