Eltheon Adviser
Redeon.SuperSiteEngineCore.Web.Eltheon.Core.Features.Adviser is the owning
feature package for Adviser run planning, execution, findings, policies, and
administration.
Phase 4.17 Sessions 2 through 11 provide the validated check registry, configurable activation baseline, deterministic run planner, bounded in-memory manual request store, scoped check executor, durable run history, finding lifecycle, typed policies, secret-safe observability, and the Service-v3 workload binding:
builder.Services.AddEltheonAdviser();
builder.Services.AddEltheonAdviserPersistence(ConfigureProvider);
The package registers adviser.evaluation as a keyed scoped IEltheonJob.
Its singleton EltheonJobDescriptor uses owner Feature/adviser,
QueueLatest, MaxParallelism = 1, a 30-minute job timeout, and no automatic
retry beyond the initial attempt.
Contributor features do not reference this package. They implement and
register checks through the neutral contracts in
Redeon.SuperSiteEngineCore.Web.Eltheon.Core.Abstractions.v1.Adviser:
builder.Services.AddEltheonAdviserCheck<MyFeatureCheck>();
The contract context contains bounded Adviser selectors, actor identity, correlation, causation, and a safe trigger summary. It intentionally exposes no raw Service-v3 trigger or event payload, Adviser persistence service, finding store, or arbitrary service provider.
Manual selectors are stored behind a bounded opaque Adviser request ID. Only
that ID is transported through EltheonJobExecutionRequest.CausationId; a
missing or expired correlated request fails safely and never becomes an
unfiltered run. Trigger defaults remain Adviser-owned:
startup → startup
interval → operational
cron → deep (configurable)
event → targeted
file → targeted with explicit check opt-in
at → recheck only for adviser.recheck.* bindings
none → manual
The Adviser executor applies a bounded overall check limit, a separate external check limit, and single-flight concurrency groups. Per-check timeouts use the contributor cancellation contract and never abandon detached contributor work. Checks must therefore observe the supplied cancellation token.
Only successful results with valid coverage retain observations. Failed, timed-out, canceled, skipped, missing, and invalid-coverage results are normalized to non-resolving coverage without observations. Individual check failures complete the Adviser job with warnings instead of turning a technical failure into a finding or failing the complete Service-v3 execution.
Process-local Adviser self-health contributes bounded runtime diagnostics for current, repeated, and persistent execution issues. It stores no observations, evidence, raw exceptions, or exception messages.
The Adviser package owns EltheonAdviserDbContext, a DataProvider-v3 migration
manifest, and provider-separated SQLite, MySQL, and MSSQL migrations. The
durable boundary records the run plan before contributor execution and then
atomically records normalized execution metadata, evaluated/excluded coverage
subjects, aggregate counts, and a secret-safe terminal summary. A unique
Service execution link and stable Adviser run IDs make retries idempotent.
Run-history queries are bounded, and completed-run retention is exposed through
IEltheonAdviserRunHistoryMaintenance. When persistence is enabled, the
package also registers adviser.retention as a keyed scoped Service-v3 job.
Its singleton descriptor uses Skip, MaxParallelism = 1, a five-minute
timeout, one attempt, and a daily interval binding without an immediate first
run. Each execution deletes no more than ten 1,000-entry batches per store,
using the configured run-history and resolved-finding retention thresholds.
Cancellation is propagated without a self-health failure; other maintenance
failures are exposed only through the bounded adviser.retention.failed
runtime diagnostic.
Session 5 projects successful finding observations through a stable SHA-256
fingerprint composed only from check, subject, reason, and condition identity.
Finding, current evidence, recommendations, transition history,
acknowledgements, and finding-scoped suppressions are committed atomically with
check history and the terminal run state. The Open/Resolved lifecycle is
independent of acknowledgement and suppression.
Only successful Complete coverage or the explicitly evaluated subjects of a
successful Targeted execution may resolve findings. Partial coverage,
excluded or indeterminate subjects, and failed, timed-out, canceled, or skipped
executions never resolve findings. Reobservation reopens the same finding,
retains suppression, and clears acknowledgement by default.
IEltheonAdviserFindings exposes bounded projections.
IEltheonAdviserFindingLifecycle applies revision-checked actor mutations, and
IEltheonAdviserFindingMaintenance provides bounded resolved-finding
retention. Restricted evidence retains only its key, type, sensitivity, and
display metadata; its raw value is never persisted.
Session 6 adds the typed IEltheonAdviserPolicies store and
IEltheonAdviserPolicyEvaluator. Rules use deterministic priority,
scope-specificity, and policy-key ordering. They may override effective
severity and control suppression, notification thresholds, quiet hours,
cooldown, and administrator/role targeting. They cannot alter observations,
subjects, reason codes, evidence, coverage, lifecycle, resolution, or
authorization. Findings retain OriginalSeverity, CurrentSeverity, the
applied severity-policy key, and an immutable transition reason.
Canonical Adviser events, metrics, and spans use only neutral Core.Abstractions ports. The production package has no direct reference to Events, Metrik, Auditing, Notifications, Service, or a contributor feature. Manual and deep runs emit audit-relevant run events; finding/policy mutations emit audit-relevant change events. Periodic detail remains in bounded metrics and tracing. Event payloads contain only safe identifiers and classifications.
Finding notifications are policy-controlled and use
FindingId + TransitionKind as their coalescing identity with the effective
cooldown as DeduplicationWindow. Open, reopen, and severity escalation are
eligible; quiet hours, policy suppression, finding suppression, lower severity,
and non-escalating transitions block publication. Notification messages never
contain evidence, free-form comments, recommendations, raw errors, paths, or
URLs.
No raw trigger payload, exception, stack trace, Restricted Evidence value, or arbitrary policy payload is written to Adviser persistence, events, metrics, spans, notifications, or logs.
Session 8 adds the complete API-first administration boundary under
/api/v1/admin/adviser: overview, bounded finding and run queries, detail
projections, acknowledgement, suppression/revocation, recheck, manual run
dispatch, check activation, and typed policies. Mutations require canonical
permissions, cookie-specific antiforgery validation, and revision ETags.
Restricted evidence is omitted unless
Eltheon.Adviser.ViewSensitiveEvidence succeeds; authorized access emits an
audit-relevant secret-safe event.
The host registers the Adviser assembly as an MVC application part and binds
the feature-owned context through AddEltheonAdviserPersistence. Manual
selectors remain Adviser-owned and only their opaque request ID crosses the
payload-free Service-v3 dispatch boundary.
Session 9 adds the feature-owned administration cockpit under
/Admin/Adviser. The RCL contributes its navigation through
IEltheonNavigationProvider, protects the page with
Eltheon.Adviser.View, and uses the existing API for Overview, Findings,
Finding Detail, Runs, Check Registry, and Policies. English and German
resources include SimpleSearch metadata.
The cockpit uses the template-provided EltheonJS Full bundle with api,
pageManager, templating, events, scheduler, and ui. A bounded
30-second change probe only announces that updated data is available; it
does not replace an active view or overwrite form input. Mutations continue
to carry the API antiforgery token and current revision ETag. No
AdminDashboard dependency or feature-local JavaScript framework is added.
The bounded plugin contract under Core.Abstractions/v1/Extensions remains a
separate compatibility surface. An adapter is deferred until after Adviser R1.