feat(eventing): add typed signal-to-event projection architecture - #363
Draft
robbiemu wants to merge 15 commits into
Draft
feat(eventing): add typed signal-to-event projection architecture#363robbiemu wants to merge 15 commits into
robbiemu wants to merge 15 commits into
Conversation
robbiemu
force-pushed
the
codex/issue-222-alerting-core
branch
from
August 11, 2026 22:35
6fb2377 to
2f5ac1c
Compare
robbiemu
force-pushed
the
codex/issue-222-alerting-core
branch
from
August 11, 2026 22:40
2f5ac1c to
0212b99
Compare
# Conflicts: # apps/api/src/services/alerts/AlertsService.ts # apps/api/src/services/integrations/planetscale/PlanetScaleWebhookQueue.ts # apps/cli/src/server/serve.ts # apps/cli/test/server-network.test.ts
Contributor
Author
|
I now have a working, mostly tested and verified version of this. Just putting a final review / finishing touches on it |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a host-neutral typed signal-to-event projection architecture and a durable named-consumer boundary for Maple Local.
It separates three concerns:
It also extracts the scheduled-alert decision and delivery policy into a reusable host-neutral package while preserving existing alert behavior.
Related to #222.
Event paths
Immediate per-occurrence path
authenticated input → source adapter → typed normalized signal → bounded selector → pure projector → durable outbox
The original telemetry continues through the existing warehouse encoder. A matched event is staged before the warehouse write and marked ready only after that write succeeds. Retrying the same source occurrence recomputes the same event identity.
Scheduled aggregate path
warehouse query → observation → alert lifecycle evaluation → factual alert event → existing delivery outbox
Rates, thresholds, percentiles, absence, recovery, flap suppression, and renotification remain scheduled conclusions over a window. They are not modeled as individual ingest-time facts.
Core architecture
A source definition publishes a typed field catalog, including allowed operators, sensitivity, and replay capability. Projection configuration stores a bounded typed predicate AST.
Projection revisions compile into immutable registry snapshots only after source fields, operators, activation time, and closed projector configuration are validated. Evaluation runs every matching projection from one snapshot and isolates failures so one malformed projector does not suppress successful siblings.
Projectors are pure, versioned functions. They declare an ID/version, accepted source kinds, output type/schema, and closed configuration decoder. They perform no I/O or external side effects.
Canonical CloudEvents and identity
Projected events use a common versioned CloudEvents envelope.
Event IDs are SHA-256 hashes over a length-delimited tuple of tenant, source kind, source, source occurrence ID, projection ID, and projection revision. Two optional backward-compatible extensions expose source occurrence identity and its quality. Historical envelopes without those extensions remain valid.
This lets downstream consumers correlate source occurrence → immutable Maple event → deterministic transport transaction without parsing event data.
Durable Local outbox and consumers
Maple Local stores projection revisions, active pointers, bounded failures, staged/ready events, and consumer state in a private SQLite control database.
Named consumers support:
Staged events are never pruned. Ready ordering is stable across restart and schema migration. Checkpoint manifests bind the control snapshot alongside the existing data backup.
Alert-core extraction
The new alerting-core package owns host-neutral observation evaluation, trigger/resolve/renotify planning, flap suppression, no-data recovery safety, scheduling helpers, delivery idempotency, and bounded retry policy.
Existing alert queries, persistence, queue behavior, and delivery payloads remain compatible. The factual event envelope is additive.
Existing producer convergence
The existing verified provider-webhook path now creates its factual event through the common projection seam while retaining queue compatibility, including jobs queued before deployment.
This demonstrates the architecture without making any provider-specific vocabulary part of the projection core.
Safety and boundedness
The implementation enforces:
Deliberate boundaries
This PR does not:
Provider adapters, deployment policy, transport delivery, and live credentials remain separate integrations built on the generic contracts introduced here.
Review guide
Primary surfaces:
packages/eventing-core: typed model, predicates, source/projector registries, deterministic identity, schemas, and fixtures;packages/alerting-core: alert evaluation, lifecycle planning, idempotency, scheduling, and retry policy;apps/cli/src/server/eventing: source-neutral normalization, telemetry, runtime, SQLite state, outbox, and consumer protocol;apps/cli/src/server/serve.ts: decode-once integration and authenticated control/consumer endpoints;apps/cli/src/server/checkpoints.ts: eventing-control checkpoint participation;docs/local-event-consumers.mdanddocs/signal-to-event-projection.md.Validation
Against the clean provider-neutral tree:
git diff --checkpasses.