Render Runbook
Purpose: Store renders, compute diffs, and manage retention.
First Diagnostic Question
Is the delta wrong? (false positives, missed changes, reordering noise)
If yes, investigate render and diff logic before summarization.
Inputs
- Latest
section_hashesfrom tracker - Previous render (if any)
Process Steps
1. Render Record
- Create a lightweight render entry (hashes + timestamps)
2. Diffing
- Compare section hashes by ID
- Classify: added / removed / changed / reordered
3. Summarizable Delta
- Extract only changed sections' normalized snippets (bounded)
4. Retention
- Keep last N renders (policy-based)
- Prune older renders without affecting audits
Diagnostic Decision Tree
Render/Diff issue suspected
│
├─ False positives? (changes reported but nothing meaningful changed)
│ ├─ Reordering detected as change → Section ID stability issue
│ ├─ Cosmetic changes surfaced → Tracker normalization issue (go to tracker)
│ └─ Same content, different hash → Hash determinism issue
│
├─ Missed changes? (known changes not detected)
│ ├─ Change between checks but same hash → Content was reverted
│ ├─ Section not tracked → New section not captured
│ └─ Change too small → Below diff threshold
│
├─ Diff inconsistent?
│ ├─ Same inputs, different output → Non-deterministic comparison
│ └─ Section ordering affects results → ID-based comparison broken
│
└─ Storage issues?
├─ Renders not persisting → Database write failure
├─ Historical data missing → Retention policy too aggressive
└─ Corruption suspected → Data integrity check needed
Common Failure Scenarios
False Positives (Noise)
Symptoms:
- Users receive alerts for trivial or cosmetic changes
- Reordering triggers change detection
- Frequent churn on same section
Actions:
- Verify against the meaningful change spec
- Inspect section hashes for instability (may be tracker issue)
- Check if reordering should be suppressed
- Increase suppression thresholds if needed
Principle: Silence is preferable to noise.
Missed Changes
Symptoms:
- Known page changes not surfaced
- User reports change not detected
Actions:
- Confirm change persisted between checks (wasn't reverted)
- Review if change fell below detection threshold
- Check if section was newly added (baseline issue)
- Verify cadence alignment - change may have happened between checks
Diff Non-Determinism
Symptoms:
- Same URL produces different diffs on re-run
- Inconsistent delta output
Actions:
- Check section ID generation stability
- Verify hash comparison is order-independent where appropriate
- Review any caching that might affect results
- Test with known-stable input
Storage/Retention Issues
Symptoms:
- Historical renders missing
- Unable to compute diff (no baseline)
- Audit trail gaps
Actions:
- Check retention policy settings
- Verify database writes are succeeding
- Review storage quotas
- Restore from backup if corruption suspected
Stop Conditions
Hard Stop
Trigger immediately if any are true:
- Diff output is inconsistent or non-deterministic
- Render persistence risks corrupting historical state
Action: Treat affected URLs as baseline and halt diff emission.
Degrade Mode
- Skip diffing and mark run as baseline
- Preserve raw hashes for later reprocessing
Resume once diff stability is verified.
Signals to Watch
| Signal | Indicates |
|---|---|
| Reordering without content change | Section ID instability |
| Frequent churn in single section | Dynamic content not filtered |
| Diff output variance | Non-deterministic comparison |
| Missing historical renders | Retention or storage issue |
Database Queries
Check render history for a URL
SELECT id, url_id, section_count, created_at
FROM url_renders
WHERE url_id = '<url_id>'
ORDER BY created_at DESC
LIMIT 10;
Find URLs with high diff frequency
SELECT url_id, COUNT(*) as diff_count
FROM url_changes
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY url_id
ORDER BY diff_count DESC
LIMIT 20;
Check for potential false positives (high churn)
SELECT url_id, COUNT(*) as changes,
COUNT(DISTINCT DATE(created_at)) as days_with_changes
FROM url_changes
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY url_id
HAVING COUNT(*) > 5
ORDER BY changes DESC;
Related Runbooks
- Incident Playbook - Master triage
- Tracker - If input is wrong (upstream issue)
- Summarization - If delta is correct but output is wrong