Skip to content

Release runtime matrix

Detailed page. Use “On this page” to jump directly to the section you need.

This is the minimum release contract for Record Health Check. It applies to every package release, including patch builds. A missing, skipped, timed-out, inconclusive, or stale result is a failure. Static analysis and unit tests do not substitute for a live Salesforce result.

Scratch-org and package-version creation are scarce, owner-controlled release operations. Pull requests run no-org CI only. Salesforce workflows are dispatched manually, after known defects have been diagnosed without creating new orgs. A shared no-org preflight and blocking source analyzer must pass before source runtime jobs can create anything. Namespaced LWS runs before portable LWS, which runs before the one-at-a-time Locker matrix. Subscriber stages also run one org at a time and require exact-commit hosted source evidence. Queued matrix work stops on failure.

GitHub artifact uploads use a Node 24 action; project npm commands use the Node major pinned in config/toolchain.json. These are separate runtimes. Deprecated action runtimes must not be restored by enabling an insecure-runtime opt-out. Missing evidence remains a failure, not a warning to ignore.

The machine-readable dimensions are in config/release-runtime-matrix.json. The CI guard npm run check:release-runtime-matrix rejects missing dimensions, missing evidence files, weakened workflow wiring, or incomplete package-install verification.

The package version is major.minor.patch.build. Use the candidate and stable package IDs from the release configuration for the upgrade path. A package candidate is identified by its exact 04t version ID and Git commit SHA. Evidence from another build, branch head, pull-request merge commit, or package ID cannot satisfy a candidate’s gate.

StageRequired resultFailure behavior
Pull request and committed sourceEvery tracked check in .github/workflows/ci.yml passesDo not merge or call the source CI-ready
Optional hosted source validationWhen explicitly authorized, namespaced LWS and Locker jobs report additional evidence for the exact commitRecord failures without blocking package creation
Package creationCode coverage, artifact membership, version identity, and dependency checks passDo not publish a candidate for subscriber testing
Optional subscriber testingWhen explicitly authorized, clean installation and reviewed upgrades exercise the exact candidateRecord the result as additional evidence
Optional representative sandboxA reviewer may record exact-candidate acceptance of the affected customer experienceRetain the result as human evidence
PromotionLocal creation evidence and the Dev Hub package report identify the exact candidate and commitPromotion command must fail closed on an identity mismatch
Release publicationRelease registry, changelog, install links, tag, and rollback information identify the promoted 04tDo not announce the release

Package creation and promotion require a clean Git worktree and exact local creation evidence before invoking a Salesforce mutation. Hosted workflows are optional and require explicit scratch-org authorization. Every workflow artifact upload uses if-no-files-found: error; a successful test without its retained evidence is a failed release gate.

The exact-inventory runner requests global --json as well as JSON result files. Global JSON mode bypasses the Salesforce CLI’s styled console formatter, which can exhaust the Node heap on large per-test coverage payloads even when stdout is ignored. Preserve that flag when changing the runner. The checked-in inventory and command-exit guards are the executable fixtures for this repository-only reporting behavior; no Check or Check Set configuration is involved.

A passing result file does not turn an aborted CLI command into a successful invocation. Retain the failed command evidence, retrieve the same completed run with sf apex get test --json, and reconcile its class/method inventory and command exit. If Streaming API reporting stalls, retrieve ApexTestRunResult and ApexTestResult through the Tooling API and reconcile the actual class and method rows, including IsTestSetup; summary completion counters alone are not sufficient. Do not submit duplicate tests solely to recover a report.

Source validation uses the package’s real namespace in both supported Lightning security modes:

Namespace topologyLightning security modeBrowser engines
rhc namespacedLightning Web SecurityChromium and Firefox
rhc namespacedLightning LockerChromium and Firefox

Each org must be newly created from the tracked scratch definition. The workflow records the org shape, deploy result, test result, and browser artifacts. Reusing an org is not evidence for the hosted release gate. A no-namespace deployment of unpackaged source remains an optional contributor portability check; it is not another form of the released rhc package.

Every entry point must execute a Check Set containing all four evaluation types:

  • Formula
  • Query
  • Compare Two Queries
  • Apex

The required entry points are:

