Release Orchestrator events consumed by Scanner
Source verified against commit
163f35a2ceon 2026-10-03. This verification covers the configuration, owner contract and consumer behavior described here. Re-verify with the source commands below. It does not establish deployment to an installation or completion of a full scan.
Scanner Worker can consume two Release Orchestrator event streams:
| Kind | Owner event | Scanner effect |
|---|---|---|
scm-info | ComponentVersionScmInfoAvailable | Creates or reuses a deterministic source-backed scan and queues its repository and commit metadata. |
build-context | BuildContextReachabilityAvailable | Passes the supplied reachability graph to Scanner’s OCI referrer coordinator. |
Both bridges are disabled by default. Enabling one requires an explicit owner URL, tenant allowlist and Authority client configuration. Only the listed tenants are polled; there is no implicit default or system tenant. This guide describes the source contract; deployment and successful event processing must be verified for each installation.
Configure the consumer
The following keys belong to Scanner:Worker in the Worker’s configuration. Environment variables use double underscores between path segments, for example Scanner__Worker__ScmInfoAvailableTrigger__Enabled.
Key below Scanner:Worker | Default | Requirement |
|---|---|---|
ScmInfoAvailableTrigger:Enabled | false | Enable to consume SCM events. |
BuildContextReachabilityTrigger:Enabled | false | Enable to consume build-context events. |
ReleaseOrchestratorEvents:BaseAddress | Unset | Absolute HTTP(S) owner URL without credentials, query or fragment; use the installation’s trusted service endpoint. |
ReleaseOrchestratorEvents:TenantIds | Empty | Nonempty, distinct allowlist when either bridge is enabled. Tenant identifiers are normalized to lowercase and may contain ASCII letters, digits, hyphens and underscores, up to 128 characters. |
ReleaseOrchestratorEvents:LeaseTtl | 00:02:00 | At least three seconds; the Worker renews its local processing lease while handling a partition. |
ReleaseOrchestratorEvents:HttpTimeout | 00:00:30 | Positive timeout for owner HTTP requests. |
ScmInfoAvailableTrigger:PollInterval, BuildContextReachabilityTrigger:PollInterval | 00:00:15 | Positive poll intervals. |
ScmInfoAvailableTrigger:BatchSize, BuildContextReachabilityTrigger:BatchSize | 50 | From 1 to 500 events per partition and poll. |
Authority:Enabled | false | Must be true. |
Authority:ClientId, Authority:ClientSecret | Unset | Use a provisioned confidential client and the existing runtime secret mechanism. |
Authority:Scopes | Includes scanner:scan | Include release:read alongside the scopes required by the Worker’s other functions. |
Configure the existing Authority issuer/token endpoint settings for the installation. The client must be permitted to obtain release:read tokens for every listed tenant. The bridge requests a token separately for the requested tenant; an unavailable token does not fall back to an anonymous request.
On Release Orchestrator, ReleaseOrchestrator:ScannerEvents:ConsumerClientId identifies the client allowed to register and report Scanner progress. Its default is stellaops-scanner-worker; it must match the Worker’s provisioned client ID. Ordinary release readers cannot report progress on the Worker’s behalf.
Owner HTTP contract
The scoped OpenAPI specification and generated API reference cover these four operations. Their capture provenance and isolated runtime proof limits are recorded in the API changelog.
The two literal route partitions are scm-info and build-context:
| Method and route | Purpose |
|---|---|
GET /internal/v1/release-orchestrator/scanner-events/scm-info/events | Read retained SCM events. |
GET /internal/v1/release-orchestrator/scanner-events/build-context/events | Read retained build-context events. |
POST /internal/v1/release-orchestrator/scanner-events/scm-info/consumer-checkpoint | Register or report the SCM consumer’s durable position. |
POST /internal/v1/release-orchestrator/scanner-events/build-context/consumer-checkpoint | Register or report the build-context consumer’s durable position. |
All routes require release:read and an authenticated tenant. POST also requires the configured consumer client identity. The owner derives the stream from that tenant and the fixed route kind; callers cannot select another tenant or arbitrary stream.
GET accepts afterSeq (nonnegative, default 0), limit (1-500, default 100) and optional positive streamEpoch. The response carries tenant, kind, stream, epoch, head, retention horizon and ordered versioned envelopes. Each payload preserves the source domain-event ID. Scanner checks the page, envelope and payload identities before handling an event.
POST accepts streamEpoch and seq together. Both null register/reset the remote registration at zero; both supplied report a positive epoch and nonnegative sequence. The owner rejects a report outside its current epoch/head with HTTP 409. These are transport operations performed by the Worker, not an operator command for changing its local checkpoint.
Startup, cutover and restart
Release Orchestrator owns the domain-event log and its P6 delivery outbox in stellaops_release_orchestrator. A new domain event and its delivery envelope commit in one transaction. The domain log retains semantic evidence; the outbox tracks delivery. The owner uses a dedicated eventing pool, separate from its key-management pool.
At owner startup, embedded migrations add the publication marker and the P6 schema. Domain migration 010 adds the marker; forward migration 011 preserves the domain log’s append-audit retention classification, existing 365-day window and custody metadata. Before the host serves requests, retained SCM/build-context domain events without a publication marker are imported into their tenant streams. Import and current publishers share a lock; each envelope and its marker commit atomically. A restart imports remaining rows without duplicating already marked rows. A publication marker says nothing about whether Scanner has applied the event. The removed StartAfterEventId settings are not P6 cursors and must be removed from configuration.
Scanner owns its inbox, checkpoints and processing leases in stellaops_scanner. scanner-web remains the migration authority; Worker consumes that schema. Each event kind and tenant has independent progress. Handling precedes the fenced checkpoint transaction, so a crash between the effect and checkpoint can replay the event through the existing idempotent handler. A Worker restart resumes its persisted checkpoint.
The Worker reports its persisted position before each batch, including caught-up polls, and after a successfully processed batch. The owner’s remote registration constrains retention while it remains active. The default delivery retention window is seven days; the remote registration lease is 24 hours. A stopped consumer can outlive that protection, so retained delivery history is not an unlimited replay archive.
Verify and recover
- Verify the owner and
scanner-webcomplete their startup migrations, and the owner finishes retained-event import before enabling a bridge. - Verify the configured client can read its tenant’s owner stream and report its durable position. A token for another tenant must not reveal or process the first tenant’s events.
- Produce an event through a normal owner operation. For SCM, completing missing repository and commit provenance on a component version emits the owner event; see component version sync.
- Match the owner
sourceEventIdto the Scanner effect and its persisted tenant/kind checkpoint. Restart the Worker and verify progress resumes without a duplicate effect.
An unavailable owner, rejected token, malformed event, tenant mismatch or handler failure leaves progress at the last successful event. Other tenant partitions remain independent. Correct the reported cause and let the next poll retry; do not advance a checkpoint by hand.
An epoch change, missing stream with an existing checkpoint, or retention gap fails closed. Keep the affected bridge disabled while restoring matching retained owner history and Scanner progress from a verified recovery point, or arranging an explicit owner-controlled replay. Re-enabling alone does not repair a gap. The consumer does not automatically reset its checkpoint or skip to the advertised head.
Source verification
Run these read-only commands from the repository root. They inspect the current source; compare changes since the verified commit before relying on a different checkout.
git diff 163f35a2ce -- src/Scanner/StellaOps.Scanner.Worker/Options src/Scanner/StellaOps.Scanner.Worker/Processing/Scm src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Endpoints/ScannerEventStreamEndpoints.cs src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/ScannerEventStreamPolicies.cs src/ReleaseOrchestrator/__Libraries/StellaOps.ReleaseOrchestrator.ScannerEvents.Contracts src/ReleaseOrchestrator/__Libraries/StellaOps.ReleaseOrchestrator.Storage/ScannerEvents
rg -n 'ReleaseOrchestratorEvents|ScmInfoAvailableTrigger|BuildContextReachabilityTrigger|release:read' src/Scanner/StellaOps.Scanner.Worker/Options
rg -n 'RequireAuthorization|RequireTenant|ConsumerClientId' src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Endpoints/ScannerEventStreamEndpoints.cs src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/ScannerEventStreamPolicies.cs
rg -n 'ImportRetainedAsync|LockPublicationAsync|CommitAsync|ReportCheckpointAsync|EnsureFencedAsync' src/ReleaseOrchestrator/__Libraries/StellaOps.ReleaseOrchestrator.Storage/ScannerEvents src/Scanner/StellaOps.Scanner.Worker/Processing/Scm
The adjacent specifications are ReleaseOrchestratorScannerEventContractTests, ReleaseOrchestratorScannerEventCheckpointTests and ReleaseOrchestratorScannerEventForcingFunctionTests in src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/, plus ScannerEventStreamOwnerRetentionTests in src/ReleaseOrchestrator/__Tests/StellaOps.ReleaseOrchestrator.Integration.Tests/. Source inspection does not replace executing those specifications or verifying the configured installation’s owner event, Scanner effect and durable checkpoint.
