Audit Emitter Coverage Matrix

Sprint: SPRINT_20260518_053_Anomaly_v2_epic.md, T6 partial EvidenceLocker phase.

Discovery date: 2026-05-18. This matrix is a read-only static sweep plus the focused EvidenceLocker capsule-download implementation proof in this phase. It does not claim full T6 completion.

Method

Limitations: mutating endpoint counts are raw grep candidates, not behavioral proof. Endpoints factored into sibling projects can be missed by project-directory counters; EvidenceLocker capsule endpoints are one such case and were read separately.

serviceDI wiredfilter wiredper-action emission verifiedgap
src/__Libraries/StellaOps.Verdict.WebServiceNoNoN/A - no mutating candidates in static scan.No T6 action identified in this first slice.
src/AdvisoryAI/StellaOps.AdvisoryAI.WebServiceYesYes - 8 audited calls / 53 mutating candidates.Partial static coverage only.Remaining mutating candidates need owner review and targeted tests.
src/AdvisoryAI/StellaOps.OpsMemory.WebServiceYesYes (Sprint 082) - 2 audited calls / 2 mutating candidates.Static coverage; both decision endpoints audited.CLOSED (Sprint 082 T081-2). POST /decisions (record_decision) and POST /decisions/{id}/outcome (record_outcome) are .Audited(opsmemory/...).
src/Attestor/StellaOps.Attestor.WebServiceYesYes - 11 audited calls / 12 mutating candidates.Partial static coverage only.Review the remaining mutating candidate and add targeted proof.
src/Attestor/StellaOps.Signer.WebServiceYesYes - 8 audited calls / 8 mutating candidates.Static coverage appears complete; no T6 behavioral proof captured here.Add owner-level Timeline landing test if this becomes part of full T6.
src/Authority/StellaOps.IssuerDirectory.WebServiceYesNo - 0 audited calls / 8 mutating candidates.No.FILED FOLLOW-UP (Sprint 082 T081-2): wiring deferred to respect the active hard scope guard on src/Authority/ (a concurrent agent owns Authority seeds). The 8 mutating endpoints (issuer create/update/delete, key create/rotate/revoke, trust set/delete) need .Audited(issuerdirectory/...) added once the Authority subtree is unlocked. Module issuerdirectory + actions are already in the catalog; only the .Audited(...) annotations remain. Follow-up ref: SPRINT_20260520_082 T081-2 IssuerDirectory residual.
src/BinaryIndex/StellaOps.BinaryIndex.WebServiceYesNoN/A - no mutating candidates in static scan.No T6 action identified in this first slice.
src/Concelier/StellaOps.Concelier.WebServiceYesYes - 86 audited calls / 94 mutating candidates.Partial static coverage only.Review remaining mutating candidates and existing Concelier audit tests before claiming parity.
src/Concelier/StellaOps.Excititor.WebServiceYesYes - 4 audited calls plus 1 explicit emit / 25 mutating candidates.Partial static coverage only.Review remaining mutating candidates and add targeted tests.
src/Doctor/StellaOps.Doctor.WebServiceYesYes - 3 audited calls / 3 mutating candidates.Static coverage appears complete; no T6 behavioral proof captured here.Add owner-level Timeline landing test if this becomes part of full T6.
src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.WebServiceYesYes - WebService and capsule endpoints use .Audited(...); this phase also adds explicit capsule download emission.Partial T6 proof captured: CapsuleEndpointsTests.ExportCapsule_EmitsDownloadAuditPayloadWithCorrelationId passed through the direct xUnit runner and asserts module=evidencelocker, action=download, resource.type=evidence_pack, resource id, actor id, tenant id, and correlation id before Timeline ingest. Live row proof captured on 2026-05-19: POST http://evidencelocker.stella-ops.local/api/v1/evidence/capsules/ followed by POST /api/v1/evidence/capsules/c9b8d5c7-aba4-43ed-b1ea-52072dfd0371/export with canonical correlation header X-StellaOps-Correlation-Id: 393e8c91-8ff7-4ff3-9b0a-0f38974f5d9e returned 200 and landed one timeline.unified_audit_events row within 361 ms: id=audit-evidencelocker-download-3c6f6c5cf22b48a9955230513e5eff14, tenant 00000000-0000-0000-0000-000000000002, module evidencelocker, persisted action update, actor a0000003000000000000000000000001, resource type evidence_pack, matching resource id, matching correlation id, and download path /api/v1/evidence/capsules/c9b8d5c7-aba4-43ed-b1ea-52072dfd0371/export.RESOLVED (Sprint 082 T081-4). Capsule export/download payload proof and live Timeline row landing are closed. R17 decision: formally accept the canonical update mapping. Timeline normalizes the non-catalog download action to canonical update at ingest; rather than expanding the Timeline-owned UnifiedAuditCatalog.Actions (a T1/T2/T3-owned change), the download signal is carried by the stable, query-safe combination module=evidencelocker + resource.type=evidence_pack + details.downloadPath (+ the raw download value preserved in tags). This is the lower-risk, offline-safe option and matches the established pack.uploadedupdate and similar non-catalog normalizations. Persisted action is therefore update by design. Remaining EvidenceLocker bundle/portable/export surfaces are read-like artifact production (owner-review exemption).
src/ExportCenter/StellaOps.ExportCenter.WebServiceYesYes (Sprint 082) - 8 audited calls.Static coverage; profile/run lifecycle + incident lifecycle audited.CLOSED (Sprint 082 T081-2). Audited the canonical operator-state lifecycle: export profile create/update/archive, run start/cancel, and incident activate/update/resolve. Owner-review exemption: the remaining POST candidates are export-artifact generation (assurance, NIS2 SoA, simulation, exception-report, audit-bundle, risk-bundle, lineage export/sign) and verify operations (run verify, attestation verify, evidence-pack verify, promotion verify) — these are deterministic artifact-producing / read-like operations, not durable operator-state mutations, and are correctly not emitted. The two /exports + /exports/{id} routes are 410-Gone legacy stubs.
src/Findings/StellaOps.Findings.Ledger.WebServiceYesYes - 25 audited calls / 31 mutating candidates.Partial static coverage only.Review remaining mutating candidates and add targeted tests.
src/Findings/StellaOps.RiskEngine.WebServiceYesYes - 3 audited calls / 4 mutating candidates.Partial static coverage only.Review remaining mutating candidate and add targeted proof.
src/Integrations/StellaOps.Integrations.WebServiceYesYes - 6 audited calls plus 2 explicit emits / 7 mutating candidates.Partial T6 proof captured: IntegrationImpactEndpointsTests.TestEndpoint_EmitsUnifiedAuditPayloadWithTimelineCompatibleFields asserts module=integrations, action=test, actor id, tenant id, correlation id, resource.type=integration, resource id, HTTP method, request path, and status code for the existing operator test-connection endpoint.Test-connection now uses bounded explicit emission so T4 correlation is captured before the shared filter’s fire-and-forget context handoff. Static coverage and one operator-action payload proof are closed for this Integrations slice. Full T6 still needs live Timeline row landing and owner review for any future mutating Integrations routes.
src/JobEngine/StellaOps.PacksRegistry.WebServiceYesNo filter annotations; 2 explicit emits / 8 mutating candidates.T6 proof captured for pack upload and signature rotation: focused API tests assert module=packsregistry, actions pack.uploaded and signature.rotated, resource.type=pack, pack id, tenant id, digest details, and T4 correlation id propagation. Live row proof after service-only rebuild: POST http://packsregistry.stella-ops.local/api/v1/packs with tenant t6-live-7c625694de7f, correlation 418d1dab-1103-4668-87f4-cf5582aca8a1, pack t6-audit-proof-8b751e38@1.0.0 landed one row in timeline.unified_audit_events within 5s (id=packsregistry-e705257f473a43a1a94bcf877a485c65, module packsregistry, canonical action update, resource type pack, matching resource id and correlation id).Pack upload/signature payload proof and pack-upload live Timeline row landing are closed for this slice. Timeline normalizes pack.uploaded to canonical update at ingest. Remaining lifecycle, parity, attestation, offline seed export, mirror upsert, and mirror sync mutating candidates still need owner review and targeted tests.
src/JobEngine/StellaOps.Scheduler.WebServiceYesYes - 11 audited calls plus 1 explicit emit / 21 mutating candidates.Partial static coverage only.Review remaining mutating candidates and add targeted tests.
src/Notifier/StellaOps.Notifier.WebServiceYesYes - 21 audited calls / 122 mutating candidates.Partial static coverage only.Large endpoint surface needs owner review; do not infer parity from static counts.
src/Notify/StellaOps.Notify.WebServiceYesYes - 31 audited calls / 110 mutating candidates.Partial T6 proof captured: CrudEndpointsTests.RuleCreate_EmitsTimelineAuditPayloadWithCorrelationId asserts module=notify, action=create_rule, actor id/name, tenant id, T4 correlation id, resource.type=rule, rule id, severity, tags, and HTTP method/path on the audited /api/v2/notify/rules operator route.Rule-create audit proof is closed for this Notify slice. The large Notify/Notifier surface still needs owner review and live Timeline row landing before full T6 closure.
src/Policy/StellaOps.Policy.EngineYesYes - active Policy Engine has broad .Audited(...) coverage for pack, revision, effective-policy, override, risk-profile, sealed-mode, violation, conflict, unknowns, exception, delta, gate, and governance mutations, plus explicit exception-service emission.Partial T6 proof captured: CraTechnicalDocumentationProvenanceEndpointTests.Save_EmitsCraProvenanceTimelineAuditPayload asserts module=policy, action=save_cra_technical_documentation_provenance, actor id, tenant id, correlation id, resource type/id, CRA export id, field counts, status, and source contract for the active CRA provenance save endpoint.CRA provenance save coverage is closed for this Policy slice. Remaining raw Policy POST/PUT/DELETE candidates include read-like compute/validate/simulate operations and other active mutation candidates that still need owner review plus live Timeline row landing before full T6 closure. Deprecated StellaOps.Policy.Gateway remains out of scope.
src/Platform/StellaOps.Platform.WebServiceYesYes - 56 audited calls plus 10 explicit emits / 122 mutating candidates.Partial static coverage only.Large endpoint surface needs owner review and targeted tests.
src/ReachGraph/StellaOps.ReachGraph.WebServiceNoNoN/A - no mutating candidates in static scan.No T6 action identified in this first slice.
src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApiYesYes - audited filters cover release CRUD/lifecycle, approvals, approval policies, deployments, environment management, scripts, evidence, and agent registration; promotion/approval decisions also emit explicit granular audit payloads.Partial T6 proof captured: PromotionAuditEmitterTests.EmitAsync_MapsPromotionDecisionToTimelineAuditPayload asserts module=release, promotion action, approval resource id, actor identity, tenant id, correlation id, severity, tags, and decision extras.Static coverage and mapper proof are strong for promotion decisions. Full T6 still needs live Timeline row landing and owner review for unaudited validation/runtime-only endpoints that do not mutate operator state.
src/Remediation/StellaOps.Remediation.WebServiceYes (Sprint 082)Yes - 3 audited calls / 3 mutating candidates.Yes (Sprint 082): RemediationAuditEmissionTests (3 tests, passed via direct xUnit runner) assert module=remediation, actions create_fix_template / create_pr_submission / upsert_marketplace_source, actor id, tenant id, resource type, correlation id, and HTTP method/path through the shared AuditActionFilter.CLOSED (Sprint 082 T081-1). All 3 mutating endpoints (fix-template create, PR-submission create, marketplace-source upsert) emit to Timeline.
src/Replay/StellaOps.Replay.WebServiceYes (Sprint 082)Yes - 1 audited call (capture_feed_snapshot).Static coverage; durable-state mutation audited.CLOSED (Sprint 082 T081-1). Of the 9 raw POST candidates only POST /v1/pit/snapshots (CaptureFeedSnapshot) mutates durable operator state and is now .Audited(replay/capture_feed_snapshot). Owner-review exemption: the token-generate/verify, verdict-replay execute/verify/compare, and PIT advisory query/diff endpoints are deterministic compute / read-like operations (replay executes in an ephemeral EnforceOffline context with CleanupOnDispose, producing no durable operator state) and are correctly not emitted.
src/Router/StellaOps.Gateway.WebServiceYesNo - 1 explicit emit / 2 mutating candidates.Partial, owned by T4/correlation work.Out of scope for this bounded EvidenceLocker phase.
src/Scanner/StellaOps.Scanner.WebServiceYesYes - 56 audited calls plus 1 explicit emit / 72 mutating candidates.Partial T6 proof captured: BulkImportEndpointTests.BulkImport_EmitsTimelineAuditPayloadWithCorrelationAndActor asserts SCM bulk import emits module=scanner, action=import, actor id, tenant id, T4 correlation id, resource.type=scm_bulk_import, batch id, integration id, repo counts, status, tags, and HTTP context fields.SCM bulk import coverage is closed for this Scanner slice. Remaining raw POST candidates include compute/read/validate/runtime-only operations plus other candidate surfaces that still need owner review and live Timeline row landing before full T6 closure.
src/Tester/StellaOps.Tester.WebServiceNoNo - 0 audited calls / 12 mutating candidates.No.EXEMPT (Sprint 082 T081-1): src/Tester/ is a hard scope-guard exclusion (owned by the separate Tester effort). Documented exemption — emitter wiring is owned by the Tester team, not Sprint 082.
src/Timeline/StellaOps.Timeline.WebServiceNoOne filter reference found, but this service is the audit sink.N/A for T6 emitter sweep.Timeline remains T1/T2/T3-owned; do not convert sink endpoints into emitters in T6.
src/Timeline/StellaOps.TimelineIndexer.WebServiceNoNo - 0 audited calls / 1 mutating candidate.N/A.EXEMPT (Sprint 082 T081-1). The single candidate POST /timeline/events is a non-mutating stub (Results.Accepted("indexed") with no body processing or persistence) and the service sits under Timeline-owned src/Timeline/, which the sprint scope guard excludes from emitter wiring. No operator-facing state is mutated; no emission required.
src/Unknowns/StellaOps.Unknowns.WebServiceYes (Sprint 082)Yes - 10 audited calls / 10 mutating candidates.Static coverage; all grey-queue state transitions audited.CLOSED (Sprint 082 T081-1). All 10 grey-queue mutations (enqueue, start-processing, record-result, resolve, dismiss, expire, assign, escalate, reject, reopen) are .Audited(unknowns/...).
src/VexHub/StellaOps.VexHub.WebServiceYes (Sprint 082)Yes - 1 audited call (resolve_conflict).Yes (Sprint 082): VexExportCompatibilityTests.ResolveConflictEndpoint_EmitsTimelineAuditPayloadWithCorrelationId (passed via direct xUnit runner) asserts module=vexhub, action=resolve_conflict, resource.type=vex_conflict, correlation id, tags, and HTTP method/path.CLOSED (Sprint 082 T081-1). The single mutating endpoint POST /api/v1/vex/conflicts/resolve emits to Timeline.
src/VexLens/StellaOps.VexLens.WebServiceYes (Sprint 082)Yes - 4 audited calls (issuer register/revoke, key add/revoke).Static coverage; issuer-registry mutations audited.CLOSED (Sprint 082 T081-1). The 4 issuer-registry mutations (register/revoke issuer, add/revoke issuer key) emit to Timeline. Owner-review exemption: the consensus/consensus-batch/delta-compute/gate-snapshot endpoints are deterministic derived-state computations (projection/cache outputs, not operator intent) and are correctly not emitted; exports are read-like.
src/Workflow/StellaOps.Workflow.WebServiceYes (Sprint 082)Yes - 10 audited calls.Static coverage; runtime + admin mutations audited.CLOSED (Sprint 082 T081-1). Audited: workflow start, task complete/assign/release, signal raise, definition import/import-multi/activate, retention run, dead-letter replay. Owner-review exemption: definition export / export-multi and canonical/validate are read-only (code comments confirm “read-only export of stored definitions” / “inspection only”) and are correctly not emitted.