Entry pointRequired live proof
Lightning Web Component, manualComponent renders without a page-level or component spinner, Run completes, and all four types return results
Lightning Web Component, run on loadInitial shell remains quiet, deferred run completes, and no manual Run button is shown
Apex APIPublic Apex API returns all four evaluation types
FlowA real Flow interview invokes the packaged action and returns all four types
REST/MCPAuthenticated REST request and MCP contract return all four types through the namespaced package API
Native Agentforce actionsThe packaged Check Set action crosses the invocable boundary and accounts for every Check in the four-type set
Platform EventsALL publication emits one Check Result per executed Check and one Set Run event, and subscriber-owned triggers receive them
QueueableJob completes and its Check Set covers all four types
BatchJob completes and its Check Set covers all four types
ScheduledScheduled adapter launches the work, it completes, and its Check Set covers all four types

An Apex unit test that calls the shared service directly does not replace the Flow, REST, browser, or asynchronous adapter test. Every adapter must cross its real platform boundary.

Browser validation must reject uncaught JavaScript errors, Salesforce component error dialogs, the reported Invalid contextElement failure, incomplete runs, and persistent spinners. It covers:

  • a configured component in Lightning App Builder;
  • a component with no selected Check Set in App Builder;
  • a saved record page in normal view mode;
  • manual and run-on-load components on the same page;
  • initial load without a page-level loading overlay;
  • RefreshView registration and refresh execution;
  • record-to-record navigation without a full browser reload;
  • component disconnect/reconnect without stale handlers or duplicate work;
  • LWS and Locker with the package’s rhc namespace;
  • Chromium and Firefox;
  • administrator and restricted-user permission assignments;
  • post-install and post-upgrade rendering.

The builder canvas must remain inert: it may show configuration guidance, but it must not run a record check, show an operational spinner, register an invalid RefreshView context, or require a record ID. At runtime, the component renders its shell first and defers on-load work; it does not put a loading overlay on the record page.

The source automatic fixture is Release_On_Load, with exactly one Check of each type. Its seeded Account yields three passes and the expected recent-activity failure. The installed fixture is Subscriber_On_Load, with four expected passes. Both reject Unable and System Error results. The restricted browser user receives Card User, not the broader User permission set. Each browser/scenario run retains its own JSON verdict and evidence directory. Skipped, failed, and flaky/retry-recovered tests block the gate; later runs cannot overwrite earlier results.

The release runner redacts login URLs, session IDs, and generated passwords before retaining JSON and a readable HTML view. Raw traces, videos, and screenshots are disabled for this authentication- inclusive run to keep credentials out of uploaded artifacts. Unredacted reporter output stays in a temporary directory outside the upload paths and is removed when the browser process finishes.

The namespaced source org runs two explicit, reconciled inventories: package-only tests before fixtures, then the final package-plus-integration identity set after the harness is deployed. npm run test:apex:exact inventories every repository class with a real class-level @IsTest annotation, passes every discovered class explicitly to Salesforce, and reconciles the returned methods and class names against that inventory. A missing, unexpected, skipped, failing, or unreported class fails the gate.

The raw Salesforce result and reconciliation verdict are kept for 90 days as two artifacts: namespaced package and namespaced full. The 18 test identities intentionally overlaid by fixture-aware integration variants are pinned in config/apex-test-overlays.json; the package variant runs in the first phase and the integration variant runs in the second. Any new duplicate identity or missing side of an approved overlay fails before Salesforce is called. The gate includes:

  • CRUD, field-level security, sharing, and restricted-user behavior;
  • injection-resistant dynamic SOQL and merge-token validation;
  • bulk input and governor-limit behavior;
  • all public Apex entry points and invocable actions;
  • Queueable, Batch, Scheduled, REST, and platform-event behavior;
  • positive, negative, null, malformed, unauthorized, and partial-failure paths;
  • package namespace resolution, with optional no-namespace portability available to contributors;
  • blocking Code Analyzer AppExchange, Recommended:Security, and every Flow Scanner rule for package, integration, and subscriber-harness source, plus an all-rules advisory report;
  • exact package test coverage, with no coverage bypass.

The installed-package tests repeat the public API, Flow interview, four evaluation types, REST/MCP, Queueable, Batch, Scheduled, and LWC gates after both a clean installation and the upgrade. The matrix remains blocked unless the subscriber-owned Flow and its Apex interview test exist; an Apex-only substitute does not satisfy the Flow entry-point gate. Subscriber execution also discovers and reconciles every executable test class under subscriber-app/main/default/classes, including RHCSubscriberFlowSmokeTest; each selected stage retains a separate mandatory Apex artifact for each security mode.

