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:
master
2026-04-19 15:00:59 +03:00
parent 2e35bf4591
commit 6eb4394b1b
2 changed files with 45 additions and 44 deletions

View File

@@ -1,51 +0,0 @@
# 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: DOING
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:
- [ ] `AddConcelierPostgresStorage` registers durable advisory-observation lookup/sink services and a durable affected-symbol store.
- [ ] The live raw-ingest path persists advisory observations and stores extracted affected symbols from those observations.
- [ ] Non-testing Concelier runtime resolves the durable affected-symbol services instead of `UnsupportedAffectedSymbol*`.
- [ ] Focused persistence/runtime proof covers observation persistence, affected-symbol persistence/query behavior, and ingest-time symbol extraction.
- [ ] 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 |
## 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.