@idriszade/ma2-deadline-watchdog
v0.1.0
Published
Deadline and expiry watchdog: scans items with dates, classifies urgency, generates action recommendations
Downloads
77
Maintainers
Readme
MA2 — Deadline Watchdog
Scans a portfolio of expiring items (contracts, licenses, certificates, insurance, SLAs) and returns urgency-classified alerts with LLM recommendations for items that need action.
Pipeline
[input] -> validate -> classifyUrgency (pure, per item) -> partition flagged/ok
-> if any flagged: LLM batch recommendations -> merge per-item
-> computeSummary (pure) -> [alerts + summary + meta]Key design: urgency classification is 100% deterministic. LLM fires only when at least one item is expired, critical, warning, or notice. Items classified ok receive an empty recommendation and skip the LLM call entirely.
Tool surface
runMA2(input, deps?)— returnsResult<MA2Output, MA2Error>classifyUrgency(expiryDate, now, thresholds)— pure, exported for compositioncomputeSummary(alerts)— pure bucket counter, exported for composition- MCP tool:
ma2_deadline_watchdog
Input (key fields)
| Field | Type | Required |
|---|---|---|
| items | WatchedItem[] (min 1) | yes |
| items[].itemId | string | yes |
| items[].itemType | string (free-text) | yes |
| items[].name | string | yes |
| items[].expiryDate | ISO 8601 string | yes |
| items[].autoRenew | boolean | yes |
| items[].currency | string | yes |
| items[].value | number | no |
| items[].stakeholder | string | no |
| items[].renewalTerms | string | no |
| now | ISO 8601 string | yes |
| thresholds | { criticalDays, warningDays, noticeDays } | yes |
Output (key fields)
alerts[] (one per item): itemId, urgency ('expired'|'critical'|'warning'|'notice'|'ok'), daysRemaining (negative if expired), recommendation, suggestedAction ('renew'|'renegotiate'|'cancel'|'escalate'|'no_action'); summary.totalScanned, summary.expired, summary.critical, summary.warning, summary.notice, summary.ok; meta.analysisMs, meta.thresholds
Test coverage
| Layer | File | Tests | What it verifies |
|---|---|---|---|
| Unit — classifyUrgency | tests/pipeline.test.ts | 7 | Each urgency band (expired/critical/warning/notice/ok), boundary at day 0, custom thresholds |
| Unit — computeSummary | tests/pipeline.test.ts | 2 | All-bucket mixed count, all-ok zero counts |
| Integration | tests/pipeline.test.ts | 4 | Happy path expired item, all-ok skips LLM (throwing stub), validation error, process failure prefix |
| Property | tests/pipeline.test.ts | 3 | daysRemaining always correct for any date offset, urgency always in valid enum, totalScanned == sum of buckets |
| Scenario | tests/scenario.test.ts | 6 | Full 5-band mixed portfolio, all expired batch, single-item expiring tomorrow, auto-renew items still classified, minimal-fields run, large 55-item portfolio |
| Business | tests/business.test.ts | 5 | Insurance cascade (5 policies, 5 urgency bands), SaaS license audit (3 auto-renewed expired), certification expiry (SOC2/ISO/PCI), urgency is time-based not value-based invariant, fiscal year-end crunch (4 same-date items) |
| Cross-atom | packages/meta-flow-tests/ | 3 | MA2 in Flow 2 (MA2→MA1 renewal), Flow 5 (full cycle), Flow 6 invariant (MA2 critical→MA1 no validation error) |
Business scenarios tested
| Scenario | Domain | Business invariant |
|---|---|---|
| Insurance cascade | Risk / compliance | 5-band urgency: GL (5d)=critical, PL (22d)=warning, Cyber (55d)=notice, D&O (80d)=notice, WC (120d)=ok |
| SaaS license audit | FinOps | Auto-renewed items still classified; 3 expired auto-renewals still get recommendations |
| Certification expiry | Compliance | SOC2 expired −10 days=expired; ISO 65 days=notice; PCI 210 days=ok; recommendation blank for ok |
| Urgency is time-based | Procurement | $5K contract (3 days)=critical; $500K contract (180 days)=ok; value ignored |
| Fiscal year-end crunch | Finance | 4 items with same expiry date all get identical daysRemaining and urgency=critical |
Composition flows
- Flow 2: MA2 flags Stripe contract as
critical(5 days remaining,daysRemaining <= 7) → MA1 receives the alert'srecommendationas a context item and gates the $250K renewal requiring CFO escalation - Flow 5: participates in full Meridian Corp month-end BizOps cycle as the first step — scans 3 items (Stripe critical, SOC2 cert warning, Datadog notice) and passes the critical alert to MA1
- Flow 6 (invariant):
classifyUrgency('2026-05-14', '2026-05-11', thresholds)returnscriticalwithdaysRemaining=3, which feeds a valid MA1 input without triggering validation errors
Error codes
| Code | Type | When |
|---|---|---|
| ma2_input_invalid | validation | Schema validation fails (empty items array, missing required fields) |
| ma2_recommendation_<code> | Propagated from process | LLM process returns a ProcessError; the atom prefixes its own code |
Running
pnpm vitest run atoms/ma2-deadline-watchdog