Renames date-prefixed migrations (20260107_002, 20260408_003, 20260409_004)
to plain sequential numbers (002, 003, 004) to match the convention used by
other service migration directories. Adds TimelineCoreMigrationCategoryTests
to verify the unified-audit migration registers under the correct category
for the StartupMigrationHost transaction classifier.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds MigrationSqlTransactionClassifier to recognize migration SQL that opens
its own transactions (BEGIN/COMMIT/ROLLBACK) so MigrationRunner can skip
wrapping those files in an outer transaction. StartupMigrationHost now surfaces
a MigrationCategory indicator for runtime-aligned bootstrap. Test harness
extended with an explicit-transaction fixture and execution scenario coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three Doctor trend endpoints (/trends/checks/{checkId}, /trends/categories/{category},
/trends/degrading) were missing the [FromServices] attribute on the
IDoctorTrendRepository? parameter, causing ASP.NET minimal-APIs to attempt model
binding from route/query instead of resolving from DI. Verified fix with HTTP 200
responses against all four trend endpoints via the gateway.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop FeedMirrorManagementEndpoints.cs (660 lines of seeded mock data)
as part of the no-mocks initiative. Feed mirror state will be served
from real source/read-model queries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scripts module now owns its PostgreSQL schema lifecycle: ScriptsPostgresOptions,
ServiceCollectionExtensions.AddReleaseOrchestratorScripts(), embedded SQL migration,
and MigrationServiceExtensions fix to register multiple IHostedService migrations
without deduplication. Fresh installs auto-converge the scripts catalog without
depending on Scheduler-owned bootstrap SQL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GetBySnapshotIdAsync and ListBySourceIdAsync provide the read-model
queries needed to replace seeded feed-mirror responses with real state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
StandardPluginBootstrapper now retries up to 15 times (2s delay) so the
admin user and client seeds converge after PostgreSQL becomes reachable.
Exceptions bubble through the retry loop instead of being swallowed per-step.
Tests cover the retry path with a FlakyUserRepository that fails once then
succeeds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mount router-gateway-local.json as appsettings.json (not appsettings.local.json)
so it fully replaces the baked-in config instead of merging. Add Node, Transports,
Routing, and OpenApi sections to make the file self-contained. Test validates all
required top-level sections are present.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DoctorTrendEndpoints used IDoctorTrendRepository and TimeProvider as
MapGet handler parameters without [FromServices], causing ASP.NET to
infer them as body parameters — crashing the scheduler on startup with
"Body was inferred but the method does not allow inferred body parameters."
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JobEngine page:
- Replace custom segmented toggle with StellaPageTabsComponent
- Fix SCHEDULER_API_BASE_URL factory (new URL() always threw on relative paths)
- Fix listSchedules to include disabled schedules
- Add source field mapping for system schedule badge
Audit log page:
- Remove Overview tab, default to All Events
- Replace custom filters with standard app-filter-bar (matching other pages)
- Remove policy-specific column toggles and category chips
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New audit-event-details-panel component with HTTP context, request body, before state sections
- Highlight [REDACTED] PII values with warning badge
- Auto-construct diff view from details.beforeState when Diff is absent
- Add release/attestor/doctor/signals/advisory-ai/riskengine module support
- Replace raw JSON dumps with semantic rendering
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Capture request body (JSON, up to 64KB, PII-redacted) in Details["requestBody"]
- Capture response resource ID for create operations in Details["responseResourceId"]
- Add IAuditResourceEnricher interface for GUID -> human-readable name resolution
- Add IAuditBeforeStateProvider for before-state snapshots in Details["beforeState"]
- Add AuditPiiRedactor with configurable field patterns (recursive JSON walk)
- AuditActionAttribute gains CaptureBody (bool?) + SensitiveFields (string[]?)
- AuditEmissionOptions gains MaxBodySizeBytes (64KB) + RedactedFieldPatterns
- All enrichment is optional and fire-and-forget (never blocks response)
- Add AuditModules constants (15 modules) and AuditActions constants (~200 actions)
organized as nested static classes per module for type-safe annotations
- All 17 consuming services verified to compile successfully
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- All active services now use their own persistence (release-orchestrator, scheduler, packsregistry)
- Zero remaining references from any active csproj
- Clean solution files (4 projects + 48 build configs removed from StellaOps.sln)
- Update README and AGENTS.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Map 532 state-changing endpoints across 9 services for AuditActionFilter
- Plan 5-batch migration: convention helper → complex services → dual-write →
read migration → drop local tables
- Reclassify Authority auth-protocol and Policy gate-bypass audit as domain evidence
- 24 days active work + 120-day verification pipeline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Switch default repository to start empty when Postgres is configured;
GraphDataLoaderHostedService loads real data from graph.graph_nodes/edges
on startup and refreshes every 5 minutes
- Keep InMemoryGraphRepository with hardcoded seed as fallback when no DB
- Add Reload() method to InMemoryGraphRepository for hot-swapping data
- Add GetAllNodesAsync/GetAllEdgesAsync to PostgresGraphRepository
- Deprecate hardcoded seed data in InMemoryGraphRepository
- Fix graph-api port mismatch: container listens on 8080 (ASPNETCORE_URLS)
but compose mapped 80:80; corrected to 80:8080 + healthcheck to 8080
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ConcurrentDictionary-based in-memory stores (VexDecisionStore,
FixVerificationStore, AuditBundleStore) with Postgres-backed repositories
that persist VEX decisions, fix verifications, and audit bundles to the
findings schema. The stores auto-detect NpgsqlDataSource availability and
fall back to in-memory mode for tests/offline.
Changes:
- Add migration 010_vex_fix_audit_tables.sql creating vex_decisions,
fix_verifications, and audit_bundles tables (partitioned by tenant_id)
- Rewrite VexDecisionStore with dual-mode: Postgres when ConnectionStrings__Default
is configured, ConcurrentDictionary otherwise (backwards-compatible for tests)
- Rewrite FixVerificationStore and AuditBundleStore with same dual-mode pattern
- Wire NpgsqlDataSource in Program.cs from ConnectionStrings__Default
- Add /api/vuln-explorer/findings/{vulnId}/evidence-subgraph route alias to
match what the Angular UI (EvidenceSubgraphService) actually calls -- the
gateway forwards this path as-is to the service
- Convert all endpoint handlers to async to use the new Postgres-backed methods
- Add Npgsql PackageReference to VulnExplorer.Api.csproj
- Add VulnExplorerRepositories.cs placeholder in Findings.Ledger.WebService
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mark CP-005 DONE: TenantAwareCryptoProviderRegistry decorator, ITenantCryptoPreferenceProvider
interface, AddTenantAwareCryptoResolution DI extension, PlatformCryptoPreferenceProvider,
14 unit tests (all pass), and sprint tracker update.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove ExceptionLifecycleWorker + ExpiringNotificationWorker from scheduler-web
- Add both to AddSchedulerWorker() extension (worker-host already calls this)
- Move PostgresExceptionRepository to Worker library
- Web retains only SystemScheduleBootstrap (startup seed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create timeline.unified_audit_events table with SHA-256 hash chain
- Create timeline.unified_audit_sequences for per-tenant tracking
- Replace IngestAuditEventStore (in-memory) with PostgresUnifiedAuditEventStore
- Preserve chain integrity via serializable isolation
- Mark AUDIT-001 as DONE in sprint tracker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create ISchedulerJobPlugin abstraction with JobKind routing
- Add SchedulerPluginRegistry for plugin discovery and resolution
- Wrap existing scan logic as ScanJobPlugin (zero behavioral change)
- Extend Schedule model with JobKind (default "scan") and PluginConfig (jsonb)
- Add SQL migrations 007 (job_kind/plugin_config) and 008 (doctor_trends table)
- Implement DoctorJobPlugin replacing standalone doctor-scheduler service
- Add PostgresDoctorTrendRepository for persistent trend storage
- Register Doctor trend endpoints at /api/v1/scheduler/doctor/trends/*
- Seed 3 default Doctor schedules (daily full, hourly quick, weekly compliance)
- Comment out doctor-scheduler container in compose and services-matrix
- Update Doctor architecture docs and AGENTS.md with scheduling migration info
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix dual-schema violation (scheduler was writing to scheduler + scripts)
- Move ScriptsDataSource, PostgresScriptStore, script endpoints
- Update gateway routes and UI references
- Each service now owns exactly one schema
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add crypto provider panel to Platform Settings at /setup/crypto-providers
- Show provider health status with status dots, latency, and last-checked time
- Collapsible start commands with copy-to-clipboard for stopped providers
- Auto-refresh every 30s using interval+switchMap, stopped on destroy
- Provider selection with confirmation dialog via existing ConfirmDialogComponent
- Priority ordering via number input per provider preference
- Active provider banner and per-card active badge
- Disabled "Set as Active" for stopped/unreachable providers with tooltip
- Algorithm scope mapping table for configured preferences
- Backward-compatible redirect from /settings/crypto-providers
- Setup overview card added for Crypto Providers
- Sprint CP-003/CP-004 marked DONE with execution log
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ported 3 database backend plugins with namespace adaptation:
- Oracle: EF Core-based store with AQ signaling wiring (2 files)
- MongoDB: Delegates to DataStore.MongoDB extension method (2 files)
- PostgreSQL: Delegates to DataStore.PostgreSQL extension method (2 files)
Implementation files already exist in __Libraries DataStore projects
(ported in earlier commits). These plugins are thin IDependencyInjectionRoutine
wrappers that enable dynamic plugin loading via the workflow plugin system.
Also fleshed out the stub OracleWorkflowDataStoreExtensions to register
WorkflowDbContext, OracleWorkflowRuntimeStateStore, and
OracleWorkflowHostedJobLockService.
All namespaces converted from Ablera.Serdica to StellaOps.
Plugin interface adapted from IPluginServiceRegistrator to IDependencyInjectionRoutine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backport generic improvements from Serdica workflow engine to StellaOps:
Abstractions:
- Add IWorkflowActorRoleResolver interface and NullWorkflowActorRoleResolver
default implementation for server-side actor identity resolution
- Add expression-based Call overloads to WorkflowFlowBuilder (6 new methods
accepting WorkflowExpressionDefinition for payload instead of Func<> factory)
- Fix failure handler compilation: preserve empty handlers (0 steps) as empty
sequences instead of null, allowing "ignore failure and continue" semantics
- Add explanatory comments to WorkflowRegistrationAbstractions for JSON number
normalization logic
Contracts:
- Add NextTasks and WorkflowState to StartWorkflowResponse so callers can
see immediate next tasks after starting a workflow
- Add WorkflowInstanceId, NextTasks, and WorkflowState to
WorkflowTaskCompleteResponse for richer task completion feedback
Transport: verified Transport.GraphQL, Transport.Http, Transport.Microservice,
and Transport.LegacyRabbit are engine-embedded plugins (no separate directories
to add/remove). ElkSharp library confirmed present at src/__Libraries/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Handle duplicate JSON property names in ToRuntimeValue — GroupBy
before ToDictionary prevents crash on case-insensitive duplicates
2. Normalize decimal-valued integers in sub-workflow payloads —
recursive NormalizePayloadNumbers converts 201000256548.0 to long
3. Add WorkflowExecutionActorContext — AsyncLocal propagation of
actor identity through OnComplete execution chains
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>