Security is checked at source, deployed-source, clean-install, and upgrade boundaries. A scanner result is not accepted if its engine logs contain a processing exception, even when the scanner returns exit code zero and reports zero violations.

  • Runtime service and adapter classes declare with sharing; packaged invocable classes, methods, request types, response types, and variables are global so the exact subscriber-namespace boundary is compiled and exercised rather than assumed.
  • Every execution surface requires the packaged Run custom permission. Restricted-user tests must prove denial through the Apex API, Flow action, REST/MCP adapter, Agentforce action, Queueable, Batch, and Scheduled submission, with no record-health detail in the denial response.
  • Customer-record queries use WITH USER_MODE or AccessLevel.USER_MODE, Schema-derived object and field identifiers, and bind variables. Admin-authored query templates cannot request WITH SYSTEM_MODE, add executable syntax through merge tokens, or access an undisclosed field.
  • Exactly five reviewed system-mode operations are pinned by check:apex-surface: one direct packaged-permission assignment query in RecordHealthCheckAccess, one Custom Metadata definition query in RecordHealthCheckScopePlanner, and two bounded queries plus one bounded delete for private readiness evidence in RecordHealthCheckReadinessService. None reads or changes customer business records. Any additional or relocated SYSTEM_MODE use requires a reviewed source-policy change, an exact-count gate update, and new restricted-user and package-build evidence.
  • Formula, relationship, currency, polymorphic, aggregate, grouped, dual-query, and plugin paths enforce object access, field access, sharing, type compatibility, bounded scope, query-row, query, CPU, heap, serialization, and response-size ceilings. Tests cover bulk, null, malformed, inaccessible, partial-failure, and exception paths.
  • The package does not grant object or field access to customer business objects. The executing user’s permissions remain in control, and subscriber plugin code runs in its declared sharing context.
  • Shipped LWC source is checked by Salesforce’s LWC lint rules, the Locker security rules, the release compatibility scanner, ESLint Recommended, RetireJS Recommended, Jest, SLDS 1/2 linting, and real browsers in both Lightning Web Security and Lightning Locker.
  • Shipped code cannot use page-owned document DOM, innerHTML, outerHTML, shadowRoot, dynamic code evaluation, browser storage, worker escape APIs, Aura globals, manual DOM, or executable URL schemes. Guided-action URLs accept only an in-app absolute path or explicit HTTPS URL.
  • RefreshView must retain both supported registration protocols: the LWS component form first and the Locker host-plus-bound-handler fallback. Registration failure is fail-open for rendering, and disconnect unregisters the accepted handler.
  • Initial configuration and run-on-load work is deferred until after the shell renders. No component spinner or page-level loading overlay is permitted on initial load, in App Builder, or during automatic execution. Progress after a deliberate user click stays inside the clicked action control.
  • A configured App Builder preview makes one lightweight shell request so it can identify the selected Check Set and show active/inactive counts. An unconfigured preview remains server-inert. Neither preview loads definitions, evaluates a Check, accesses sample-record data, or renders a runtime action.
  • Browser tests fail on any uncaught page error, Salesforce component-error dialog, incomplete result count, persistent spinner, duplicate automatic run, stale handler, full reload during record navigation, or the reported Invalid contextElement signature.

REST, MCP, Agentforce, Flow, async, and events

