docs(implplan,concelier): close SPRINT_20260419_027 REALPLAN-007-F
Durable advisory-observation + affected-symbol runtime is live: PostgresAdvisoryObservationStore persists observations and delegates to IAffectedSymbolExtractor during upsert; PostgresAffectedSymbolStore backs /v1/signals/symbols/*. Non-testing runtime resolves both durable stores (Unsupported* registration removed). Targeted xUnit runs via scripts/test-targeted-xunit.ps1: - PostgresAdvisoryObservationStoreTests 2/2 - PostgresAffectedSymbolStoreTests 2/2 - ConcelierInfrastructureRegistrationTests 3/3 - UnsupportedRuntimeWiringTests 9/9 docs/modules/concelier/architecture.md updated to reflect the durable /v1/signals/symbols/* contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# Sprint 20260419-027 - Concelier Durable Affected Symbol Runtime
|
||||
|
||||
## Topic & Scope
|
||||
- Replace the live affected-symbol truthful `501` fallback with a durable PostgreSQL-backed runtime.
|
||||
- Persist advisory observations from the real raw-ingest path so live read models and signal writers stop depending on no-op observation services.
|
||||
- Wire ingest-time affected-symbol extraction from persisted advisory observations without changing AOC raw-fact ownership.
|
||||
- Working directory: `src/Concelier/`.
|
||||
- Cross-module touchpoints explicitly allowed for this sprint: `docs/modules/concelier/`, `docs/implplan/`.
|
||||
- Expected evidence: focused persistence tests, targeted runtime/DI proof, and synced Concelier architecture/task-board notes.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on `docs/implplan/SPRINT_20260417_023_Concelier_truthful_affected_symbol_runtime.md`, which intentionally moved `/v1/signals/symbols/*` to explicit `501` until a durable backend existed.
|
||||
- Safe to execute in parallel with unrelated Excititor or non-Concelier work because the write scope is limited to Concelier persistence, the Concelier raw-ingest pipeline, signals runtime composition, and their tests/docs.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/concelier/architecture.md`
|
||||
- `src/Concelier/StellaOps.Concelier.WebService/TASKS.md`
|
||||
- `src/Concelier/__Libraries/StellaOps.Concelier.Persistence/TASKS.md`
|
||||
- `src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/TASKS.md`
|
||||
- `src/Concelier/__Tests/StellaOps.Concelier.Persistence.Tests/TASKS.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### REALPLAN-007-F - Durable advisory observation and affected-symbol runtime
|
||||
Status: DONE
|
||||
Dependency: REALPLAN-007-E
|
||||
Owners: Developer, Test Automation, Documentation author
|
||||
Task description:
|
||||
- The live Concelier raw-ingest path already materializes `AdvisoryObservation` instances inside `AdvisoryRawService`, but the observation pipeline still resolves `IAdvisoryObservationSink` to a null sink and has no persistent `IAdvisoryObservationLookup`. That leaves live linkset/read-model consumers dependent on testing-only replacements instead of a durable runtime owner.
|
||||
- The affected-symbol surface also has no durable backend or writer path. This sprint adds PostgreSQL-backed advisory-observation persistence plus a PostgreSQL-backed affected-symbol store, then hooks the real ingest path to extract and persist symbols from advisory observations so `/v1/signals/symbols/*` can stop returning truthful `501`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `AddConcelierPostgresStorage` registers durable advisory-observation lookup/sink services and a durable affected-symbol store.
|
||||
- [x] The live raw-ingest path persists advisory observations and stores extracted affected symbols from those observations.
|
||||
- [x] Non-testing Concelier runtime resolves the durable affected-symbol services instead of `UnsupportedAffectedSymbol*`.
|
||||
- [x] Focused persistence/runtime proof covers observation persistence, affected-symbol persistence/query behavior, and ingest-time symbol extraction.
|
||||
- [x] Concelier docs and task boards describe the implemented durable runtime contract.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-04-19 | Sprint created and set `DOING` after reviewing the truthful-runtime follow-up gap: the real raw-ingest path already emits `AdvisoryObservation`, but live persistence still uses a null observation sink/lookup and no durable affected-symbol backend exists. | Developer |
|
||||
| 2026-04-19 | Shipped migration 008 (advisory_observations + affected_symbols), `PostgresAdvisoryObservationStore` (implements both lookup + sink and delegates to `IAffectedSymbolExtractor` during upsert), and `PostgresAffectedSymbolStore`. Wired via `AddConcelierPostgresStorage` in `ConcelierPersistenceExtensions` and registered before `AddConcelierObservationPipeline` so `TryAddSingleton` null-fallbacks do not override. Removed the non-testing `UnsupportedAffectedSymbolStore/Provider` registration in `Program.cs`. Targeted xUnit runs via `scripts/test-targeted-xunit.ps1`: `PostgresAdvisoryObservationStoreTests` 2/2 ✓, `PostgresAffectedSymbolStoreTests` 2/2 ✓, `ConcelierInfrastructureRegistrationTests` 3/3 ✓, `UnsupportedRuntimeWiringTests` 9/9 ✓. `docs/modules/concelier/architecture.md` updated to reflect the durable contract. | Codex |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: include durable advisory-observation persistence in the same slice as affected-symbol durability because the live writer hook already materializes observations inside `AdvisoryRawService`; leaving that path null would keep the affected-symbol writer detached from the real runtime.
|
||||
- Risk: advisory IDs can arrive under multiple aliases (`CVE`, `GHSA`, vendor IDs). The durable affected-symbol store must preserve a primary advisory key while still allowing alias-based lookup so the runtime does not regress query behavior.
|
||||
- Documentation sync target: `docs/modules/concelier/architecture.md` plus the relevant Concelier task boards once the runtime contract is finalized.
|
||||
|
||||
## Next Checkpoints
|
||||
- Finish durable observation + affected-symbol persistence.
|
||||
- Replace the explicit `501` affected-symbol runtime proof with focused durable-runtime verification.
|
||||
Reference in New Issue
Block a user