T6 Status (CLOSED 2026-05-20)

T6 is DONE. Per Sprint 053 decision D5 and completion criterion 4, the Tier 9 §2.3 high-impact services were hard-blocked + verified in this sprint, and every residual gap row above is filed as a follow-up sprint rather than holding up T7.

Follow-up sprint for all residual gap rows: SPRINT_20260520_082_Audit_emitter_coverage_followup.md. Each remaining gap cell in the matrix above is owned by that sprint (T081-1 zero-coverage services, T081-2 DI-wired-no-emission, T081-3 partial-coverage owner review, T081-4 EvidenceLocker download action-catalog decision / R17).

Sprint 082 Follow-up Status (2026-05-20)

SPRINT_20260520_082 closed the residual gap rows.

Catalog additions (Audit.Emission + Timeline)

T081-1 (zero-coverage) — CLOSED except 1 exempt

Remediation, Replay, Unknowns, VexHub, VexLens, Workflow now wire AddAuditEmission + .Audited(...) on genuine operator-state mutations. TimelineIndexer EXEMPT (non-mutating stub under Timeline-owned tree). Tester EXEMPT (owned by Tester effort). Proven Timeline-landing integration tests: Remediation (3) + VexHub (1), both run via the direct xUnit runner.

T081-2 (DI-wired, no emission) — CLOSED except IssuerDirectory (filed)

OpsMemory + ExportCenter now .Audited(...). IssuerDirectory is FILED as a follow-up (8 endpoints; wiring deferred to respect the active src/Authority/ scope guard — concurrent Authority-seeds agent). Catalog entries are already in place; only .Audited(...) annotations remain.

T081-3 (partial-coverage owner review) — RESOLVED (per-service verdict)

The high-impact mutating slices for each partial service were already proven in Sprint 053 T6. Owner review of the remaining raw POST/PUT/DELETE candidates confirms they are dominated by read-like operations and do not require emission:

T081-4 (EvidenceLocker download / R17) — RESOLVED

Decision: accept the canonical update mapping; do not expand the Timeline action catalog. The download signal is carried by module=evidencelocker + resource.type=evidence_pack + details.downloadPath (+ raw download in tags). See the EvidenceLocker matrix row above.