OpsMemory (pointer)
Consolidated into AdvisoryAI (Sprint 213). There is no standalone OpsMemory dossier. The authoritative design lives in
advisory-ai/architecture.md§15 — OpsMemory (Operational Memory and RAG).
OpsMemory is a decision ledger for security operations: it records the lifecycle of a decision (situation → action → outcome) and retrieves similar precedents via array-stored cosine similarity (no pgvector). It was folded into the AdvisoryAI module but still ships as its own container.
Where things live
| Thing | Location |
|---|---|
| Library | src/AdvisoryAI/__Libraries/StellaOps.OpsMemory/ |
| WebService | src/AdvisoryAI/StellaOps.OpsMemory.WebService/ (/api/v1/opsmemory/*) |
| Tests | src/AdvisoryAI/__Tests/StellaOps.OpsMemory.Tests/ |
| Container | opsmemory-web / stellaops-opsmemory-web (devops/compose/docker-compose.stella-services.yml:2710) |
| Schema | opsmemory (auto-migrated on startup; Migrations/001_initial_schema.sql, embedded) |
| Scopes | ops-memory:read / ops-memory:write — canonical catalog StellaOpsScopes.cs:864-865 |
Docs in this directory
api-reference.md+openapi/— autogenerated from the service’s OpenAPI document. They describe the wire shape only; they are not a dossier and they do not carry the auth/tenancy contract.
Tenancy contract (read before trusting the api-reference)
The generated api-reference.md shows tenantId as a plain query parameter. That is not the isolation key. Since Sprint SPRINT_20260712_001 (TEN-1) the /api/v1/opsmemory group carries .RequireTenant() and every handler isolates on the tenant resolved from the authenticated stellaops:tenant claim; the tenantId query parameter and the RecordDecisionRequest.TenantId body field are optional conflict checks only (disagreeing with the claim → 400 tenant_conflict; no tenant claim → 400 tenant_missing). See advisory-ai/architecture.md §15 “Tenancy contract”.
