Timeline
Verified against commit
942a18727con 2026-09-26 (UTC). Re-verify:git grep -n "MapGroup(\|Map\(Get\|Post\)(" -- src/Timeline/StellaOps.Timeline.WebServiceandls src/Timeline/__Libraries/StellaOps.Timeline.Persistence/Migrations.Service rows (host project, image, database and role, compose file, bundle presence, Doctor registration) are generated in
docs/architecture/service-inventory.md; where this page and the inventory differ, the inventory is authoritative.
Purpose
Timeline is one deployable with two roles:
- Unified audit sink. Services push audit events to
POST /api/v1/audit/ingest; they are stored intimeline.unified_audit_events(monthly partitions, per-tenant SHA-256 hash chain) with the verified identity of the caller that wrote each one (ingestIdentity), and served back with filtering, statistics, correlation clusters, chain verification, retention and GDPR controls, and anomaly detection (anomaly v2). - HLC event timeline. Hybrid Logical Clock-ordered event queries, critical-path analysis, export and replay, plus the TimelineIndexer event store and its NATS/Redis ingestion worker, which run in the same process.
Deployables
| Deployable | Source | Compose | Release bundle |
|---|---|---|---|
timeline-web | src/Timeline/StellaOps.Timeline.WebService/ (Program.cs) | devops/compose/docker-compose.timeline.yml | Yes: service timeline-web, image stellaops/timeline-web, aliases timeline.stella-ops.local, timelineindexer.stella-ops.local |
Database
- Own database
stellaops_timeline: schemastimeline,timeline_app(row-level-security helpers) andeventing(reliability store self-migrated byStellaOps.Eventing.Reliability) (StellaOps.Timeline.WebService/Doctor/TimelineSchemaTopology.cs). - Connection:
STELLAOPS_POSTGRES_TIMELINE_CONNECTION(keyPostgres:Timeline:ConnectionString);ConnectionStrings:Defaultis not a source. The bundle also derivesEventing__ConnectionStringfrom the same variable. - One migration authority:
src/Timeline/__Libraries/StellaOps.Timeline.Persistence/Migrations/(000to009), wired byAddConsolidatedTimelinePersistence. The host removes the TimelineIndexer hosted migrator.
API surface
| Family | Routes | Source |
|---|---|---|
| HLC timeline | GET /api/v1/timeline/hlc/{correlationId}, /critical-path | Endpoints/TimelineEndpoints.cs |
| HLC export and replay | /api/v1/timeline/hlc/{correlationId}/export, /export/{exportId}[/download], /{correlationId}/replay, /replay/{replayId}[/cancel] | Endpoints/ExportEndpoints.cs, Endpoints/ReplayEndpoints.cs |
| Unified audit | /api/v1/audit/ingest, /events, /stats, /timeline/search, /correlations, /chain/verify, /anomalies*, /export*, /retention-policies, /actors/{actorId}/pii | Endpoints/UnifiedAuditEndpoints.cs |
| Indexer events | GET /api/v1/timeline, /{eventId}, /{eventId}/evidence; POST /api/v1/timeline/events; the same four also at the bare /timeline prefix | Program.cs (MapTimelineIndexerEndpoints) |
| Operations | /health, /health/ready, /health/live, build info, /doctor/timeline/checks | Endpoints/HealthEndpoints.cs, Program.cs |
Replay and export bundle building are registered only in Development and Testing; elsewhere the Unsupported* implementations answer 501 (StellaOps.Timeline.Core/ServiceCollectionExtensions.cs).
Authorization
| Policy | Scopes | Used by |
|---|---|---|
Timeline.Read | timeline:read | Reads, status lookups, indexer reads |
Timeline.Write | timeline:write | Export and replay initiation, acknowledgement, indexer event ingest |
Timeline.AuditIngest | audit:ingest or timeline:write | POST /api/v1/audit/ingest (only audit:ingest may name the event tenant, and its tenant-less events join the admin-only installation tenant; a timeline:write caller writes to its own tenant and records only itself as the actor; every event stores its verified writer) |
Timeline.Admin | timeline:admin | Anomaly-rule CRUD, Notify dispatch worklist, GDPR PII redaction |
Timeline.DoctorHealth | ops.health | Doctor endpoints |
Source: Program.cs (AddStellaOpsScopePolicy, AddStellaOpsAnyScopePolicy) and Security/TimelinePolicies.cs.
Doctor checks
doctor.timeline.database.own-database-cutover, doctor.timeline.unified-audit-events.partitioning, doctor.timeline.eventing.co-tenancy (Doctor/TimelineDoctorChecks.cs), plus the standard service checks from AddServiceDoctorChecks("timeline").
Retired predecessors
StellaOps.TimelineIndexer.WebServiceandStellaOps.TimelineIndexer.Worker: archived tosrc/__Obsoleted/Timeline/on 2026-08-10 (SPRINT_20260722_020 W3-01); replaced bytimeline-web. TheTimelineIndexer.Coreand.Infrastructurelibraries stay live.- The legacy heap copy
timeline.unified_audit_events_heap_rollback, kept by the000partition bridge on a converted estate: classified source-of-truth by008_v1_timeline_heap_bridge_copy_retention_class.sql(RFC-19). Fresh databases never create it; disposal is the operator step in the partition cutover runbook. - The former TimelineIndexer dossier is archived at
docs-archive/modules/timeline-indexer/.
Subordinate documents
| Document | Status |
|---|---|
| architecture.md | current |
| api-reference.md, openapi/v1.json | current generated reference |
| audit-retention.md | design record, not re-verified 2026-09-26 |
| anomaly-v2.md | design record, not re-verified 2026-09-26 |
| audit-emitter-coverage.md | design record (2026-05-18 matrix), not re-verified 2026-09-26 |
