Release 1.31.3 — Semaphore taxonomy auto-sync (DEV→main promotion) - #2492
Merged
Merged
Conversation
…e) + fix mislog
Rework the semaphore-tag-sync applier so a weekly run adopts the existing
tag corpus without importing all ~20k SES terms, and picks up genuinely
new tags only under an explicit class allowlist.
Tier 1 (adopt-only): match each SES term by semaphoreId, then by name.
Backfill taxonomy fields (label/name/titlePath/semaphoreId) in place when
they differ; NEVER overwrite editorial flags (isActualTag/isInterestItem).
Tier 2 (gated intake): INSERT an unmatched term only when its SES class is
in semaphore.sync.intakeClasses (case-insensitive, URI-leaf tolerant).
New rows land inert (flags forced false), awaiting editor curation. Empty
allowlist = intake OFF (adopt-only), the safe default.
Dry-run summary now carries a pre-formatted classHistogram string so the
real SES class distribution can be read from an in-app dry run and used to
choose semaphore.sync.filter / intakeClasses from data. dryRun defaults TRUE.
Also fixes a scheduler mislog: a job fn RETURNING { ok:false } (rather than
throwing) was recorded as SUCCESS. The chassis now inspects the return value,
logs a FAILED PipelineLog row, records JobLastRun.lastErrorAt, and raises an
alert. Covered by new admin-job-controls tests.
Config keys (all ImsConfig, DB-driven -- no env vars):
semaphore.sync.intakeClasses (new), .dryRun, .filter, .model, .lang,
.actualTagClasses, .interestItemClasses
Refs #2184, #2478
…er-sync feat(semaphore-sync): two-tier tag sync + scheduler mislog fix
The scheduler only branched on a thrown exception; a runner that RETURNS
{ ok:false, error } (a soft failure, e.g. semaphore-tag-sync's fail-shut
fetch/mapping path) fell through to the SUCCESS path — logging green in
PipelineLog and JobLastRun and masking a silent no-op.
runWithLock now inspects fn(logId)'s return value: an object with
`ok === false` is recorded as outcome `error` via
logPipelineEnd(logId, 'FAILED', summary, errorMessage) with the error in
the errorDetails column (arg 4), a failed JobLastRun, and a
ScheduledJobFailed alert. errorMessage derives from result.error, else
"<jobName> returned ok:false". Thrown exceptions fail as before; {ok:true}
and plain-summary returns still succeed.
Covered by 5 new cases in run-job-by-name-opts.test.js asserting on the
actual PipelineLog/JobLastRun rows.
Ref: #2184
…duler-soft-fail # Conflicts: # srv/jobs/scheduler.js
…er-soft-fail fix(scheduler): record FAILED when a job returns ok:false (#2478)
Expose the semaphore.sync.* tuning keys in the Admin UI so operators can configure the taxonomy-sync job without hand-editing ImsConfig rows. - Shared descriptor srv/lib/semaphore-sync/config-keys.js is the single source of truth for the 7 keys (model, lang, filter, actualTagClasses, interestItemClasses, intakeClasses, dryRun): their defaults, value types, and help text. The sync job's readConfig now imports the key list from it. - AdminService.SemaphoreConfig: a @cds.persistence.skip viewer (modeled on FeatureFlags) synthesizing one row per key, layering the live ImsConfig value over the default. Bound setValue(value)/clearValue() actions upsert or delete the raw row; both allowlisted to semaphore.sync.* (exact match). - New Fiori Elements app app/admin/semaphoreConfig (auto-discovered by the admin-shell component copier) + shell manifest wiring + nav entry. - intakeClasses is surfaced + read for forward-compat but NOT yet consumed by the mapper/applier — intake enforcement is a separate feature (#2477 scopes to surfacing only; 'No behavior change to readConfig'). Tests: 7 new (READ default synthesis, string/csv/bool upsert, clearValue reset, non-allowlisted 400, unauth 401). Job + admin-shell/bundle/registry regression suites green.
…hore-config-panel feat(admin): Semaphore sync config panel (#2477)
Explains the org-wide OSPO branch-protection ruleset (no direct pushes to the default branch, PR + >=1 approval required) with concepts (branch/fork/PR), the exact enforced rules, and step-by-step CLI and web-UI instructions for both write-access and fork-based contributors. Registers the page in the VitePress authors sidebar and cross-links it from the authors README and writing-tutorials.md (workflow, quick edits, known-gaps).
PR #2484 added the Semaphore Config panel with a manifest route and a navigation.json entry, but never registered semaphoreConfig in NAV_KEY_TO_ROUTE / NAV_KEY_TO_TITLE. The sidebar click therefore silently no-ops. The cross-file consistency guard in admin-shell-pats-nav.test.ts caught this and is now red on DEV. Add semaphoreConfig to both maps so the sidebar entry routes and titles correctly.
…ch-protection docs(authors): add branch protection & pull request guide
…fig-nav-route fix(admin): route semaphoreConfig nav-key (#2477)
Fixes the docs:build failure: challenge-widget-cost-sizing.md was added to docs/developers/reference in #2441 without a sidebar entry, so the predocs:build guard (check-docs-sidebar.cjs) exits 1. Adds the missing entry, alphabetically after CAP / CDS gotchas.
…llenge-widget docs: register challenge-widget-cost-sizing in sidebar (fix docs build)
The applier writes via cds.db directly, bypassing AdminService's before(CREATE) hook that auto-assigns legacyId. New synced tags landed with a NULL legacyId (the Admin UI 'ID' column showed blank). Assign it from the Tags HANA sequence via getNextLegacyId on each intake INSERT, guarded so dryRun never burns a sequence value. Existing 119 null-legacyId tags on DEV backfilled separately.
…yrun fix(semaphore-sync): assign legacyId on Tier-2 tag inserts (#2479)
chore(release): 1.31.3
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.31.3 — DEV → main promotion
Promotes today's Semaphore taxonomy-sync work from DEV to main for a PROD deploy. Version bumped to 1.31.3 in
.deploy/mta.yaml(#2491).Shipped
Semaphore taxonomy auto-sync (#2184 / #2477 / #2478 / #2479)
feat(semaphore-sync): two-tier tag sync — Tier-1 adopts existing curated tags by semaphoreId/name (taxonomy fields only, never editorial flags); Tier-2 intakes genuinely-new terms gated by a class allowlist, inserted inert. Weekly cron (Sun 04:47 UTC), fail-shut. (feat(semaphore-sync): two-tier tag sync + scheduler mislog fix #2480)feat(admin): Semaphore sync config panel in the Admin UI (Admin UI config backfill for semaphore sync #2477)fix(admin): route semaphoreConfig nav-key in Shell controller (Admin UI config backfill for semaphore sync #2477)fix(semaphore-sync): assign legacyId on Tier-2 tag inserts — the applier bypasses AdminService's before(CREATE) hook, so new tags had NULL legacyId (the Admin UI "ID" column); now assigned from the Tags sequence, dryRun-guarded (Finish semaphore-tag-sync two-tier rollout (prod config, dry-run validate, flip live) #2479)fix(scheduler): record FAILED when a job returns ok:false (Scheduler logs SUCCESS when a job returns ok:false (soft failure) #2478)Docs
Verified on DEV
PROD rollout notes (post-merge, NOT in this PR)
flag.semaphore.sync,semaphore.sync.intakeClasses,semaphore.sync.dryRunon the PROD instance after deploy; validate with a dry-run before flipping live.semaphore.sync.*config is clean before enabling (a stray intakeClasses value existed on PROD earlier)./topics/leaf-slug smoke check flags on DEV (pre-existing content-publish state, not caused by this release).