A vulnerability management program runs on dates. A finding has a remediation deadline. A scan is scheduled to run on a given night. A penetration testing project starts and ends on fixed days. A retest is owed once a fix is claimed. A framework agreement expires at the close of its contract term. Every one of these dates carries an obligation, and every missed date carries a cost. Yet in most security tooling these dates live in separate screens. The deadline sits inside the finding record. The scan time sits inside the scan scheduler. The project window sits inside the project view. The contract end date sits inside a vendor or agreement table. No single screen answers the one question an operations lead actually asks each morning, which is simple. What is due, and when.
A security operations calendar answers that question by pulling time-sensitive items from across the platform onto a single timeline. This article walks through how PMAP builds that calendar. It is a read-only aggregation layer rather than a new place to store dates. It reads seven kinds of events from four domains, sorts them in chronological order, and returns them inside a caller-supplied window. It supports a personal mode that narrows the view down to the obligations a single user owns. It applies a deliberate exclusion rule so that closed and otherwise resolved findings stop cluttering deadline views. The goal throughout is the same. Keep every deadline in one view so that no obligation falls through the gap between two screens.
This is a concept piece in PMAP’s real-time operations cluster. For the operational picture that surrounds it, including how alerts get routed and how live status reaches the browser, see the pillar guide on real-time security operations.
Why Deadlines Get Missed Without a Shared Timeline
Deadlines are not usually missed because someone forgot a task. They are missed because the task was visible in a screen nobody opened that day. A remediation deadline is recorded faithfully against the finding. The problem is that an analyst has to be looking at that finding, with that filter applied, on that day, to notice it is about to breach. Multiply that by hundreds of open findings, dozens of scheduled scans, several active projects, and a handful of contracts approaching renewal, and the surface area of things that could quietly slip becomes too large for any one person to hold in their head.
The structural issue is fragmentation. Each domain in a security platform owns its own dates and presents them in its own way. The finding domain knows about SLA deadlines and retest obligations. The scan domain knows when scans are scheduled and when they are running. The project domain knows start and end milestones. The agreements area knows contract expiry. These are correct sources of truth, and they should stay that way. But a date that is only visible from inside the record that owns it is a date that depends on someone navigating to that record at the right moment.
A shared timeline removes that dependency. Instead of asking the analyst to visit five screens and mentally merge them, the calendar visits those sources on the analyst’s behalf and presents one merged, date-sorted feed. The underlying records do not move. The calendar does not become a second copy of the truth. It is a lens that looks across domains and lines their dated items up in order. In PMAP this lens is exactly that. The calendar domain owns no persistent tables and writes nothing. It queries the other domains and returns a sorted list of dated events within the window the caller asked for.
That framing matters for trust. Because the calendar reads live from the source tables, what it shows is what those tables currently hold. There is no separate calendar database to fall out of sync, no nightly job to copy deadlines into a parallel store, and no risk that a finding’s deadline changed in one place but not in the calendar. The timeline is a projection of current state, recomputed on each request.
One Feed, Many Sources
The calendar exposes a single read endpoint. A request to it returns every qualifying event from every source it knows about, merged into one list and sorted ascending by date. Under the hood, that single response is assembled from four domains.
The first source is projects. PMAP surfaces project start and project end events for any project whose start or end date falls inside the requested window. For an assessment-driven program these milestones frame the work. They tell an operations lead when an engagement begins and when its deliverables are due.
The second source is scans. The calendar reads the scan records and surfaces scheduled and running scan activity whose time falls in the window. This puts the scanning cadence directly onto the same timeline as everything else, so a manager can see at a glance whether a heavy scan is set to run on the same night a project is due to close.
The third source is findings. This is the richest source for an operations team because it carries two distinct obligations. One is the SLA deadline on open findings. The other is the retest-due signal on findings that have entered a retest state. Both are obligations with dates, and both belong on the timeline.
The fourth source is framework agreements. The calendar reads the contract end date on framework agreements and surfaces an expiry event. This is the kind of date that is easy to forget precisely because it lives outside day-to-day security work, yet a lapsed agreement can interrupt scanning rights or assessment scope.
Each event the calendar returns is enriched at query time with the context a user needs to act. Rather than returning a bare date and a label, every event carries the originating entity’s identifier, its type, the owning company name, and where relevant the severity and status of the underlying record. That enrichment is what lets the user interface open a detail drawer on click without firing a second request back to the server. The data needed to render the detail is already in the event.
The Seven Calendar Event Types
The calendar emits exactly seven event types. Each type maps to a specific source table and a specific trigger condition. Understanding the seven is the fastest way to understand what the calendar will and will not show.
Project Milestones: Start and End
The first two event types are project_start and project_end. A project_start event is emitted for a project whose start date falls inside the window, and a project_end event is emitted for a project whose end date falls inside the window. The start event carries the project’s end date alongside it as an extra field, which lets a calendar widget draw the full engagement span rather than a single point. These two events give the timeline its scaffolding. They mark where work begins and where it is expected to conclude.
Scan Activity on the Timeline
The next two event types are scan_scheduled and scan_running. These are surfaced for scans whose time falls in the window, and they are filtered by scan status. A scan_scheduled event corresponds to a scan in a completed posture, while a scan_running event corresponds to a scan that is running or importing results. Putting scan activity on the calendar matters because scanning is itself a time-sensitive operation. A scan that runs late or overlaps a maintenance window has downstream effects, and seeing scan timing next to project and deadline timing makes those collisions obvious. For more on how scan timing is managed and kept in sync, see the scan scheduling guide referenced later in the cluster section.
SLA Deadlines and Retest-Due Obligations
The fifth and sixth event types are sla_deadline and retest_due, and both come from the findings domain. An sla_deadline event is emitted for an open finding whose remediation deadline falls inside the window. A retest_due event is emitted for a finding that has entered a retest state, keyed on when that finding was last updated. These are the events that an operations lead cares about most, because they represent direct work owed against agreed timelines. An SLA deadline is a promise about when a vulnerability will be fixed. A retest-due signal is a reminder that a claimed fix still needs verification. Both are deduplicated at the query level using a distinct select joined through the finding assignees table, so a finding with several assignees produces one calendar event rather than one per assignee.
Framework Agreement Expiry Reminders
The seventh event type is agreement_expiry. It is emitted for a framework agreement whose contract end date falls inside the window, drawn straight from the agreement’s end date. This is the long-horizon reminder of the set. Where SLA deadlines move in days and weeks, agreement expiry tends to move in months, and surfacing it on the same timeline ensures contract renewal is planned rather than discovered after the fact.
These seven types are the complete vocabulary of the calendar. There is no eighth hidden category and no catch-all event. If an item is on the calendar, it is one of these seven, and that constraint is what keeps the timeline legible.
Personal Calendar Mode: Just My Obligations
A company-wide calendar is the right default for a manager who needs the whole picture. It is the wrong default for an individual analyst who only wants to know what they personally owe. PMAP handles this with a personal calendar mode driven by a single request parameter.
When a request includes assigned_to=me, the calendar resolves that shorthand to the authenticated user’s identity and switches into personal mode. An explicit user identifier can also be supplied to view a specific user’s obligations. In personal mode the behavior changes in a precise and deliberate way. The calendar stops fetching project events, scan events, and agreement events entirely. Those are company-wide streams that do not belong to any one analyst, so they are suppressed. What remains is the subset that can actually be owned by an individual, which is SLA deadlines and retest-due events, and even those are filtered down to findings where the user is a direct assignee.
The result is a profile calendar tab that answers a sharper question than the platform view. Not what is due across the whole company, but what is due for me. An analyst opening their personal calendar sees their own SLA deadlines and their own pending retests, with the company-wide noise stripped away. This separation respects how security work is actually distributed. A manager reasons about the program. An analyst reasons about their queue. The same calendar serves both because the personal parameter cleanly narrows the feed to the events an individual is accountable for.
The filtering is enforced at the query layer rather than in the user interface. In personal mode the SLA and retest fetchers join through the finding assignees table and constrain on the requesting user’s identity with an assignee role. That means the narrowing is structural. A user in personal mode cannot accidentally see another user’s obligations, because the queries that would surface them are not run.
Terminal Status Exclusion for SLA Events
A deadline view is only useful if it shows live obligations. A finding that has already been closed has no live deadline worth chasing, and surfacing its old SLA date on the calendar would be pure noise. PMAP handles this with a terminal status exclusion that governs which findings can produce SLA deadline events.
SLA deadline events are emitted only for findings in non-terminal statuses. Four statuses are treated as terminal and excluded. A finding marked closed has been remediated and verified, so its deadline is settled. A finding marked false_positive was never a real exposure, so there is nothing to remediate. A finding marked accepted_risk has been formally signed off, so the deadline no longer applies. A finding marked not_accessible could not be reached for assessment, so no remediation clock is meaningful. In each of these four cases the deadline is no longer an open obligation, and the calendar leaves it out.
This is more than a convenience. It is what keeps a deadline view trustworthy over time. Without the exclusion, the calendar would accumulate stale deadlines from every finding ever raised, and the signal of genuinely upcoming work would drown in resolved history. With it, an SLA deadline on the calendar always means the same thing. There is an open finding, with an unmet remediation clock, due in the window you are looking at.
Notably, the exclusion uses the same terminal-state set that the finding domain’s own state machine uses. The calendar is not inventing its own definition of resolved. It mirrors the definition the finding lifecycle already enforces, so a finding that is terminal everywhere else in the platform is terminal on the calendar too. That consistency is what prevents the confusing situation where a finding looks closed in one view but still nags from the calendar in another.
The Default Three-Month Rolling Window
Every calendar request is bounded by a date window, supplied as a from date and a to date in year-month-day form. The window keeps responses focused and fast, because the calendar only fetches and merges events that fall inside it rather than every dated item in history.
When a caller does not supply the bounds, sensible defaults apply. If the from date is omitted, it defaults to one month before now. If the to date is omitted, it defaults to two months after now. Together these produce a three-month rolling window centered on the present, reaching one month back and two months forward. The to bound is treated inclusively and extended to the end of its day so that an event dated on the final day of the window is not lost to a time-of-day cutoff.
The choice of a backward-and-forward window rather than a purely forward one is deliberate. A pure forward window would only show what is coming. The slight reach into the recent past lets a user see deadlines and milestones that just occurred, which matters for catching a deadline that slipped yesterday or confirming a scan that should have run last week. The forward reach of two months gives enough runway to plan remediation and notice an agreement expiry before it arrives. Of course, a caller who needs a tighter or wider view simply supplies their own from and to bounds, and a dashboard widget that wants a next-seven-days summary requests a narrow window of its own.
A Read-Only Aggregation Layer, Not a New Data Store
It is worth being precise about what the calendar is, because the design choice shapes everything about how it behaves. The calendar is a read-only aggregation layer. It owns no persistent tables of its own and it writes nothing. There is no calendar record created when a finding gets a deadline. There is no calendar entry inserted when a scan is scheduled. The dates continue to live where they always lived, inside the finding, the scan, the project, and the agreement.
When a request arrives, the calendar runs a small set of lightweight queries against those source tables, one per source, each a range scan over an indexed date column. It merges the results in memory, sorts them ascending by date, and returns the sorted slice. The whole operation is synchronous. There is no background job, no queue, and no precomputation. The timeline you receive is assembled fresh from current state at the moment you ask for it.
This architecture has practical consequences worth naming. Because there is no copy of the data, there is nothing to keep in sync and nothing to invalidate when a deadline changes. Edit a finding’s deadline and the next calendar request reflects it immediately, because the next request re-reads the finding. Because the calendar writes nothing, it cannot corrupt or contradict the source domains. It is a pure consumer. And because the queries are bounded range scans on indexed columns within a window, the aggregation stays fast even as the underlying data grows, since the window limits how much each query has to consider.
The trade-off of this model is that the calendar is exactly as current as the tables it reads, no more and no less. That is the right trade-off for an operations timeline, where the value is in reflecting reality rather than in being a separate system of record. For the broader pattern of how live state reaches users across PMAP, the real-time operations cluster covers the push side of the story.
Metadata That Powers the Detail Drawer
A timeline is only the entry point. When a user clicks an event, they want detail, and they want it without a round trip. PMAP supports this by enriching every event with metadata at the moment the calendar assembles it.
Each event carries the identifier and type of the entity it came from, so the interface knows exactly which finding, scan, project, or agreement to open. Each event carries the owning company name, denormalized from a join so the display does not need a second lookup. Finding-sourced events additionally carry severity and status, and project- and finding-sourced events carry status, so a deadline event can show not just a date and a title but the severity of the vulnerability and where it currently sits in its lifecycle.
This is why a calendar detail drawer can open instantly. The drawer does not need to fetch the finding to know its severity and status, because that context was embedded in the event when the calendar built it. A title like an SLA deadline for a specific finding, a description carrying the severity and current status, and the entity reference for deep navigation are all present in the single response that drew the timeline. The metadata turns a flat list of dates into an actionable surface, where a user can triage straight from the calendar and only drill into the full record when they decide to act.
That same metadata is what makes the calendar useful to other surfaces beyond the main view. A dashboard upcoming-events widget can render a compact next-few-days panel from the same enriched events, and a profile calendar tab can present personal obligations with their severity already attached. One enriched feed serves several consumers, because the enrichment travels with each event rather than being recomputed per screen.
How PMAP Keeps Every Deadline in One View
Pulling the pieces together, the PMAP calendar is a single read endpoint that aggregates seven event types from four domains, enriches each event with the context needed to act, sorts everything chronologically, and returns it inside a default three-month window that callers can override. It runs in two modes. The company-wide mode gives a manager the whole program on one timeline, spanning projects, scans, SLA deadlines, retests, and agreement expiry. The personal mode narrows to a single user’s owned SLA deadlines and retests, suppressing the company-wide streams that do not belong to an individual.
Two rules keep the timeline honest. Terminal status exclusion means SLA deadline events only appear for genuinely open findings, so a closed or accepted finding stops nagging the calendar. Deduplication means a finding with multiple assignees produces one event, not many. And one architectural choice keeps the whole thing trustworthy. The calendar reads live from the source domains and stores nothing of its own, so the timeline is always a faithful projection of current state rather than a copy that can drift.
The payoff is the answer to the morning question. Instead of opening five screens and merging them in your head, you open one calendar and read what is due, when, and for whom. A deadline that would otherwise be visible only from inside a finding is now visible on a shared timeline that someone actually looks at. That is the difference between a deadline that is recorded and a deadline that gets met.
To see how the calendar fits alongside alert routing and live push in a full operations workflow, read the notifications and real-time operations datasheet, and review the surrounding cluster on notification routing, SLA escalation, and scan scheduling to understand where each calendar event originates.
Frequently Asked Questions
What is a security operations calendar?
A security operations calendar is a single timeline that surfaces time-sensitive items from across a vulnerability management platform. In PMAP it aggregates seven event types from four domains, covering project start and end milestones, scheduled and running scans, SLA deadlines, retest-due obligations, and framework agreement expiry. Rather than asking a team to track these dates in separate screens, the calendar merges them into one date-sorted feed so that what is due and when is answerable in one place.
Does the calendar store its own copy of deadlines and scan dates?
No. The calendar is a read-only aggregation layer. It owns no persistent tables and writes nothing. On each request it queries the source domains for projects, scans, findings, and framework agreements, merges the results in memory, sorts them by date, and returns them. Because it reads live from the source tables, the timeline always reflects current state, and there is no separate calendar store that can fall out of sync.
What is personal calendar mode and how does it differ from the company view?
Personal calendar mode is activated by an assigned-to parameter resolving to the requesting user. In this mode the calendar stops fetching project, scan, and agreement events, since those are company-wide streams, and returns only the SLA deadlines and retest-due events for findings where the user is a direct assignee. The company-wide view, by contrast, shows all seven event types across accessible companies. Personal mode answers what is due for me, while the company view answers what is due across the program.
Why do some findings not appear as SLA deadlines on the calendar?
SLA deadline events are emitted only for findings in non-terminal statuses. Findings marked closed, false positive, accepted risk, or not accessible are excluded, because their remediation clock is no longer an open obligation. This terminal status exclusion uses the same terminal-state set as the finding lifecycle, so a finding that is resolved elsewhere in the platform stops appearing on the deadline timeline too. The rule keeps the calendar focused on live work rather than resolved history.
What date range does the calendar show by default?
If a request does not supply explicit bounds, the calendar defaults to a three-month rolling window, reaching from one month before now to two months ahead. The backward reach lets a user catch deadlines and milestones that just passed, and the forward reach gives runway to plan upcoming remediation and agreement renewal. Callers can override the window by supplying their own from and to dates in year-month-day form, which is how a dashboard widget requests a narrower next-few-days summary.
How can clicking a calendar event show detail without another request?
Each event is enriched at query time with the originating entity’s identifier and type, the owning company name, and, where relevant, severity and status. Because that context travels inside the event itself, a calendar detail drawer can render severity, status, and a deep link straight from the data already returned, with no second call back to the server. This enrichment also lets other surfaces, like a dashboard upcoming-events widget, reuse the same feed.
Can a single finding with several assignees clutter the calendar with duplicate events?
No. The SLA and retest fetchers use a distinct select joined through the finding assignees table, so a finding with multiple assignees produces one calendar event rather than one per assignee. In personal mode that same join is what narrows the feed to the requesting user’s findings. The deduplication keeps the company-wide timeline clean while the join keeps the personal timeline scoped to obligations a user actually owns.