Section titled “REST, MCP, Agentforce, Flow, async, and events”
  • REST accepts only authenticated callers with the Run custom permission, JSON content type, a bounded request body, an approved operation, one syntactically valid record ID, exact qualified metadata identity, and a bounded safe correlation ID. It returns versioned, redacted validation, authorization, limit, or execution envelopes rather than raw exceptions.
  • MCP and Agentforce inputs use the same exact qualified identity contract. Agentforce/MCP-backed invocable methods are global, run as the authenticated user, use sharing, and return aligned, bounded output. Flow tests must use a real Flow interview; a direct Apex call is supplemental.
  • Queueable, Batch, and Scheduled adapters recheck authorization at both submission and execution boundaries, defensively copy and bound explicit record populations, and publish no event unless the caller requests an allowed publication mode. Their release tests capture every result event, resolve each event’s exact Check identity back to Custom Metadata, and require the resulting set to contain APEX, COMPARE_TWO_QUERIES, FORMULA, and QUERY; job completion or event counts alone are insufficient evidence.
  • Platform Events contain stable IDs, counts, status, reason code, source, and record identity but no raw exception or restricted diagnostic detail. Publication is chunked, publish failures are inspected, subscriber triggers are exercised, and recursion is suppressed.
  • The blocking Apex/XML profile runs Salesforce Code Analyzer’s AppExchange, Recommended:Security, and flow:all selectors. Shipped JavaScript runs eslint:Recommended and retire-js:Recommended; the all-rules reports remain retained advisory evidence.
  • Analyzer JSON must be complete and every analyzer log must be free of engine processing errors and null-pointer failures. This prevents a scanner crash from becoming a false green release result.
  • code-analyzer.yml has an exact approved list of five file-scoped ProtectSensitiveData false positives. Each permits one finding and carries a specific reason. A new path, a second finding, a widened limit, or globally disabling that security rule fails CI and release preflight.
  • Inline Apex suppressions remain visible beside the guarded statement and are reviewed with the code. Hosted reports, scanner versions, configurations, logs, and HTML/JSON results are retained for 90 days against the exact commit.

Each upgrade org starts with the exact reviewed release declared in upgradeBases. Before upgrading, the workflow creates subscriber-owned Check Sets and Checks and records their identities and values. It then:

  1. deploys only the subscriber-owned preservation fixture and proves the stable package global Apex API can execute it;
  2. installs the exact candidate package using the tracked upgrade mode;
  3. verifies the installed package version ID;
  4. proves the subscriber-owned metadata is unchanged;
  5. reassigns and verifies permissions;
  6. deploys the candidate-only subscriber harness, then runs Apex, asynchronous, REST/MCP, Flow, Agentforce, Platform Event, App Builder, restricted-user, and browser gates under both LWS and Locker;
  7. retains install requests, test output, sanitized browser reports, and the exact before/after Custom Metadata preservation snapshot for 90 days.

A clean install cannot satisfy the upgrade gate. An upgrade that succeeds but loses configuration or fails an entry point is a failed release.

The optional subscriber workflow offers only the stages declared by expectedStages. Each authorized stage creates two fresh orgs (LWS and Locker). Daily quotas may require the staged plan in the scratch org lifecycle. Shared workflow concurrency prevents release workflows from overlapping but does not reserve Dev Hub quota.

The five representative-sandbox scenarios in the manual release-owner checklist remain available for optional human review. The guarded promotion command does not require that attestation.

Supply-chain, metadata, and documentation gates

Section titled “Supply-chain, metadata, and documentation gates”

The release also requires:

  • pinned Node, Salesforce CLI, Java, Python, and Code Analyzer policy versions;
  • separate audits of the root and MCP service lockfiles: production dependencies fail on any known vulnerability, and the complete dependency trees fail on moderate or higher severity. Run npm run check:dependency-security to audit both. The patched @babel/core transitive override is lockfile-pinned and must remain compatible with the Salesforce LWC compiler and Jest suite;
  • package-boundary, manifest, converted-artifact, permission, namespace-token, API-surface, query, field-limit, XML, formatting, lint, SLDS, JavaScript, and documentation checks;
  • every intended Custom Metadata record in both the manifest and physical package artifact;
  • permanent regression tests for every escaped defect;
  • release notes that describe user-visible behavior, upgrade impact, and rollback steps;
  • retained evidence tied to the exact commit and 04t candidate.

For an explicitly authorized optional workflow, missing credentials, unavailable scratch capacity, and test failures must remain visible failures. They do not block package creation or promotion.

Evidence belongs in hosted workflow logs and retained artifacts for the exact source revision. Record deploy IDs, Apex run IDs, org shape, security mode, sanitized browser reports, package install request IDs, before/after metadata snapshots, candidate ID, and workflow URL.

The hosted checker verifies successful named jobs and nonempty, unexpired artifacts created in the current attempt, not merely the overall workflow conclusion. Artifact presence is not an independent content audit: the test runners must validate their results before publishing evidence.

There is no informal release exception. Reducing supported scope or waiving a gate requires a reviewed source change to this contract and the machine-readable matrix before a candidate exists; it must not be done to make a failing candidate pass.