Standard operating procedures for daily operations, incident response, and escalation paths for QuorumProof platform operators.
- Daily Operations
- Monitoring & Alerting
- Incident Response
- Escalation Procedures
- Maintenance Windows
- Disaster Recovery
- Contact Information
Time: Start of each shift (every 8 hours)
Checklist:
- Check monitoring dashboard for alerts
- Review contract event logs from past 8 hours
- Verify all contract instances are responding
- Check RPC endpoint health
- Review dispute queue for pending resolutions
- Verify admin key accessibility (hardware wallet connected)
- Check IPFS pinning service status
- Review credential issuance volume (compare to baseline)
Tools:
- Grafana dashboard:
https://monitoring.quorumproof.io/grafana - Soroban RPC:
https://soroban-testnet.stellar.org(testnet) orhttps://soroban-mainnet.stellar.org(mainnet) - IPFS status:
ipfs daemon --statsor Pinata dashboard
Expected Baseline:
- Credential issuance: 10-50 per day (testnet), 100-500 per day (mainnet)
- Dispute filings: 0-5 per day
- Failed transactions: < 1% of total
Action if Baseline Exceeded:
- Investigate unusual activity (see Section 3: Incident Response)
- Check for DDoS or spam attacks
- Review recent contract changes
Time: Every hour, automated
Checks:
# Check contract responsiveness
stellar contract invoke \
--network testnet \
--contract $CONTRACT_QUORUM_PROOF \
-- get_credential_count
# Check RPC latency
time curl -X POST https://soroban-testnet.stellar.org \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getLatestLedger","params":[]}'
# Check IPFS connectivity
ipfs swarm peers | wc -l
# Check contract pause status
stellar contract invoke \
--network testnet \
--contract $CONTRACT_QUORUM_PROOF \
-- is_pausedExpected Results:
get_credential_count: Returns u64 (no error)- RPC latency: < 500ms
- IPFS peers: > 10
is_paused: false
Action if Check Fails:
- See Section 3: Incident Response
Time: Once per day (recommended: 00:00 UTC)
Procedure:
- Export credential count:
get_credential_count() - Export slice count:
get_slice_count() - Export revocation count:
get_revoked_count() - Compare to previous day
- Flag unusual changes (> 50% increase/decrease)
Script:
#!/bin/bash
DATE=$(date +%Y-%m-%d)
CRED_COUNT=$(stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_credential_count)
SLICE_COUNT=$(stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_slice_count)
REVOKED_COUNT=$(stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_revoked_count)
echo "$DATE,credentials=$CRED_COUNT,slices=$SLICE_COUNT,revoked=$REVOKED_COUNT" >> audit.logRetention: Keep audit logs for 2 years
Time: Twice per day (08:00 UTC, 16:00 UTC)
Procedure:
- Query pending disputes:
get_pending_disputes() - For each dispute:
- Check filing timestamp
- Verify evidence hash is accessible on IPFS
- Notify slice members if > 24 hours old
- Escalate if > 7 days old (see Section 4: Escalation)
Script:
#!/bin/bash
DISPUTES=$(stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_pending_disputes)
for DISPUTE_ID in $DISPUTES; do
DISPUTE=$(stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_dispute $DISPUTE_ID)
FILED_AT=$(echo $DISPUTE | jq .filed_at)
EVIDENCE_HASH=$(echo $DISPUTE | jq .evidence_hash)
# Check if evidence is available on IPFS
ipfs cat $EVIDENCE_HASH > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "WARNING: Evidence unavailable for dispute $DISPUTE_ID"
fi
# Check age
AGE_HOURS=$(( ($(date +%s) - $FILED_AT) / 3600 ))
if [ $AGE_HOURS -gt 24 ]; then
echo "ALERT: Dispute $DISPUTE_ID pending for $AGE_HOURS hours"
fi
doneFrequency: Quarterly (every 90 days)
Keys to Rotate:
- Admin Stellar account (if single-sig; multi-sig rotates individual signers)
- Issuer accounts (if managed by operator)
- ZK prover private key (annually)
Procedure:
- Generate new key
- Test new key with testnet deployment
- Schedule rotation window (low-traffic period)
- Update key in hardware wallet
- Document old key in secure archive
- Verify new key works with all operations
Backup:
- Store encrypted backup in secure vault
- Maintain geographically distributed copies
- Test recovery procedure quarterly
| Metric | Threshold | Severity | Action |
|---|---|---|---|
| RPC Latency | > 1000ms | High | Check RPC endpoint, consider failover |
| Contract Error Rate | > 5% | High | Investigate error logs |
| Credential Issuance Rate | > 2x baseline | Medium | Check for spam, investigate source |
| Dispute Filing Rate | > 10/day | Medium | Monitor for abuse |
| IPFS Availability | < 80% | High | Check pinning service, add replicas |
| TTL Expiry Events | > 0 | Critical | Immediate investigation (data loss) |
| Pause Events | Any | High | Verify admin action, check logs |
| Unauthorized Auth Attempts | > 0 | Critical | Investigate potential attack |
Grafana Alerts:
- alert: HighRPCLatency
expr: rpc_latency_ms > 1000
for: 5m
annotations:
summary: "RPC latency high: {{ $value }}ms"
action: "Check RPC endpoint health"
- alert: HighContractErrorRate
expr: rate(contract_errors[5m]) > 0.05
for: 5m
annotations:
summary: "Contract error rate: {{ $value }}"
action: "Review contract logs"
- alert: UnusualCredentialVolume
expr: rate(credentials_issued[1h]) > 2 * avg_over_time(credentials_issued[24h])
for: 10m
annotations:
summary: "Credential issuance spike"
action: "Investigate source, check for spam"
- alert: TTLExpiryDetected
expr: ttl_expiry_events > 0
for: 1m
annotations:
summary: "TTL expiry detected (data loss)"
action: "CRITICAL: Immediate investigation required"Logs to Collect:
- Contract event logs (Soroban RPC)
- RPC endpoint logs
- IPFS daemon logs
- Application logs (API server, dashboard)
- Admin action logs
Retention: 90 days (hot), 2 years (archive)
Tools: ELK Stack, Datadog, or CloudWatch
| Severity | Response Time | Escalation | Example |
|---|---|---|---|
| Critical | Immediate (< 5 min) | Level 2 | Data loss, unauthorized access, contract exploit |
| High | 15 minutes | Level 1 | Service degradation, high error rate, DDoS |
| Medium | 1 hour | Level 1 | Unusual activity, performance degradation |
| Low | 4 hours | None | Minor bugs, documentation issues |
Scenario: TTL Expiry Detected (Data Loss)
Steps:
-
Immediate (< 1 min):
- Pause contract:
pause() - Alert Level 2 on-call engineer
- Notify stakeholders
- Pause contract:
-
Investigation (1-5 min):
- Identify affected credentials
- Check TTL extension logs
- Determine root cause (code bug, missed extension, etc.)
-
Remediation (5-30 min):
- If code bug: Deploy fix
- If missed extension: Manually extend TTL
- Restore from backup if necessary
-
Verification (30-60 min):
- Verify affected credentials are recoverable
- Test contract operations
- Unpause contract
-
Post-Incident (1-24 hours):
- Root cause analysis
- Implement preventive measures
- Update runbook
Escalation: Immediately to Level 2 (Security Lead)
Scenario: Unauthorized Credential Issuance
Steps:
-
Immediate (< 1 min):
- Pause contract
- Alert Level 2 on-call engineer
- Preserve transaction logs
-
Investigation (1-10 min):
- Identify unauthorized issuer
- Check if issuer key was compromised
- Determine scope (how many credentials issued)
-
Remediation (10-30 min):
- Revoke unauthorized credentials
- Rotate compromised key
- Deploy contract fix if vulnerability found
-
Verification (30-60 min):
- Verify revocations are effective
- Test contract with new key
- Unpause contract
-
Post-Incident (1-24 hours):
- Security audit
- Notify affected parties
- Update security procedures
Escalation: Immediately to Level 2 (Security Lead) and Level 3 (CISO)
Scenario: High Error Rate (> 5%)
Steps:
-
Immediate (< 5 min):
- Check RPC endpoint health
- Review error logs
- Check contract state
-
Investigation (5-15 min):
- Identify error type (contract error, RPC error, network error)
- Check for recent deployments
- Check for DDoS or spam
-
Remediation (15-60 min):
- If RPC issue: Failover to backup RPC
- If contract issue: Pause and investigate
- If DDoS: Enable rate limiting
-
Verification (60-120 min):
- Monitor error rate
- Verify normal operation
- Document root cause
Escalation: To Level 1 (On-call Engineer) if not resolved in 15 minutes
Scenario: Service Degradation (RPC Latency > 1000ms)
Steps:
-
Immediate (< 5 min):
- Check RPC endpoint status
- Check network connectivity
- Review recent changes
-
Investigation (5-15 min):
- Check RPC logs for errors
- Monitor latency trend
- Check for DDoS
-
Remediation (15-60 min):
- If RPC overloaded: Failover to backup RPC
- If network issue: Contact ISP
- If DDoS: Enable rate limiting
-
Verification (60-120 min):
- Monitor latency
- Verify normal operation
Escalation: To Level 1 (On-call Engineer) if not resolved in 15 minutes
INCIDENT REPORT
===============
ID: INC-2026-05-29-001
Severity: [Critical/High/Medium/Low]
Status: [Open/Resolved/Closed]
Timeline:
- 2026-05-29 14:30 UTC: Alert triggered
- 2026-05-29 14:32 UTC: On-call engineer notified
- 2026-05-29 14:35 UTC: Investigation started
- 2026-05-29 14:45 UTC: Root cause identified
- 2026-05-29 15:00 UTC: Fix deployed
- 2026-05-29 15:15 UTC: Verified resolved
Root Cause:
[Description of root cause]
Impact:
- Affected users: [number]
- Affected credentials: [number]
- Duration: [time]
Resolution:
[Description of fix]
Prevention:
[Steps to prevent recurrence]
Lessons Learned:
[What we learned]
Owner: [Name]
Reviewer: [Name]
Level 0: Automated monitoring and alerting
- No human intervention required
- Automatic remediation (e.g., failover)
Level 1: On-call Engineer
- Response time: 15 minutes
- Authority: Investigate, implement fixes, pause contract
- Cannot: Deploy to mainnet, rotate admin keys
Level 2: Security Lead
- Response time: 30 minutes
- Authority: All Level 1 + security decisions, key rotation
- Cannot: Override business decisions
Level 3: CISO / Executive
- Response time: 1 hour
- Authority: All Level 2 + business decisions, public communication
- Cannot: Technical decisions (deferred to Level 2)
| Condition | Escalate To | Reason |
|---|---|---|
| Incident not resolved in 15 min | Level 1 | Requires human intervention |
| Security incident | Level 2 | Requires security expertise |
| Data loss or corruption | Level 2 | Requires security review |
| Mainnet impact | Level 3 | Requires executive approval |
| Public communication needed | Level 3 | Requires executive decision |
| Regulatory notification required | Level 3 | Requires legal review |
See Section 7: Contact Information
Frequency: Monthly (first Sunday of each month)
Duration: 2 hours (02:00-04:00 UTC)
Activities:
- Contract upgrades
- Dependency updates
- Database maintenance
- Security patches
Notification:
- Announce 2 weeks in advance
- Send reminder 24 hours before
- Post status updates during maintenance
Before Maintenance:
- Backup contract state
- Backup database
- Notify stakeholders
- Prepare rollback plan
- Test changes on testnet
During Maintenance:
- Pause contract
- Deploy changes
- Run smoke tests
- Monitor for errors
- Unpause contract
After Maintenance:
- Verify all operations
- Check monitoring dashboard
- Document changes
- Send completion notification
Trigger: Critical security vulnerability or data loss
Procedure:
- Pause contract immediately
- Assess impact
- Develop fix
- Deploy fix to testnet
- Test thoroughly
- Deploy to mainnet
- Unpause contract
- Notify stakeholders
No advance notice required (security incident)
What to Backup:
- Contract state (ledger entries)
- Database (credentials, slices, disputes)
- Configuration files
- Admin keys (encrypted)
Backup Frequency:
- Contract state: Continuous (Stellar ledger)
- Database: Daily (incremental), Weekly (full)
- Configuration: On change
- Keys: On rotation
Backup Location:
- Primary: Secure vault (on-premises)
- Secondary: Cloud storage (encrypted)
- Tertiary: Geographically distributed (different region)
Scenario: Database Corruption
Steps:
- Pause contract
- Restore database from latest backup
- Verify data integrity
- Replay transactions from contract logs
- Unpause contract
RTO: 1 hour RPO: 1 day
Scenario: Contract State Loss
Steps:
- Pause contract
- Redeploy contract from source
- Restore state from backup
- Verify state matches ledger
- Unpause contract
RTO: 2 hours RPO: Continuous (Stellar ledger is immutable)
Scenario: Admin Key Compromise
Steps:
- Pause contract immediately
- Rotate admin key
- Audit all admin actions since compromise
- Revoke any unauthorized changes
- Unpause contract
RTO: 30 minutes RPO: Depends on detection time
Frequency: Quarterly
Test Scenarios:
- Database restore from backup
- Contract state recovery
- Admin key rotation
- RPC failover
- IPFS pinning service failover
Documentation: Record test results and any issues found
| Role | Name | Phone | Backup | |
|---|---|---|---|---|
| On-Call Engineer | [Name] | [Phone] | [Email] | [Backup Name] |
| Security Lead | [Name] | [Phone] | [Email] | [Backup Name] |
| CISO | [Name] | [Phone] | [Email] | [Backup Name] |
On-Call Schedule: [Link to calendar]
Level 1 (On-Call Engineer):
- Phone: [Number]
- Slack: #incidents
- Email: oncall@quorumproof.io
Level 2 (Security Lead):
- Phone: [Number]
- Slack: @security-lead
- Email: security@quorumproof.io
Level 3 (CISO):
- Phone: [Number]
- Slack: @ciso
- Email: ciso@quorumproof.io
Stellar Support:
- Email: support@stellar.org
- Slack: [Stellar Dev Slack]
IPFS Support:
- Email: support@protocol.ai
- Slack: [IPFS Community Slack]
Cloud Provider (if applicable):
- Support Portal: [URL]
- Phone: [Number]
# Get credential count
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_credential_count
# Get credential details
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_credential 1
# Check if paused
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- is_paused
# Get pending disputes
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_pending_disputes
# Get slice details
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_slice 1# Pause contract
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF \
--source-account $ADMIN_KEY -- pause
# Unpause contract
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF \
--source-account $ADMIN_KEY -- unpause
# Revoke credential
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF \
--source-account $ISSUER_KEY -- revoke_credential $CREDENTIAL_ID# Check RPC health
curl -X POST https://soroban-testnet.stellar.org \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getLatestLedger","params":[]}'
# Check IPFS connectivity
ipfs swarm peers
# Monitor contract events
stellar contract invoke --network testnet --contract $CONTRACT_QUORUM_PROOF -- get_events
# Check transaction status
stellar transaction info $TX_HASH| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | 2026-05-29 | [Author] | Initial version |
Last Updated: May 29, 2026 Next Review: November 29, 2026
Meaning: The quorumproof_ws_messages_dropped_total counter is growing faster than 0.1 drops/s sustained for 2+ minutes. This means one or more WebSocket clients are consuming messages slower than the server is producing them, causing the per-connection send queue (api-server/src/ws/connectionQueue.ts) to overflow and drop the oldest queued messages. A push-based alert is also dispatched via alertChannels.ts when the in-process drop window counter reaches WS_DROP_ALERT_THRESHOLD (default: 10) within a WS_DROP_ALERT_WINDOW_SECONDS (default: 60s) window.
Impact: Affected clients will miss real-time events. They should reconcile on reconnect via REST (see useRealtimeUpdates.ts which performs a full fetch on reconnect).
Recommended operator response:
- Identify the affected instance: check
quorumproof_ws_connections{instance=...}andquorumproof_ws_messages_dropped_total{instance=...}to pinpoint which replica is dropping. - Inspect client connectivity: are specific clients on slow networks, in tight receive loops, or experiencing high CPU load on their side?
- If drops are concentrated on one client, consider terminating that WebSocket connection (the client will reconnect and reconcile via REST).
- If drops are systemic across many connections, check server CPU and memory — an overloaded server may be unable to drain queues fast enough.
- Tune queue limits for bursty workloads: increase
WS_SEND_QUEUE_MAX_MESSAGES(default: 200) and/orWS_SEND_QUEUE_MAX_BYTES(default: 1 MiB) at the cost of higher memory usage per connection. - Tune alert sensitivity via
WS_DROP_ALERT_THRESHOLD(drops per window before alerting) andWS_DROP_ALERT_WINDOW_SECONDS(observation window length).
Meaning: The API error rate exceeds 10% over the last 5 minutes.
Recommended operator response:
- Check the API server logs for the dominant error type (contract trap, RPC timeout, validation failure).
- Verify Soroban RPC health:
curl -X POST https://soroban-testnet.stellar.org -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"getLatestLedger","params":[]}' - If error rate is climbing, pause the contract to stop further failed writes while investigating.
- If caused by a recent deploy, roll back using
scripts/upgrade_rollback.sh. - See Section 3.2 (High Error Rate scenario) for the full incident procedure.
Meaning: The quorumproof-exporter Prometheus target has been unreachable for more than 1 minute (up == 0).
Recommended operator response:
- Check whether the exporter process is running:
systemctl status quorumproof-exporteror equivalent container health check. - Check exporter logs for startup errors or panics.
- Verify network connectivity between Prometheus and the exporter host/pod.
- Restart the exporter if it has crashed.
- If the exporter is healthy but Prometheus cannot scrape it, check firewall rules and the
scrape_configsinmonitoring/prometheus/prometheus.yml.
Meaning: quorumproof_contract_paused == 1 — an admin has paused the contract. All mutating operations are blocked.
Recommended operator response:
- Confirm the pause was intentional (check admin action logs and Slack/PagerDuty for a corresponding maintenance notice).
- If unintentional, identify who triggered the pause: query the ledger for recent
pause()invocations. - Once the reason is understood and resolved, unpause:
stellar contract invoke --network <net> --contract $CONTRACT_QUORUM_PROOF --source-account $ADMIN_KEY -- unpause - If the pause was triggered by an automated security rule, do not unpause until the triggering condition is investigated.
Meaning: The attestation success rate has been below 50% for 10+ minutes.
Recommended operator response:
- Check for errors in
quorumproof_attestation_*metrics to identify the failure mode (timeout, auth failure, quorum threshold not met). - Verify that attestor nodes in the affected slices are reachable and have valid keys.
- Check whether a recent slice configuration change reduced the effective attestor pool below the threshold.
- Review the quorum slice model docs:
docs/quorum-slice-guide.md.
Meaning: The rate-limit counter is increasing faster than 5 hits/s sustained for 2 minutes, indicating unusual traffic or a misbehaving client.
Recommended operator response:
- Identify the source of rate-limited requests from API access logs (client IP, API key, operation).
- If a single client is responsible, consider temporarily blocking it or reducing its quota.
- If the spike is broad, check for a DDoS pattern and engage your CDN/WAF rate-limiting layer.
- Review
docs/throttling.mdfor configuration options.
Meaning: More than 20 contract errors occurred within a 10-minute window — a sudden burst rather than a sustained high rate.
Recommended operator response:
- Correlate the burst timestamp with recent deployments, cron jobs, or batch operations.
- Inspect contract error codes in the API server logs to identify the dominant error type.
- If the burst is still ongoing and errors are growing, pause the contract.
- If caused by a bad deployment, roll back with
scripts/upgrade_rollback.sh.
Meaning: No successful backup has been recorded in the last 25 hours. The expected backup cadence is every 24 hours.
Recommended operator response:
- Check
scripts/automated_backup.shlogs and the backup job scheduler (cron / CI schedule). - Verify that
quorumproof_backup_last_success_timestampis being updated by the exporter after a successful backup run. - Trigger a manual backup:
./scripts/backup.sh - After the backup completes, confirm
quorumproof_backup_last_success_timestampadvances and the alert resolves. - See
docs/backup-system.mdfor the full backup architecture.
Meaning: quorumproof_backup_verification_status == 0 — the most recent backup failed its integrity check. Restore from this backup may not be possible.
Recommended operator response:
- Run
scripts/verify_backup.shmanually to get detailed failure output. - Check whether the backup storage location is accessible and the archive is intact (no truncation, checksum mismatch).
- If the backup is corrupted, trigger a fresh backup immediately:
./scripts/backup.sh - Verify the new backup passes:
scripts/check_backup_integrity.sh - Investigate the root cause (storage provider issue, interrupted write, etc.) and document in the incident log.
- See
docs/backup-verification.mdfor verification procedures.
Meaning: One or more operations are producing SLA violations (latency above the per-operation threshold defined in quorumproof_query_sla_threshold_seconds).
Recommended operator response:
- Identify the affected
operationlabel from the alert. - Check
quorumproof_contract_invocation_duration_secondshistogram for that operation. - Look for recent changes that could have increased latency: new contract logic, increased data volume, degraded RPC.
- Apply tuning guidance from
docs/performance-tuning-guide.mdsection 4. - If latency is RPC-driven, check
RpcCircuitBreakerOpenalert anddocs/performance-tuning-guide.mdsection 4.2.
Meaning: quorumproof_performance_regression_detected == 1 — p95 latency for an operation is ≥20% above the recorded baseline for 5+ minutes.
Recommended operator response:
- Identify the affected
operationfrom the alert labels. - Check recent deployments: did a contract or API server change land near the regression start time?
- Compare current p95 against the baseline stored in
quorumproof_query_sla_threshold_seconds. - If regression is caused by a new deploy, roll back:
scripts/upgrade_rollback.sh. - See
docs/perf-regression.mdfor the regression detection methodology and baseline update procedure.
Meaning: p95 contract invocation latency for an operation exceeds its configured SLA ceiling for 5+ minutes.
Recommended operator response:
- Check which
operationlabel is firing. - Look for concurrent
RpcCircuitBreakerOpenorDbPoolSaturatedalerts — these are common upstream causes. - If the issue is isolated to one operation, review recent changes to that contract path.
- Apply tuning steps from
docs/performance-tuning-guide.mdsection 4.2. - If latency does not resolve, consider pausing background jobs (
DISABLE_BACKGROUND_JOBS=true) to reduce RPC load.
Meaning: The storage entries estimate is growing faster than 500 entries/s, well above normal credential issuance rates.
Recommended operator response:
- Check
quorumproof_credentials_active_totalandquorumproof_storage_entries_estimateto confirm abnormal growth. - Identify the source: which issuer or API key is responsible for the volume spike?
- Review
docs/operator-health-metrics.mdfor theget_state_metricssnapshot interpretation. - If the growth is caused by a runaway integration, rate-limit or block the caller.
- If it looks like an attack (credential spam), pause the contract and escalate to Level 2.
Meaning: Over 30% of recent credential activity in the last hour has been revocations — a potential sign of issuer compromise or a bulk-revocation event.
Recommended operator response:
- Identify which issuers are performing the revocations (check API access logs and on-chain events).
- Verify whether this is a planned bulk-revocation (e.g., a batch cleanup) or unexpected activity.
- If issuer keys may be compromised, pause the contract and rotate the affected keys immediately (see Section 3.2).
- Notify affected credential holders if the revocations are unauthorized.
Meaning: More than one distinct quorumproof_state_version value is being reported — an upgrade may have partially rolled out, or a stale exporter is scraping an old deployment.
Recommended operator response:
- Check which instances are reporting each state version: filter
quorumproof_state_versionbyinstancelabel. - Verify that all contract instances (if running multiple replicas) are on the same contract hash.
- If a stale exporter is present, remove it from the scrape config or redeploy it pointing at the current contract.
- If a partial upgrade is in progress, follow
docs/contract-upgrade-strategy.mdto complete or roll it back cleanly.
Meaning: A migration job (quorumproof_migration_status == 0 / InProgress) has not advanced its cursor in 30+ minutes.
Recommended operator response:
- Check whether
scripts/migration_orchestrator.pyis still running and healthy. - Inspect migration logs for the stalled
migration_idfrom the alert label. - Check for upstream blockers: RPC errors, storage quota, or credential lock contention.
- If the orchestrator has crashed, restart it:
python3 scripts/migration_orchestrator.py --resume - See
docs/contract-upgrade-strategy.mdfor the paginated migration protocol and recovery steps.
Meaning: More than 10 revocation-category critical events were emitted in the last 15 minutes.
Recommended operator response:
- Check
GET /events/critical/recent?category=revocationfor the specific credentials and issuers involved. - Determine whether this matches scheduled or authorized bulk-revocation activity.
- If unexpected, treat as a potential issuer compromise: pause the contract and escalate to Level 2.
- See
docs/critical-event-alerting.mdfor the full interpretation of revocation events.
Meaning: One or more credential disputes were raised on-chain in the last 5 minutes.
Recommended operator response:
- Retrieve dispute details:
GET /events/critical/recent?category=disputefor topic, ledger, and tx hash. - Add the dispute to the resolution queue (Section 1.4).
- Notify the relevant slice members so they can review the dispute evidence.
- If multiple disputes fire simultaneously, escalate to Level 2 — this may indicate coordinated fraud.
- See
docs/critical-event-alerting.mdfor dispute event interpretation.
Meaning: An upgrade or migration event was detected on-chain in the last 5 minutes.
Recommended operator response:
- Confirm this corresponds to a planned, authorized upgrade: check the maintenance calendar and Slack.
- If unexpected, treat as a security incident: pause the contract immediately and escalate to Level 2.
- Verify the new contract hash matches the expected build artifact.
- Check
GET /events/critical/recent?category=upgradefor ledger and tx details. - See
docs/contract-upgrade-strategy.mdanddocs/contract-upgrade-checklist.md.
Meaning: One or more critical-event alerts failed to reach a configured channel (Slack/PagerDuty) in the last 15 minutes.
Recommended operator response:
- Check
api-serverlogs foralertChannels.tserrors (authentication failures, network timeouts). - Verify Slack webhook and PagerDuty integration keys are valid and not rotated/expired.
- Test channel reachability manually.
- While degraded, monitor
GET /events/critical/recentdirectly — do not assume the absence of alerts means no critical events occurred. - See
docs/critical-event-alerting.mdfor channel configuration and troubleshooting.
Meaning: A secondary region is now serving traffic because the primary region is unreachable.
Recommended operator response:
- Confirm Route 53 health check and DNS failover have completed correctly.
- Investigate the primary region outage: check cloud provider status page and instance health.
- Decide whether to run a planned promotion:
scripts/region_failover.sh plannedonce the primary is confirmed unavailable for an extended period. - When the primary recovers, follow the failback procedure in
docs/multi-region-failover.mdbefore switching DNS back. - Do not switch back without verifying Aurora data replication has caught up.
Meaning: A region cannot reach its peer region for 5+ minutes. Failover capacity is degraded.
Recommended operator response:
- Check the network link between regions (VPC peering, Transit Gateway, or direct connect health).
- Verify the peer region's health endpoint from the alerting region.
- If the primary region cannot reach the secondary, failover capacity is lost — treat this as high priority.
- Engage the cloud provider if the network link itself is faulty.
- See
docs/multi-region-failover.mdfor the full failover architecture.
Meaning: The p95 API response latency has exceeded 500 ms for 10+ minutes.
Recommended operator response:
- Check whether
RpcCircuitBreakerOpenorDbPoolSaturatedalerts are also firing — they are common causes. - Review
docs/performance-tuning-guide.mdsection 4.2 for tuning steps. - Check API server CPU and memory usage for resource exhaustion.
- If latency is RPC-driven, consider increasing
RPC_POOL_SIZEor switching to the backup RPC endpoint.
Meaning: The p99 API response latency has exceeded 2 s for 5+ minutes. Tail latency is critically high.
Recommended operator response:
- Check the RPC circuit breaker state (
quorumproof_rpc_circuit_breaker_state). - Check the concurrency queue depth — the API server may be queueing requests behind a saturated RPC pool.
- Reduce concurrency: lower
RPC_MAX_CONCURRENT_REQUESTStemporarily to shed tail latency. - See
docs/performance-tuning-guide.mdsection 4.2.
Meaning: quorumproof_rpc_circuit_breaker_state == 2 — the Soroban RPC circuit breaker has tripped. Verification requests are being served from cache or failing fast.
Recommended operator response:
- Check the Soroban RPC endpoint health directly.
- Review the circuit breaker error log in the API server for the failure that tripped it.
- If the RPC is recovering, the breaker will automatically move to half-open and probe. Do not manually reset unless necessary.
- If the RPC is persistently down, switch to the backup RPC URL in the API server config.
- See
docs/performance-tuning-guide.mdsection 4.2 for breaker configuration.
Meaning: Database connection pool utilisation exceeds 90%, or requests are waiting for a connection.
Recommended operator response:
- Check which query paths are holding connections longest (slow query log).
- Check for long-running transactions that are not releasing connections.
- Temporarily reduce background job concurrency (
BACKGROUND_JOB_CONCURRENCY) to free pool capacity. - If the load is genuinely growing, increase
DB_POOL_MAXand add read replicas. - See
docs/performance-tuning-guide.mdsection 4.2.
Meaning: WebSocket message drop rate exceeds 1 drop/s sustained for 5+ minutes. Slow consumers are overflowing send queues.
Recommended operator response:
- Identify affected connections via
quorumproof_ws_messages_dropped_total{instance=...}. - Check for slow or stalled consumers — clients on poor network connections or in tight processing loops.
- Consider terminating connections with consistently large queues so clients reconnect and reconcile via REST.
- Increase
WS_SEND_QUEUE_MAX_MESSAGESif the workload is bursty and clients can catch up after spikes. - See the
#ws-message-dropssection above for full tuning guidance.
Meaning: Rolling 24-hour gas cost has exceeded 80% of the configured daily budget.
Recommended operator response:
- Identify top-spending operations:
GET /api/costs/optimizations. - Review whether recent usage growth is expected or anomalous.
- Apply tuning steps from
docs/cost-alert-thresholds.md§Reducing Cost before the critical threshold is reached. - Consider increasing
quorumproof_cost_daily_budget_stroopsif legitimate usage has grown.
Meaning: Rolling 24-hour gas cost has exceeded 100% of the configured daily budget.
Recommended operator response:
- Immediate: check
GET /api/costs/reportfor the top spenders. - Apply quick wins from
GET /api/costs/optimizations. - Consider setting
DISABLE_BACKGROUND_JOBS=trueto shed non-critical gas spend immediately. - Throttle or block high-volume callers if the overage is caused by a runaway integration.
- See
docs/cost-alert-thresholds.md§Emergency Response.
Meaning: A single operation consumed more than 50% of the expected hourly budget allocation in the last hour.
Recommended operator response:
- Identify the
operationlabel from the alert. - Investigate at
GET /api/costs/projection?operation=<name>&callsPerDay=...to understand the cost driver. - Check whether call volume spiked or per-call cost increased (e.g., larger payloads, more storage writes).
- Apply per-operation tuning from
docs/cost-alert-thresholds.md§Per-Operation Tuning.