7.1 KiB
7.1 KiB
Active Plan: PR-0 Spec Correction Pass (Security Notifications Provider Events)
Date: 2026-02-20 Status: Active and authoritative (supersedes all prior appended sections in this file)
1) Scope and Intent
- This is a spec-only correction pass for compatibility, migration determinism, and rollout safety.
- Security notifications are provider-event subscriptions, not a single global destination.
- Notify-only runtime remains fail-closed; legacy fallback dispatch remains blocked.
2) Compatibility GET Aggregation Rules (Exact)
Compatibility endpoint in scope:
GET /api/v1/notifications/settings/security
Aggregation source of truth:
- Active provider rows in
notification_providersafter filteringenabled=trueand supported notify-only types.
Derived booleans (OR semantics):
security_waf_enabled = OR(provider.notify_security_waf_blocks)security_acl_enabled = OR(provider.notify_security_acl_denies)security_rate_limit_enabled = OR(provider.notify_security_rate_limit_hits)
Deterministic conflict behavior when providers disagree:
- If any active provider has
truefor a category, compatibility GET returnstruefor that category. - Returns
falseonly when all active providers arefalse(or no active providers exist). - Provider order never affects result.
Legacy destination reporting:
- If compatibility payload still includes
destination, it is read-only compatibility metadata. destinationis emitted only when exactly one active managed-legacy provider is in scope.- If zero or more than one candidate exists,
destinationis returned as empty string anddestination_ambiguous=trueis set in compatibility metadata.
3) Compatibility PUT Translation Semantics (Exact)
Compatibility endpoint in scope:
PUT /api/v1/notifications/settings/security
Deterministic target set:
- If one or more managed-legacy providers exist, target set is exactly that managed set.
- If none exist and request is valid, create one managed-legacy provider and use it as the target set.
- Non-managed providers are never mutated by compatibility PUT.
Translation mode: replace on managed set (not global merge)
- For each target provider, set security event booleans exactly to request values:
notify_security_waf_blocks = request.security_waf_enablednotify_security_acl_denies = request.security_acl_enablednotify_security_rate_limit_hits = request.security_rate_limit_enabled
- Existing non-security provider event booleans remain unchanged.
- Existing provider transport fields remain unchanged unless destination mapping applies (Section 5).
Idempotency:
- Repeating identical PUT payload produces no state drift and same compatibility GET output.
- Write timestamps may change only when effective values change.
Conflict handling:
- If target set cannot be resolved deterministically (for example data corruption with duplicate managed identity keys), return
409 Conflictand do not partially write. - If request includes unsupported destination mapping shape, return
422 Unprocessable Entityand do not mutate providers. - All compatibility PUT writes are transactional: all target providers updated or none.
4) Migration Marker Storage and Deterministic Re-Run
Marker storage:
- Table:
settings - Key:
notifications.security_provider_events.migration.v1 - Value JSON schema:
version(string, fixedv1)checksum(string, deterministic hash of legacy source fields used for migration)last_completed_at(RFC3339 timestamp)result(completed|completed_with_warnings)
Deterministic boot-time re-run behavior:
- Read legacy source (
notification_configs) and compute checksum. - Read migration marker.
- If marker missing: run migration and write marker.
- If marker exists with same checksum: skip mutation (no-op).
- If marker exists but checksum differs: re-run migration in upsert mode, then replace marker.
Determinism constraints:
- Migration is pure over legacy source + managed provider key.
- Upsert key for managed provider is fixed identity
managed_legacy_security=trueplus nameMigrated Security Notifications (Legacy). - Re-run does not create duplicate managed providers.
5) Legacy Destination-to-Provider Mapping Rules
Supported destination mappings for compatibility PUT:
webhook_urlpresent:- map to provider type
webhook, set endpoint URL fromwebhook_url.
- map to provider type
discord_webhook_urlpresent:- map to provider type
discord, set endpoint URL fromdiscord_webhook_url.
- map to provider type
slack_webhook_urlpresent:- map to provider type
slack, set endpoint URL fromslack_webhook_url.
- map to provider type
gotify_url+gotify_tokenpresent:- map to provider type
gotify, set URL/token fields.
- map to provider type
Unsupported/ambiguous destination handling (fail-safe):
- If multiple destination types are simultaneously present in one request, return
422. - If destination type is unknown or incomplete for required fields, return
422. - On
422, no provider rows are created/updated and compatibility state remains unchanged.
6) Feature Flag as Explicit Rollout Gate
Primary gate:
feature.notifications.security_provider_events.enabled
Required defaults:
- Default in production:
false - Default in development/test:
true
Behavior when flag is false:
- Provider-based security dispatch path is disabled.
- Compatibility GET/PUT remain available.
- Runtime dispatch uses compatibility translation path only.
- Managed migration may run in read-only dry-evaluate mode, but must not mutate providers.
Behavior when flag is true:
- Provider-based security dispatch is authoritative.
- Compatibility GET is derived projection from providers.
- Compatibility PUT writes managed set via translation semantics defined above.
Operational rule:
- This flag is mandatory for rollout and rollback; it is not optional/recommended.
7) Authoritative Plan Boundary and Cleanup
- This document is now the single authoritative plan for this scope.
- All previously appended certificate flaky-test and QA remediation sections are removed from active plan scope.
- Any future unrelated plan content must go to a separate plan file under
docs/plans/.
8) PR Slicing Strategy
Decision: two PR slices.
- PR-0 (this pass): spec correction only in
docs/plans/current_spec.md. - PR-1: backend compatibility, migration marker, and feature-flag gate implementation.
- PR-2: frontend alignment and compatibility deprecation messaging.
9) Acceptance Criteria (Spec Pass)
- Compatibility GET rules define exact OR aggregation and disagreement behavior.
- Compatibility PUT defines deterministic target set, replace semantics, idempotency, and transaction/conflict behavior.
- Migration marker key/storage and deterministic re-run logic are explicit.
- Destination mapping rules cover supported non-webhook legacy forms and fail-safe unsupported behavior.
- File contains one authoritative plan with stale duplicate trailing sections removed.
- Feature flag is defined as explicit mandatory rollout gate with defaults and disable behavior.
10) Handoff
- Delegate PR-1 implementation to
Supervisorusing this plan as the sole baseline.