Doctor plugin checks: implement health check classes and documentation

Implement remediation-aware health checks across all Doctor plugin modules
(Agent, Attestor, Auth, BinaryAnalysis, Compliance, Crypto, Environment,
EvidenceLocker, Notify, Observability, Operations, Policy, Postgres, Release,
Scanner, Storage, Vex) and their backing library counterparts (AI, Attestation,
Authority, Core, Cryptography, Database, Docker, Integration, Notify,
Observability, Security, ServiceGraph, Sources, Verification).

Each check now emits structured remediation metadata (severity, category,
runbook links, and fix suggestions) consumed by the Doctor dashboard
remediation panel.

Also adds:
- docs/doctor/articles/ knowledge base for check explanations
- Advisory AI search seed and allowlist updates for doctor content
- Sprint plan for doctor checks documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-27 12:28:00 +02:00
parent fbd24e71de
commit c58a236d70
326 changed files with 18500 additions and 463 deletions

View File

@@ -11,6 +11,7 @@
"docs/modules/router",
"docs/modules/scanner",
"docs/operations",
"docs/operations/devops/runbooks"
"docs/operations/devops/runbooks",
"docs/doctor/articles"
]
}

View File

@@ -34,6 +34,22 @@
- Evidence logs are JSONL with deterministic ordering and include `doctor_command`.
- DSSE summaries assume operator execution and include the same command note.
## Article Requirement (MANDATORY)
Every `IDoctorCheck` implementation MUST have a corresponding documentation article.
**When creating or modifying a Doctor check:**
1. **Article**: Create/update `docs/doctor/articles/<plugin>/<check-slug>.md` using the template at `docs/doctor/articles/_TEMPLATE.md`. The article must include deployment-specific fix steps for Docker Compose, bare metal, and Kubernetes.
2. **RunbookUrl**: Call `.WithRunbookUrl("docs/doctor/articles/<plugin>/<check-slug>.md")` in the check's `WithRemediation()` builder so the Doctor UI links to the article.
3. **Search seed**: Add/update an entry in `src/AdvisoryAI/StellaOps.AdvisoryAI/KnowledgeSearch/doctor-search-seed.json` with `checkCode`, `title`, `severity`, `description`, `remediation`, `runCommand`, `symptoms`, `tags`, and `references` pointing to the article.
**File naming**: `check.agent.heartbeat.freshness``docs/doctor/articles/agent/heartbeat-freshness.md`
**PR reviewers MUST reject checks that are missing any of these three artifacts.**
## Testing
- Doctor engine tests: `src/__Libraries/__Tests/StellaOps.Doctor.Tests`
- Plugin tests: `src/__Libraries/__Tests/StellaOps.Doctor.Plugins.*.Tests`

View File

@@ -83,7 +83,8 @@ public sealed class AgentCapacityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Bootstrap new agents if needed",
"stella agent bootstrap --name <name> --env <env>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/capacity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -158,7 +158,8 @@ public sealed class AgentCertificateExpiryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check agent logs for renewal failures",
"stella agent logs --agent-id <agent-id> --level warn",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/certificate-expiry.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -184,7 +185,8 @@ public sealed class AgentCertificateExpiryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Optionally force early renewal",
"stella agent renew-cert --agent-id <agent-id>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/certificate-expiry.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -83,7 +83,8 @@ public sealed class AgentHeartbeatFreshnessCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check agent registration status",
"stella agent list --all",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/heartbeat-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -174,7 +175,8 @@ public sealed class AgentHeartbeatFreshnessCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Monitor heartbeat trend",
"stella agent logs --agent-id <agent-id> --tail 50",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/heartbeat-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -117,7 +117,8 @@ public sealed class AgentVersionConsistencyCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Enable auto-update if appropriate",
"stella agent config --agent-id <id> --set auto_update.enabled=true",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/version-consistency.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -110,7 +110,8 @@ public sealed class StaleAgentCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "If agent should be active, investigate host",
"ssh <agent-host> 'systemctl status stella-agent'",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/stale.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -136,7 +137,8 @@ public sealed class StaleAgentCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Restart agent service",
"ssh <agent-host> 'systemctl restart stella-agent'",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/agent/stale.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -79,7 +79,8 @@ public sealed class CosignKeyMaterialCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Configure signing mode",
"stella attestor signing configure --mode keyless",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/cosign-keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -128,7 +129,8 @@ public sealed class CosignKeyMaterialCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Configure the key path",
"stella attestor signing configure --mode file --key-path /etc/stellaops/cosign.key",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/cosign-keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -154,7 +156,8 @@ public sealed class CosignKeyMaterialCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Update configuration with correct path",
"stella attestor signing configure --key-path <path-to-key>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/cosign-keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -207,7 +210,8 @@ public sealed class CosignKeyMaterialCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Or for GCP KMS",
"stella attestor signing configure --mode kms --kms-key-ref 'gcpkms://projects/.../cryptoKeys/...'",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/cosign-keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -95,7 +95,8 @@ public sealed class RekorClockSkewCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check network connectivity",
$"curl -s {rekorUrl}/api/v1/log",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/clock-skew.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -167,7 +168,8 @@ public sealed class RekorClockSkewCheck : IDoctorCheck
"NTP server unreachable",
"System clock manually set incorrectly",
"Virtual machine clock drift")
.WithRemediation(rb => BuildPlatformSpecificRemediation(rb, ntpStatus, vmStatus))
.WithRemediation(rb => BuildPlatformSpecificRemediation(rb, ntpStatus, vmStatus)
.WithRunbookUrl("docs/doctor/articles/attestor/clock-skew.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -112,7 +112,8 @@ public sealed class RekorConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(4, "If air-gapped, configure offline bundle",
"stella attestor offline-bundle download --output /var/lib/stellaops/rekor-offline",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -137,7 +138,8 @@ public sealed class RekorConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "For air-gapped environments, configure offline mode",
"stella attestor config set --key offline.enabled --value true",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -158,7 +160,8 @@ public sealed class RekorConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check SSL certificates",
"openssl s_client -connect rekor.sigstore.dev:443 -brief",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -89,7 +89,8 @@ public sealed class RekorVerificationJobCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check application logs for errors",
"journalctl -u stellaops-attestor --since '1 hour ago' | grep -i 'verification\\|rekor'",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-verification-job.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -118,7 +119,8 @@ public sealed class RekorVerificationJobCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Contact security team if tampering suspected",
"# This may indicate a security incident. Review evidence carefully.",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-verification-job.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -145,7 +147,8 @@ public sealed class RekorVerificationJobCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "If mismatch persists, escalate to security team",
"# Root hash mismatch may indicate log tampering",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-verification-job.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -173,7 +176,8 @@ public sealed class RekorVerificationJobCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Review recent logs",
"journalctl -u stellaops-attestor --since '48 hours ago' | grep -i error",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-verification-job.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -202,7 +206,8 @@ public sealed class RekorVerificationJobCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Re-sync from Rekor if needed",
"stella attestor verification resync --failed-only",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/rekor-verification-job.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -114,7 +114,8 @@ public sealed class SigningKeyExpirationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Set up key expiration monitoring",
"stella notify channels add --type email --event key.expiring --threshold-days 30",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -135,7 +136,8 @@ public sealed class SigningKeyExpirationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Review all critical keys",
"stella keys status",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -157,7 +159,8 @@ public sealed class SigningKeyExpirationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Schedule rotation with overlap period",
$"stella keys rotate {warningKeys[0].KeyId} --overlap-days 14",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/keymaterial.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -106,7 +106,8 @@ public sealed class TransparencyLogConsistencyCheck : IDoctorCheck
$"cat {checkpointPath}")
.AddStep(2, "Trigger re-sync",
"stella attestor transparency sync",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/transparency-consistency.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -184,7 +185,8 @@ public sealed class TransparencyLogConsistencyCheck : IDoctorCheck
CommandType.Shell)
.AddDestructiveStep(4, "If using wrong log, reset checkpoint (DESTRUCTIVE)",
$"rm {checkpointPath} && stella attestor transparency sync",
$"ls -la {checkpointPath}"))
$"ls -la {checkpointPath}")
.WithRunbookUrl("docs/doctor/articles/attestor/transparency-consistency.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -211,7 +213,8 @@ public sealed class TransparencyLogConsistencyCheck : IDoctorCheck
CommandType.Manual)
.AddStep(2, "Compare with independent source",
"curl -s https://rekor.sigstore.dev/api/v1/log | jq .",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/attestor/transparency-consistency.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -71,7 +71,8 @@ public sealed class AuthConfigurationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Generate signing keys",
"stella keys generate --type rsa",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/config.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -96,7 +97,8 @@ public sealed class AuthConfigurationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check key store health",
"stella doctor --check check.crypto.keystore",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/config.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -122,7 +124,8 @@ public sealed class AuthConfigurationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Schedule key rotation",
"stella keys rotate --schedule 30d",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/config.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -103,7 +103,8 @@ public sealed class OidcProviderConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check network configuration",
"stella doctor --check check.network.dns",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/oidc.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -132,7 +133,8 @@ public sealed class OidcProviderConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check OIDC provider configuration",
"stella auth oidc validate",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/oidc.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -159,7 +161,8 @@ public sealed class OidcProviderConnectivityCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check JWKS endpoint",
$"curl -s {oidcStatus.JwksUri} | jq .",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/oidc.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -69,7 +69,8 @@ public sealed class SigningKeyHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Activate the key",
"stella keys activate",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/signing-key.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -94,7 +95,8 @@ public sealed class SigningKeyHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Schedule automatic rotation",
"stella keys rotate --schedule 30d",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/signing-key.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -74,7 +74,8 @@ public sealed class TokenServiceHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check database connectivity",
"stella doctor --check check.storage.postgres",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/token-service.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -99,7 +100,8 @@ public sealed class TokenServiceHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Review database performance",
"stella doctor --check check.storage.performance",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/token-service.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -121,7 +123,8 @@ public sealed class TokenServiceHealthCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Monitor service metrics",
"stella auth metrics --watch",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/token-service.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -116,7 +116,8 @@ public sealed class BuildinfoCacheCheck : IDoctorCheck
.AddShellStep(3, "Check proxy settings if behind a corporate firewall",
"export HTTPS_PROXY=http://proxy.example.com:8080")
.AddManualStep(4, "For air-gapped environments",
"Pre-populate the buildinfo cache with required files or disable this check"))
"Pre-populate the buildinfo cache with required files or disable this check")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/buildinfo-cache.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -140,7 +141,8 @@ public sealed class BuildinfoCacheCheck : IDoctorCheck
.AddShellStep(1, "Test connectivity",
$"curl -I {BuildinfosUrl}")
.AddManualStep(2, "If air-gapped intentionally",
"Ensure buildinfo cache is pre-populated with required files"))
"Ensure buildinfo cache is pre-populated with required files")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/buildinfo-cache.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -161,7 +163,8 @@ public sealed class BuildinfoCacheCheck : IDoctorCheck
.WithCauses("Cache directory not created")
.WithRemediation(rb => rb
.AddShellStep(1, "Create cache directory",
$"sudo mkdir -p {cacheDir} && sudo chmod 755 {cacheDir}"))
$"sudo mkdir -p {cacheDir} && sudo chmod 755 {cacheDir}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/buildinfo-cache.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -181,7 +184,8 @@ public sealed class BuildinfoCacheCheck : IDoctorCheck
.WithCauses("Insufficient permissions on cache directory")
.WithRemediation(rb => rb
.AddShellStep(1, "Fix cache directory permissions",
$"sudo chown $(whoami) {cacheDir} && chmod 755 {cacheDir}"))
$"sudo chown $(whoami) {cacheDir} && chmod 755 {cacheDir}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/buildinfo-cache.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -92,7 +92,8 @@ public sealed class CorpusMirrorFreshnessCheck : IDoctorCheck
.AddStellaStep(2, "Initialize corpus mirrors",
"groundtruth mirror sync --all")
.AddManualStep(3, "For air-gapped environments",
"Copy pre-populated mirrors from an online system to the mirrors directory"))
"Copy pre-populated mirrors from an online system to the mirrors directory")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-mirror-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -156,7 +157,8 @@ public sealed class CorpusMirrorFreshnessCheck : IDoctorCheck
.AddShellStep(2, "Or sync specific mirrors",
"stella groundtruth mirror sync --source debian")
.AddManualStep(3, "For air-gapped environments",
"Transfer pre-populated mirrors from an online system"))
"Transfer pre-populated mirrors from an online system")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-mirror-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -178,7 +180,8 @@ public sealed class CorpusMirrorFreshnessCheck : IDoctorCheck
.AddShellStep(2, "Check mirror sync job status",
"systemctl status stella-mirror-sync.timer")
.AddManualStep(3, "Set up automatic mirror sync",
$"Configure a cron job or systemd timer to run 'stella groundtruth mirror sync' at least every {staleThresholdDays} days"))
$"Configure a cron job or systemd timer to run 'stella groundtruth mirror sync' at least every {staleThresholdDays} days")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-mirror-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -198,7 +201,8 @@ public sealed class CorpusMirrorFreshnessCheck : IDoctorCheck
.AddStellaStep(1, "Sync stale mirrors",
$"groundtruth mirror sync --sources {string.Join(",", staleMirrors.Select(m => m.Name.Split('/')[0]))}")
.AddShellStep(2, "Check sync logs for errors",
"journalctl -u stella-mirror-sync --since '7 days ago' | grep -i error"))
"journalctl -u stella-mirror-sync --since '7 days ago' | grep -i error")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-mirror-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -212,7 +216,8 @@ public sealed class CorpusMirrorFreshnessCheck : IDoctorCheck
.WithEvidence("Mirror Status", AddMirrorEvidence)
.WithRemediation(rb => rb
.AddManualStep(1, "Optionally add missing mirrors",
$"stella groundtruth mirror sync --sources {string.Join(",", missingMirrors.Select(m => m.Name.Split('/')[0]))}"))
$"stella groundtruth mirror sync --sources {string.Join(",", missingMirrors.Select(m => m.Name.Split('/')[0]))}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-mirror-freshness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -115,7 +115,8 @@ public sealed partial class DdebRepoEnabledCheck : IDoctorCheck
.AddShellStep(2, "Import repository signing key",
"sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622")
.AddShellStep(3, "Update package lists",
"sudo apt update"))
"sudo apt update")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/ddeb-enabled.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -138,7 +139,8 @@ public sealed partial class DdebRepoEnabledCheck : IDoctorCheck
.AddShellStep(2, "Import repository signing key",
"sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622")
.AddShellStep(3, "Update package lists",
"sudo apt update"))
"sudo apt update")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/ddeb-enabled.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -167,7 +169,8 @@ public sealed partial class DdebRepoEnabledCheck : IDoctorCheck
.AddShellStep(2, "Check proxy settings if behind a corporate firewall",
"export HTTP_PROXY=http://proxy.example.com:8080")
.AddManualStep(3, "For air-gapped environments",
"Set up a local ddeb mirror or use offline symbol packages"))
"Set up a local ddeb mirror or use offline symbol packages")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/ddeb-enabled.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -113,7 +113,8 @@ public sealed class DebuginfodAvailabilityCheck : IDoctorCheck
.AddShellStep(2, "Verify network connectivity",
$"curl -I {DefaultFedoraUrl}")
.AddManualStep(3, "For air-gapped environments",
"Set up a local debuginfod mirror or pre-populate the symbol cache. See docs/modules/binary-index/ground-truth-corpus.md for offline setup"))
"Set up a local debuginfod mirror or pre-populate the symbol cache. See docs/modules/binary-index/ground-truth-corpus.md for offline setup")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/debuginfod-available.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -131,7 +132,8 @@ public sealed class DebuginfodAvailabilityCheck : IDoctorCheck
})
.WithRemediation(rb => rb
.AddShellStep(1, "Optionally set DEBUGINFOD_URLS for explicit configuration (recommended for production)",
$"export {DebuginfodUrlsEnvVar}=\"{DefaultFedoraUrl}\""))
$"export {DebuginfodUrlsEnvVar}=\"{DefaultFedoraUrl}\"")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/debuginfod-available.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -158,7 +160,8 @@ public sealed class DebuginfodAvailabilityCheck : IDoctorCheck
.AddShellStep(2, "Check proxy settings if behind a corporate firewall",
"export HTTPS_PROXY=http://proxy.example.com:8080")
.AddManualStep(3, "For air-gapped environments",
"Deploy a local debuginfod instance or use offline symbol bundles. See docs/modules/binary-index/ground-truth-corpus.md for offline setup"))
"Deploy a local debuginfod instance or use offline symbol bundles. See docs/modules/binary-index/ground-truth-corpus.md for offline setup")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/debuginfod-available.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -182,7 +185,8 @@ public sealed class DebuginfodAvailabilityCheck : IDoctorCheck
.AddShellStep(1, "Verify unreachable servers",
$"curl -I {unreachableUrls[0]}")
.AddManualStep(2, "Update DEBUGINFOD_URLS to remove unavailable servers",
$"Edit DEBUGINFOD_URLS to remove: {string.Join(", ", unreachableUrls)}"))
$"Edit DEBUGINFOD_URLS to remove: {string.Join(", ", unreachableUrls)}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/debuginfod-available.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -95,7 +95,8 @@ public sealed class KpiBaselineExistsCheck : IDoctorCheck
.AddStellaStep(2, "Run corpus validation to establish baseline",
"groundtruth validate run --corpus datasets/golden-corpus/seed/ --output-baseline")
.AddStellaStep(3, "Or manually set the current results as baseline",
$"groundtruth baseline update --from-latest --output {baselinePath}"))
$"groundtruth baseline update --from-latest --output {baselinePath}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-kpi-baseline.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -130,7 +131,8 @@ public sealed class KpiBaselineExistsCheck : IDoctorCheck
.AddShellStep(1, "Copy latest baseline to default location",
$"cp {Path.Combine(baselineDir, latest.Filename)} {baselinePath}")
.AddManualStep(2, "Or update configuration to use existing baseline",
$"Set BinaryAnalysis:Corpus:BaselineFilename to '{latest.Filename}'"))
$"Set BinaryAnalysis:Corpus:BaselineFilename to '{latest.Filename}'")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-kpi-baseline.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -154,7 +156,8 @@ public sealed class KpiBaselineExistsCheck : IDoctorCheck
.AddStellaStep(1, "Run corpus validation to establish baseline",
$"groundtruth validate run --corpus datasets/golden-corpus/seed/ --output {baselinePath}")
.AddStellaStep(2, "Or update baseline from existing validation results",
$"groundtruth baseline update --from-latest --output {baselinePath}"))
$"groundtruth baseline update --from-latest --output {baselinePath}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-kpi-baseline.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -189,7 +192,8 @@ public sealed class KpiBaselineExistsCheck : IDoctorCheck
.AddStellaStep(2, "Regenerate baseline from latest validation",
$"groundtruth baseline update --from-latest --output {baselinePath}")
.AddShellStep(3, "Or validate JSON manually",
$"cat {baselinePath} | jq ."))
$"cat {baselinePath} | jq .")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-kpi-baseline.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -219,7 +223,8 @@ public sealed class KpiBaselineExistsCheck : IDoctorCheck
"Partial baseline update")
.WithRemediation(rb => rb
.AddStellaStep(1, "Regenerate complete baseline",
$"groundtruth baseline update --from-latest --output {baselinePath}"))
$"groundtruth baseline update --from-latest --output {baselinePath}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/corpus-kpi-baseline.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -151,7 +151,8 @@ public sealed class SymbolRecoveryFallbackCheck : IDoctorCheck
.AddManualStep(3, "For air-gapped environments",
"Set up an offline symbol bundle. See docs/modules/binary-index/ground-truth-corpus.md for instructions on creating and importing offline symbol packs")
.AddManualStep(4, "Consider setting up a local debuginfod mirror",
"Run a local debuginfod server and point DEBUGINFOD_URLS to it"))
"Run a local debuginfod server and point DEBUGINFOD_URLS to it")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/symbol-recovery-fallback.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -168,7 +169,8 @@ public sealed class SymbolRecoveryFallbackCheck : IDoctorCheck
.WithEvidence("Symbol Recovery Status", AddChildEvidence)
.WithRemediation(rb => rb
.AddManualStep(1, "Optionally configure additional sources for redundancy",
$"The following sources are unavailable: {string.Join(", ", unavailableNames)}"))
$"The following sources are unavailable: {string.Join(", ", unavailableNames)}")
.WithRunbookUrl("docs/doctor/articles/binaryanalysis/symbol-recovery-fallback.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -109,6 +109,7 @@ public sealed class AttestationSigningHealthCheck : IDoctorCheck
rb.AddStep(2, "Verify HSM/KMS connectivity",
"stella attestor hsm test",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/compliance/attestation-signing.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -130,7 +131,8 @@ public sealed class AttestationSigningHealthCheck : IDoctorCheck
})
.WithCauses("Key not rotated before expiry")
.WithRemediation(rb => rb
.AddStep(1, "Rotate signing key", "stella attestor key rotate", CommandType.Shell))
.AddStep(1, "Rotate signing key", "stella attestor key rotate", CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/compliance/attestation-signing.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -147,7 +149,8 @@ public sealed class AttestationSigningHealthCheck : IDoctorCheck
})
.WithCauses("Key approaching end of validity")
.WithRemediation(rb => rb
.AddStep(1, "Schedule key rotation", "stella attestor key rotate --schedule", CommandType.Shell))
.AddStep(1, "Schedule key rotation", "stella attestor key rotate --schedule", CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/compliance/attestation-signing.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -117,6 +117,7 @@ public sealed class AuditReadinessCheck : IDoctorCheck
rb.AddStep(2, "Enable audit logging",
"stella audit enable",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/compliance/audit-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -111,6 +111,7 @@ public sealed class ComplianceFrameworkCheck : IDoctorCheck
rb.AddStep(2, "Review remediation guidance",
"stella compliance remediate --plan",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/compliance/framework.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -115,6 +115,7 @@ public sealed class EvidenceExportReadinessCheck : IDoctorCheck
rb.AddStep(1, "Check export configuration",
"stella evidence export --check",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/compliance/export-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -112,6 +112,7 @@ public sealed class EvidenceGenerationRateCheck : IDoctorCheck
rb.AddStep(2, "Verify signing keys",
"stella evidence keys status",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/compliance/evidence-rate.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -108,6 +108,7 @@ public sealed class EvidenceTamperCheck : IDoctorCheck
.WithSafetyNote("DO NOT delete tampered evidence - preserve for investigation");
rb.AddStep(2, "Investigate security incident", "Contact security team", CommandType.Manual)
.RequiresBackup();
rb.WithRunbookUrl("docs/doctor/articles/compliance/evidence-integrity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -109,6 +109,7 @@ public sealed class ProvenanceCompletenessCheck : IDoctorCheck
rb.AddStep(2, "Generate backfill provenance",
"stella provenance backfill --dry-run",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/compliance/provenance-completeness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -79,7 +79,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Update certificate path",
"stella crypto config set --tls-cert <correct-path>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -109,7 +110,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Update configuration",
"stella crypto config set --tls-cert fullchain.pem",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -133,7 +135,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Or configure explicit trust anchor",
"stella crypto trust-anchors add --type ca --cert root-ca.crt",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -160,7 +163,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Deploy renewed certificate",
"stella crypto config set --tls-cert <new-cert-path>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -179,7 +183,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Renew certificate urgently",
"stella crypto cert renew --cert <cert-path>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -203,7 +208,8 @@ public sealed class CertChainValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Set up automated renewal",
"stella notify channels add --type email --event cert.expiring --threshold-days 14",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/certchain.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -115,7 +115,8 @@ public sealed class EidasComplianceCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Configure eIDAS crypto profile",
"stella crypto profile set --profile eu",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/eidas.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -138,7 +139,8 @@ public sealed class EidasComplianceCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Update minimum RSA key size",
"stella crypto config set --min-rsa-key-size 3072",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/eidas.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -114,6 +114,7 @@ public sealed class FipsComplianceCheck : IDoctorCheck
"Consult your OS documentation for FIPS enablement",
CommandType.Manual);
}
rb.WithRunbookUrl("docs/doctor/articles/crypto/fips.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build());
@@ -149,7 +150,8 @@ public sealed class FipsComplianceCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify crypto algorithms",
"openssl list -digest-algorithms",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/fips.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -94,7 +94,8 @@ public sealed class GostAvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(4, "Configure StellaOps GOST profile",
"stella crypto profile set --profile ru",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/gost.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -135,7 +136,8 @@ public sealed class GostAvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify available algorithms",
"openssl engine gost -c",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/gost.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -68,7 +68,8 @@ public sealed class HsmPkcs11AvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Or for Windows",
"stella crypto config set --hsm-module C:\\SoftHSM2\\lib\\softhsm2.dll",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/hsm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -91,7 +92,8 @@ public sealed class HsmPkcs11AvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Update module path configuration",
"stella crypto config set --hsm-module <correct-path>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/hsm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -118,7 +120,8 @@ public sealed class HsmPkcs11AvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Initialize slot if needed",
"softhsm2-util --init-token --slot 0 --label \"stellaops\"",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/hsm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -145,7 +148,8 @@ public sealed class HsmPkcs11AvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Configure token PIN",
"stella crypto config set --hsm-pin <your-pin>",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/hsm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -106,7 +106,8 @@ public sealed class SmCryptoAvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Or use StellaOps bundled crypto",
"stella crypto config set --provider bundled-sm",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/sm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -135,7 +136,8 @@ public sealed class SmCryptoAvailabilityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Use external SM provider if needed",
"stella crypto config set --sm-provider gmssl",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/sm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -159,7 +161,8 @@ public sealed class SmCryptoAvailabilityCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Verify SM2 curve",
"openssl ecparam -list_curves | grep -i sm2",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/crypto/sm.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -146,6 +146,7 @@ public sealed class EnvironmentCapacityCheck : IDoctorCheck
rb.AddStep(3, "Or remove unused deployments",
$"stella env cleanup {criticalEnvs[0].Name}",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/environment/capacity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -171,6 +172,7 @@ public sealed class EnvironmentCapacityCheck : IDoctorCheck
rb.AddStep(1, "Monitor capacity trend",
"stella env capacity --trend",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/environment/capacity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -164,6 +164,7 @@ public sealed class EnvironmentConnectivityCheck : IDoctorCheck
rb.AddStep(3, "Test network connectivity",
"# Check firewall rules and network routes to environment agent",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/environment/connectivity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -204,6 +205,7 @@ public sealed class EnvironmentConnectivityCheck : IDoctorCheck
$"stella env diagnose {highLatency[0].Name} --network",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/environment/connectivity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -159,6 +159,7 @@ public sealed class EnvironmentDeploymentHealthCheck : IDoctorCheck
rb.AddStep(3, "Rollback if needed",
$"stella release rollback --env {prodFailures[0].Env}",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/environment/deployments.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -182,6 +183,7 @@ public sealed class EnvironmentDeploymentHealthCheck : IDoctorCheck
rb.AddStep(1, "View service logs",
$"stella env logs {failedServices[0].Env} --service {failedServices[0].Service}",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/environment/deployments.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -208,6 +210,7 @@ public sealed class EnvironmentDeploymentHealthCheck : IDoctorCheck
rb.AddStep(1, "View service health",
$"stella env health {degradedServices[0].Env} --service {degradedServices[0].Service}",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/environment/deployments.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -150,6 +150,7 @@ public sealed class EnvironmentDriftCheck : IDoctorCheck
rb.AddStep(3, "Or accept drift as intentional",
$"stella env drift accept {criticalDrifts[0].ConfigKey}",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/environment/drift.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -175,6 +176,7 @@ public sealed class EnvironmentDriftCheck : IDoctorCheck
rb.AddStep(1, "Review drift report",
"stella env drift show",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/environment/drift.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -99,7 +99,8 @@ public sealed class EnvironmentNetworkPolicyCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Configure network isolation",
"stella env network-policy create --default-deny",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/environment/network-policy.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -192,6 +193,7 @@ public sealed class EnvironmentNetworkPolicyCheck : IDoctorCheck
rb.AddStep(2, "Fix production isolation",
$"stella env network-policy update {criticalViolations[0].Environment} --default-deny --allow-from staging",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/environment/network-policy.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -213,7 +215,8 @@ public sealed class EnvironmentNetworkPolicyCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Review policy recommendations",
"stella env network-policy audit",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/environment/network-policy.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -164,6 +164,7 @@ public sealed class EnvironmentSecretHealthCheck : IDoctorCheck
rb.AddStep(2, "Check secret provider status",
"stella secrets provider status",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/environment/secrets.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -196,6 +197,7 @@ public sealed class EnvironmentSecretHealthCheck : IDoctorCheck
"stella env secrets rotate-scheduled --days 7",
CommandType.Manual);
}
rb.WithRunbookUrl("docs/doctor/articles/environment/secrets.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -223,7 +225,8 @@ public sealed class EnvironmentSecretHealthCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "View secrets status",
"stella env secrets list --expiring",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/environment/secrets.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -104,7 +104,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify authentication",
"stella evidence auth-test",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -127,7 +128,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check evidence locker metrics",
"stella evidence metrics",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -163,7 +165,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check evidence locker status",
"stella evidence status",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -183,7 +186,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check service connectivity",
"stella evidence ping",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -219,7 +223,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Initialize evidence locker",
"stella evidence init",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -270,7 +275,8 @@ public sealed class AttestationRetrievalCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check file permissions",
$"ls -la {attestationDir}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/retrieval.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -77,7 +77,8 @@ public sealed class EvidenceIndexCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Rebuild evidence index",
"stella evidence index rebuild",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/index.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -155,7 +156,8 @@ public sealed class EvidenceIndexCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify evidence integrity",
"stella evidence verify --all",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/index.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -182,7 +184,8 @@ public sealed class EvidenceIndexCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Refresh evidence index",
"stella evidence index refresh",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/index.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -213,7 +216,8 @@ public sealed class EvidenceIndexCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Rebuild evidence index",
"stella evidence index rebuild",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/index.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -84,7 +84,8 @@ public sealed class MerkleAnchorCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Trigger anchor creation",
"stella evidence anchor create",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/merkle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -111,7 +112,8 @@ public sealed class MerkleAnchorCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Create initial anchor",
"stella evidence anchor create",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/merkle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -160,7 +162,8 @@ public sealed class MerkleAnchorCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Investigate specific anchors",
$"stella evidence anchor verify {invalidAnchors.First()}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/merkle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -194,7 +197,8 @@ public sealed class MerkleAnchorCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Create new anchor",
"stella evidence anchor create",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/merkle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -222,7 +226,8 @@ public sealed class MerkleAnchorCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check evidence locker status",
"stella evidence status",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/merkle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -139,7 +139,8 @@ public sealed class ProvenanceChainCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Review evidence locker integrity",
"stella evidence integrity-check",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/provenance.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -167,7 +168,8 @@ public sealed class ProvenanceChainCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check evidence locker integrity",
"stella evidence integrity-check",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/evidence-locker/provenance.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -80,7 +80,8 @@ public sealed class EmailConfiguredCheck : IDoctorCheck
"export Notify__Channels__Email__SmtpHost=\"smtp.example.com\"\n" +
"export Notify__Channels__Email__SmtpPort=\"587\"\n" +
"export Notify__Channels__Email__FromAddress=\"noreply@example.com\"",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/email-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -101,7 +102,8 @@ public sealed class EmailConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Set SMTP port",
"# Common SMTP ports:\n# 25 - Standard SMTP (often blocked)\n# 465 - SMTP over SSL\n# 587 - SMTP with STARTTLS (recommended)",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/email-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -121,7 +123,8 @@ public sealed class EmailConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Set from address",
"# Add Notify:Channels:Email:FromAddress to configuration",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/notify/email-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -142,7 +145,8 @@ public sealed class EmailConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Enable email notifications",
"# Set Notify:Channels:Email:Enabled to true",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/notify/email-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -122,7 +122,8 @@ public sealed class EmailConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Test with telnet",
$"telnet {smtpHost} {smtpPort}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/email-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -152,7 +153,8 @@ public sealed class EmailConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check firewall rules",
"# Ensure outbound connections to SMTP ports are allowed",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/email-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -179,7 +181,8 @@ public sealed class EmailConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Verify SMTP host and port settings",
"# Common SMTP ports: 25, 465 (SSL), 587 (STARTTLS)",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/email-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -198,6 +198,7 @@ public sealed class NotifyQueueHealthCheck : IDoctorCheck
"# Check Notify:Queue:Transport setting",
CommandType.Manual);
}
rb.WithRunbookUrl("docs/doctor/articles/notify/queue-health.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -225,7 +226,8 @@ public sealed class NotifyQueueHealthCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check queue server health",
"# Review queue server metrics and logs",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/queue-health.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -76,7 +76,8 @@ public sealed class SlackConfiguredCheck : IDoctorCheck
.AddStep(2, "Or set via environment variable",
"export Notify__Channels__Slack__WebhookUrl=\"https://hooks.slack.com/services/YOUR/WEBHOOK/URL\"",
CommandType.Shell)
.WithSafetyNote("Slack webhook URLs are secrets - store in a secrets manager"))
.WithSafetyNote("Slack webhook URLs are secrets - store in a secrets manager")
.WithRunbookUrl("docs/doctor/articles/notify/slack-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -94,7 +95,8 @@ public sealed class SlackConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Enable Slack notifications",
"# Set Notify:Channels:Slack:Enabled to true in configuration",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/notify/slack-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -99,7 +99,8 @@ public sealed class SlackConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Regenerate webhook if needed",
"# Create a new webhook URL in Slack and update configuration",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/slack-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -124,7 +125,8 @@ public sealed class SlackConnectivityCheck : IDoctorCheck
CommandType.Manual)
.AddStep(3, "Verify proxy settings if applicable",
"echo $HTTP_PROXY $HTTPS_PROXY",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/slack-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -146,7 +148,8 @@ public sealed class SlackConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Test HTTPS connectivity",
"curl -v https://hooks.slack.com/",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/slack-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -73,7 +73,8 @@ public sealed class TeamsConfiguredCheck : IDoctorCheck
.AddStep(3, "Or set via environment variable",
"export Notify__Channels__Teams__WebhookUrl=\"https://YOUR_WEBHOOK_URL\"",
CommandType.Shell)
.WithSafetyNote("Teams webhook URLs are secrets - store securely"))
.WithSafetyNote("Teams webhook URLs are secrets - store securely")
.WithRunbookUrl("docs/doctor/articles/notify/teams-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -93,7 +94,8 @@ public sealed class TeamsConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Verify webhook URL",
"# Teams webhook URLs typically look like:\n# https://YOUR_TENANT.webhook.office.com/webhookb2/...",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/teams-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -110,7 +112,8 @@ public sealed class TeamsConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Enable Teams notifications",
"# Set Notify:Channels:Teams:Enabled to true in configuration",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/notify/teams-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -115,7 +115,8 @@ public sealed class TeamsConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Recreate webhook if needed",
"# Delete and recreate the Incoming Webhook connector in Teams",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/teams-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -140,7 +141,8 @@ public sealed class TeamsConnectivityCheck : IDoctorCheck
CommandType.Manual)
.AddStep(3, "Verify proxy settings if applicable",
"echo $HTTP_PROXY $HTTPS_PROXY",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/teams-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -162,7 +164,8 @@ public sealed class TeamsConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Test HTTPS connectivity",
"curl -v https://webhook.office.com/",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/teams-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -72,7 +72,8 @@ public sealed class WebhookConfiguredCheck : IDoctorCheck
CommandType.FileEdit)
.AddStep(2, "Or set via environment variable",
"export Notify__Channels__Webhook__Url=\"https://your-endpoint/webhook\"",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -92,7 +93,8 @@ public sealed class WebhookConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Fix URL format",
"# Ensure URL starts with http:// or https:// and is properly encoded",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -111,7 +113,8 @@ public sealed class WebhookConfiguredCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Enable webhook notifications",
"# Set Notify:Channels:Webhook:Enabled to true in configuration",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -112,7 +112,8 @@ public sealed class WebhookConnectivityCheck : IDoctorCheck
CommandType.Manual)
.AddStep(3, "Check endpoint logs",
"# Review logs on the webhook endpoint server",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -137,7 +138,8 @@ public sealed class WebhookConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Test port connectivity",
$"nc -zv {new Uri(url).Host} {(new Uri(url).Port > 0 ? new Uri(url).Port : (new Uri(url).Scheme == "https" ? 443 : 80))}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -159,7 +161,8 @@ public sealed class WebhookConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Test connectivity",
$"curl -v {DoctorPluginContext.Redact(url)}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/notify/webhook-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -63,7 +63,8 @@ public sealed class LogDirectoryCheck : IDoctorCheck
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? $"icacls \"{logPath}\" /grant Users:F"
: $"sudo chown -R stellaops:stellaops {logPath} && sudo chmod 755 {logPath}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/logs/directory-writable.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -100,7 +101,8 @@ public sealed class LogDirectoryCheck : IDoctorCheck
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? $"icacls \"{logPath}\" /grant Users:F"
: $"sudo chown -R stellaops:stellaops {logPath} && sudo chmod 755 {logPath}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/logs/directory-writable.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -85,7 +85,8 @@ public sealed class LogRotationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Adjust rotation threshold",
"Edit Logging:RollingPolicy in configuration",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/logs/rotation-configured.md"))
.Build());
}
@@ -121,7 +122,8 @@ public sealed class LogRotationCheck : IDoctorCheck
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? "Use Windows Event Log or configure log cleanup task"
: "sudo cp /usr/share/stellaops/logrotate.conf /etc/logrotate.d/stellaops",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/logs/rotation-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -82,7 +82,8 @@ public sealed class OtlpEndpointCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Verify configuration",
"cat /etc/stellaops/telemetry.yaml | grep otlp",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/telemetry/otlp-endpoint.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -103,7 +104,8 @@ public sealed class OtlpEndpointCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check network connectivity",
$"nc -zv {new Uri(endpoint).Host} {new Uri(endpoint).Port}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/telemetry/otlp-endpoint.md"))
.Build();
}
catch (HttpRequestException ex)

View File

@@ -87,7 +87,8 @@ public sealed class PrometheusScrapeCheck : IDoctorCheck
CommandType.FileEdit)
.AddStep(2, "Verify metrics configuration",
"stella config get Metrics",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/metrics/prometheus-scrape.md"))
.WithVerification($"curl -s {metricsUrl} | head -5")
.Build();
}
@@ -108,7 +109,8 @@ public sealed class PrometheusScrapeCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check port binding",
$"netstat -an | grep {metricsPort}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/metrics/prometheus-scrape.md"))
.Build();
}
catch (HttpRequestException ex)

View File

@@ -75,7 +75,8 @@ public sealed class DeadLetterQueueCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Investigate common failures",
"stella orchestrator deadletter analyze",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/dead-letter.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -99,7 +100,8 @@ public sealed class DeadLetterQueueCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Retry failed jobs",
"stella orchestrator deadletter retry --all",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/dead-letter.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -78,7 +78,8 @@ public sealed class JobQueueHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check orchestrator logs",
"stella orchestrator logs --tail 100",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/job-queue.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -110,7 +111,8 @@ public sealed class JobQueueHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Review job processing metrics",
"stella orchestrator metrics --period 1h",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/job-queue.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -141,7 +143,8 @@ public sealed class JobQueueHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Consider scaling workers",
"stella orchestrator workers scale --count 6",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/job-queue.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -67,7 +67,8 @@ public sealed class SchedulerHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Start scheduler",
"stella scheduler start",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/scheduler.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -93,7 +94,8 @@ public sealed class SchedulerHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Trigger catch-up",
"stella scheduler catchup --dry-run",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/operations/scheduler.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -124,7 +124,8 @@ public sealed class PolicyEngineHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Recompile policies",
"stella policy compile --all",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/policy/engine.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -158,7 +159,8 @@ public sealed class PolicyEngineHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check for complex policies",
"stella policy list --complexity high",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/policy/engine.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -201,7 +203,8 @@ public sealed class PolicyEngineHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify network connectivity",
$"curl -s {policyEngineUrl}/health",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/policy/engine.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -225,7 +228,8 @@ public sealed class PolicyEngineHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Restart policy engine if needed",
"stella policy restart",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/policy/engine.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -106,7 +106,8 @@ public sealed class PostgresConnectionPoolCheck : IDoctorCheck
CommandType.Shell)
.AddStep(4, "Terminate idle connections if necessary",
"stella db pool reset --idle-only",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/pool.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -134,7 +135,8 @@ public sealed class PostgresConnectionPoolCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Review active queries",
"stella db queries --active",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/pool.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -162,7 +164,8 @@ public sealed class PostgresConnectionPoolCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Consider increasing pool size",
"stella db config set --max-pool-size 150",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/pool.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -195,7 +198,8 @@ public sealed class PostgresConnectionPoolCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check database connectivity",
"stella doctor --check check.postgres.connectivity",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/pool.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -117,7 +117,8 @@ public sealed class PostgresConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check network connectivity",
"stella db ping --trace",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -142,7 +143,8 @@ public sealed class PostgresConnectivityCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Monitor database performance",
"stella db status --watch",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -187,7 +189,8 @@ public sealed class PostgresConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Verify firewall rules",
"stella db connectivity-test",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -215,7 +218,8 @@ public sealed class PostgresConnectivityCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check credentials",
"stella db verify-credentials",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -78,7 +78,8 @@ public sealed class PostgresMigrationStatusCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Initialize database with migrations",
"stella db migrate --init",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/migrations.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -118,7 +119,8 @@ public sealed class PostgresMigrationStatusCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Verify migration status",
"stella db migrations status",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/migrations.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -150,7 +152,8 @@ public sealed class PostgresMigrationStatusCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check database connectivity",
"stella doctor --check check.postgres.connectivity",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/postgres/migrations.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -98,7 +98,8 @@ public sealed class ActiveReleaseHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check service status",
"stella release status",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/release/active.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -189,6 +190,7 @@ public sealed class ActiveReleaseHealthCheck : IDoctorCheck
"stella release approvals list",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/release/active.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -225,6 +227,7 @@ public sealed class ActiveReleaseHealthCheck : IDoctorCheck
"stella release approvals list",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/release/active.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -265,7 +268,8 @@ public sealed class ActiveReleaseHealthCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check Release Orchestrator health",
$"curl -s {orchestratorUrl}/health",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/release/active.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -83,7 +83,8 @@ public sealed class EnvironmentReadinessCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check Release Orchestrator health",
$"curl -s {orchestratorUrl}/health",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/release/environment-readiness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -174,6 +175,7 @@ public sealed class EnvironmentReadinessCheck : IDoctorCheck
$"stella env health {unhealthy[0].Name}",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/release/environment-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -212,6 +214,7 @@ public sealed class EnvironmentReadinessCheck : IDoctorCheck
$"stella env health {unhealthy[0].Name}",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/release/environment-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -233,7 +236,8 @@ public sealed class EnvironmentReadinessCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Trigger health check refresh",
"stella env health --refresh-all",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/release/environment-readiness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -83,7 +83,8 @@ public sealed class PromotionGateHealthCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check Release Orchestrator health",
$"curl -s {orchestratorUrl}/health",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/release/promotion-gates.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -212,6 +213,7 @@ public sealed class PromotionGateHealthCheck : IDoctorCheck
"stella release gates configure <gate-id> --approvers <user>",
CommandType.Manual);
}
rb.WithRunbookUrl("docs/doctor/articles/release/promotion-gates.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -98,7 +98,8 @@ public sealed class ReleaseConfigurationCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Create a release workflow",
"stella release workflow create --name <name> --stages dev,staging,prod",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/release/configuration.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -219,6 +220,7 @@ public sealed class ReleaseConfigurationCheck : IDoctorCheck
rb.AddStep(2, "Fix workflow configuration",
$"stella release workflow edit {validationErrors[0].WorkflowId}",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/release/configuration.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -147,6 +147,7 @@ public sealed class ReleaseScheduleHealthCheck : IDoctorCheck
rb.AddStep(2, "Reschedule or run immediately",
$"stella release schedule run {missedSchedules[0].Id}",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/release/schedule.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -173,7 +174,8 @@ public sealed class ReleaseScheduleHealthCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Reschedule one of the conflicting releases",
"stella release schedule update <id> --time <new-time>",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/release/schedule.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -169,6 +169,7 @@ public sealed class RollbackReadinessCheck : IDoctorCheck
rb.AddStep(3, "Configure artifact retention",
"stella config set Release:ArtifactRetention:Count 5",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/release/rollback-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -193,7 +194,8 @@ public sealed class RollbackReadinessCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "This is expected for new environments",
"# After the next successful deployment, rollback will be available",
CommandType.Manual))
CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/release/rollback-readiness.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -220,6 +222,7 @@ public sealed class RollbackReadinessCheck : IDoctorCheck
rb.AddStep(2, "Enable auto-rollback",
$"stella env configure {noHealthProbe[0].Name} --auto-rollback-on-failure",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/release/rollback-readiness.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -119,6 +119,7 @@ public sealed class ReachabilityComputationHealthCheck : IDoctorCheck
rb.AddStep(2, "Retry failed computations",
"stella scanner reachability retry --failed",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/reachability.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -149,6 +150,7 @@ public sealed class ReachabilityComputationHealthCheck : IDoctorCheck
rb.AddStep(2, "Scale workers",
"stella scanner workers scale --replicas 4",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/reachability.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -119,6 +119,7 @@ public sealed class SbomGenerationHealthCheck : IDoctorCheck
rb.AddStep(2, "Retry failed SBOMs",
"stella scanner sbom retry --failed",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/sbom.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -123,6 +123,7 @@ public sealed class ScannerQueueHealthCheck : IDoctorCheck
rb.AddStep(3, "Check worker status",
"stella scanner workers status",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/scanner/queue.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -145,7 +146,8 @@ public sealed class ScannerQueueHealthCheck : IDoctorCheck
})
.WithCauses("High volume", "Workers overwhelmed", "High error rate")
.WithRemediation(rb => rb
.AddStep(1, "Scale workers", "stella scanner workers scale --replicas 4", CommandType.Manual))
.AddStep(1, "Scale workers", "stella scanner workers scale --replicas 4", CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/scanner/queue.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -120,6 +120,7 @@ public sealed class ScannerResourceUtilizationCheck : IDoctorCheck
rb.AddStep(2, "Reduce concurrent jobs",
"stella scanner config set MaxConcurrentJobs 2",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/resources.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -139,7 +140,8 @@ public sealed class ScannerResourceUtilizationCheck : IDoctorCheck
})
.WithCauses("High demand", "Consider scaling")
.WithRemediation(rb => rb
.AddStep(1, "Scale workers", "stella scanner workers scale --replicas 4", CommandType.Manual))
.AddStep(1, "Scale workers", "stella scanner workers scale --replicas 4", CommandType.Manual)
.WithRunbookUrl("docs/doctor/articles/scanner/resources.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -115,6 +115,7 @@ public sealed class SliceCacheHealthCheck : IDoctorCheck
rb.AddStep(2, "Increase cache size",
"# Update Scanner:Cache:MaxSizeBytes in configuration",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/slice-cache.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -149,6 +150,7 @@ public sealed class SliceCacheHealthCheck : IDoctorCheck
rb.AddStep(2, "Warm cache",
"stella scanner cache warm",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/slice-cache.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -111,6 +111,7 @@ public sealed class VulnerabilityScanHealthCheck : IDoctorCheck
rb.AddStep(2, "Check sync status",
"stella scanner db status",
CommandType.Shell);
rb.WithRunbookUrl("docs/doctor/articles/scanner/vuln.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();
@@ -128,7 +129,8 @@ public sealed class VulnerabilityScanHealthCheck : IDoctorCheck
})
.WithCauses("Scheduled sync delayed")
.WithRemediation(rb => rb
.AddStep(1, "Check sync schedule", "stella scanner db schedule", CommandType.Shell))
.AddStep(1, "Check sync schedule", "stella scanner db schedule", CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/scanner/vuln.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -117,6 +117,7 @@ public sealed class WitnessGraphHealthCheck : IDoctorCheck
rb.AddStep(2, "Rebuild failed graphs",
"stella scanner witness rebuild --failed",
CommandType.Manual);
rb.WithRunbookUrl("docs/doctor/articles/scanner/witness-graph.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -81,7 +81,8 @@ public sealed class BackupDirectoryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify backup configuration",
"stella backup config show",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/backup.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -114,7 +115,8 @@ public sealed class BackupDirectoryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check disk space",
"stella doctor --check check.storage.diskspace",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/backup.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -146,7 +148,8 @@ public sealed class BackupDirectoryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Verify backup schedule",
"stella backup schedule show",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/backup.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -178,7 +181,8 @@ public sealed class BackupDirectoryCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check backup logs",
"stella backup logs --tail 50",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/backup.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -127,6 +127,7 @@ public sealed class DiskSpaceCheck : IDoctorCheck
"docker system df",
CommandType.Shell);
}
rb.WithRunbookUrl("docs/doctor/articles/storage/diskspace.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build());
@@ -155,7 +156,8 @@ public sealed class DiskSpaceCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Schedule cleanup if needed",
"stella storage cleanup --dry-run",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/diskspace.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -89,7 +89,8 @@ public sealed class EvidenceLockerWriteCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Set permissions",
$"chmod 750 {lockerPath}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/evidencelocker.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -141,7 +142,8 @@ public sealed class EvidenceLockerWriteCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check filesystem integrity",
"stella storage verify --path evidence-locker",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/evidencelocker.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -165,7 +167,8 @@ public sealed class EvidenceLockerWriteCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Check storage I/O metrics",
"stella storage iostat",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/evidencelocker.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -202,7 +205,8 @@ public sealed class EvidenceLockerWriteCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Fix permissions",
$"chown -R stellaops:stellaops {lockerPath}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/evidencelocker.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -226,7 +230,8 @@ public sealed class EvidenceLockerWriteCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Check filesystem mount",
$"mount | grep {Path.GetPathRoot(lockerPath)}",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/storage/evidencelocker.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -86,7 +86,8 @@ public sealed class VexDocumentValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(3, "Check issuer key availability",
"stella issuer keys list",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/vex/validation.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -116,7 +117,8 @@ public sealed class VexDocumentValidationCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Review validation warnings",
"stella vex list --status warning",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/vex/validation.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -67,7 +67,8 @@ public sealed class VexIssuerTrustCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Import trust anchors",
"stella trust-anchors import --defaults",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/vex/issuer-trust.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -91,7 +92,8 @@ public sealed class VexIssuerTrustCheck : IDoctorCheck
CommandType.Shell)
.AddStep(2, "Trust a known issuer",
"stella issuer trust --url https://example.com/.well-known/vex-issuer",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/vex/issuer-trust.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -65,7 +65,8 @@ public sealed class VexSchemaComplianceCheck : IDoctorCheck
.WithRemediation(rb => rb
.AddStep(1, "Update VEX schemas",
"stella vex schemas update",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/vex/schema.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -155,7 +155,8 @@ public sealed class ClaudeProviderCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Verify API key", "Check ANTHROPIC_API_KEY is valid")
.AddManualStep(2, "Check quotas", "Verify API usage limits on console.anthropic.com"))
.AddManualStep(2, "Check quotas", "Verify API usage limits on console.anthropic.com")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.claude")
.Build();
}
@@ -171,7 +172,8 @@ public sealed class ClaudeProviderCheck : IDoctorCheck
.WithCauses("Network connectivity issue or invalid endpoint")
.WithRemediation(r => r
.AddManualStep(1, "Check network", "Verify network connectivity to api.anthropic.com")
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required"))
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.claude")
.Build();
}

View File

@@ -143,7 +143,8 @@ public sealed class GeminiProviderCheck : IDoctorCheck
.WithRemediation(r => r
.AddManualStep(1, "Verify API key", "Check GEMINI_API_KEY or GOOGLE_API_KEY is valid")
.AddManualStep(2, "Enable API", "Ensure Generative Language API is enabled in Google Cloud Console")
.AddManualStep(3, "Check quotas", "Verify API usage limits in Google Cloud Console"))
.AddManualStep(3, "Check quotas", "Verify API usage limits in Google Cloud Console")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.gemini")
.Build();
}
@@ -159,7 +160,8 @@ public sealed class GeminiProviderCheck : IDoctorCheck
.WithCauses("Network connectivity issue or invalid endpoint")
.WithRemediation(r => r
.AddManualStep(1, "Check network", "Verify network connectivity to generativelanguage.googleapis.com")
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required"))
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.gemini")
.Build();
}

View File

@@ -143,7 +143,8 @@ public sealed class LlmProviderConfigurationCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Set API key", "Configure API key for the default provider")
.AddManualStep(2, "Verify provider", "Ensure default provider matches a configured one"))
.AddManualStep(2, "Verify provider", "Ensure default provider matches a configured one")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.llm.config")
.Build());
}

View File

@@ -142,7 +142,8 @@ public sealed class LocalInferenceCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Load model", "Ensure a model is loaded in the server")
.AddManualStep(2, "Check model path", "Verify the model file exists at configured path"))
.AddManualStep(2, "Check model path", "Verify the model file exists at configured path")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.local")
.Build();
}

View File

@@ -84,7 +84,8 @@ public sealed class OllamaProviderCheck : IDoctorCheck
.WithCauses("Ollama server is not running or endpoint is incorrect")
.WithRemediation(r => r
.AddManualStep(1, "Start Ollama", "Run: ollama serve")
.AddManualStep(2, "Check endpoint", $"Verify Ollama is running at {endpoint}"))
.AddManualStep(2, "Check endpoint", $"Verify Ollama is running at {endpoint}")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.ollama")
.Build();
}
@@ -160,7 +161,8 @@ public sealed class OllamaProviderCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Pull model", $"Run: ollama pull {model}")
.AddManualStep(2, "List models", "Run: ollama list"))
.AddManualStep(2, "List models", "Run: ollama list")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.ollama")
.Build();
}

View File

@@ -139,7 +139,8 @@ public sealed class OpenAiProviderCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Verify API key", "Check OPENAI_API_KEY is valid")
.AddManualStep(2, "Check quotas", "Verify API usage limits on platform.openai.com"))
.AddManualStep(2, "Check quotas", "Verify API usage limits on platform.openai.com")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.openai")
.Build();
}
@@ -155,7 +156,8 @@ public sealed class OpenAiProviderCheck : IDoctorCheck
.WithCauses("Network connectivity issue or invalid endpoint")
.WithRemediation(r => r
.AddManualStep(1, "Check network", "Verify network connectivity to api.openai.com")
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required"))
.AddManualStep(2, "Check proxy", "Ensure proxy settings are configured if required")
.WithRunbookUrl(""))
.WithVerification("stella doctor --check check.ai.provider.openai")
.Build();
}

View File

@@ -96,7 +96,8 @@ public sealed class ClockSkewCheck : AttestationCheckBase
.Add("Note", "Clock skew verification skipped - no network reference available"))
.WithRemediation(r => r
.AddShellStep(1, "Check system time", GetTimeCheckCommand())
.AddManualStep(2, "Configure NTP", "Ensure NTP is configured for time synchronization"))
.AddManualStep(2, "Configure NTP", "Ensure NTP is configured for time synchronization")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-clock-skew.md"))
.Build();
}
@@ -122,7 +123,8 @@ public sealed class ClockSkewCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Check current time", GetTimeCheckCommand())
.AddShellStep(2, "Force NTP sync", GetNtpSyncCommand())
.AddManualStep(3, "Configure NTP", "Ensure NTP is properly configured and the NTP service is running"))
.AddManualStep(3, "Configure NTP", "Ensure NTP is properly configured and the NTP service is running")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-clock-skew.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}
@@ -143,7 +145,8 @@ public sealed class ClockSkewCheck : AttestationCheckBase
"Infrequent NTP sync interval")
.WithRemediation(r => r
.AddShellStep(1, "Check NTP status", GetNtpStatusCommand())
.AddShellStep(2, "Force NTP sync", GetNtpSyncCommand()))
.AddShellStep(2, "Force NTP sync", GetNtpSyncCommand())
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-clock-skew.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -93,7 +93,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
.Add("Note", "Enable Sigstore to use attestation signing"))
.WithRemediation(r => r
.AddManualStep(1, "Enable Sigstore", "Set Sigstore:Enabled to true in configuration")
.AddManualStep(2, "Configure signing mode", "Set either Sigstore:KeyPath, Sigstore:Keyless:Enabled, or Sigstore:KMS:KeyRef"))
.AddManualStep(2, "Configure signing mode", "Set either Sigstore:KeyPath, Sigstore:Keyless:Enabled, or Sigstore:KMS:KeyRef")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.Build());
}
@@ -112,7 +113,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
.AddShellStep(1, "Generate a signing key pair", "cosign generate-key-pair")
.AddManualStep(2, "Configure key path", "Set Sigstore:KeyPath to the path of the private key")
.AddManualStep(3, "Or enable keyless", "Set Sigstore:Keyless:Enabled to true for OIDC-based signing")
.AddManualStep(4, "Or use KMS", "Set Sigstore:KMS:KeyRef to your KMS key reference"))
.AddManualStep(4, "Or use KMS", "Set Sigstore:KMS:KeyRef to your KMS key reference")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.WithVerification($"stella doctor --check check.attestation.cosign.keymaterial")
.Build());
}
@@ -135,7 +137,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Verify file exists", $"ls -la {keyPath}")
.AddShellStep(2, "Generate new key pair if needed", "cosign generate-key-pair")
.AddManualStep(3, "Update configuration", "Ensure Sigstore:KeyPath points to the correct file"))
.AddManualStep(3, "Update configuration", "Ensure Sigstore:KeyPath points to the correct file")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.WithVerification($"stella doctor --check check.attestation.cosign.keymaterial")
.Build());
}
@@ -172,7 +175,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
.WithCauses("File permissions prevent reading the key file")
.WithRemediation(r => r
.AddShellStep(1, "Check file permissions", $"ls -la {keyPath}")
.AddShellStep(2, "Fix permissions if needed", $"chmod 600 {keyPath}"))
.AddShellStep(2, "Fix permissions if needed", $"chmod 600 {keyPath}")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.WithVerification($"stella doctor --check check.attestation.cosign.keymaterial")
.Build());
}
@@ -213,7 +217,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
"Fulcio URL is incorrect")
.WithRemediation(r => r
.AddShellStep(1, "Test Fulcio endpoint", $"curl -I {fulcioApiUrl}")
.AddManualStep(2, "Check service status", "Visit https://status.sigstore.dev"))
.AddManualStep(2, "Check service status", "Visit https://status.sigstore.dev")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.WithVerification($"stella doctor --check check.attestation.cosign.keymaterial")
.Build();
}
@@ -242,7 +247,8 @@ public sealed class CosignKeyMaterialCheck : AttestationCheckBase
"Firewall blocking HTTPS traffic")
.WithRemediation(r => r
.AddShellStep(1, "Test connectivity", $"curl -I {fulcioUrl}")
.AddManualStep(2, "Check network configuration", "Ensure HTTPS traffic to Fulcio is allowed"))
.AddManualStep(2, "Check network configuration", "Ensure HTTPS traffic to Fulcio is allowed")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-cosign-keymaterial.md"))
.WithVerification($"stella doctor --check check.attestation.cosign.keymaterial")
.Build();
}

View File

@@ -69,7 +69,8 @@ public sealed class OfflineBundleCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Export bundle from online system", "stella attestation bundle export --output /path/to/bundle.json")
.AddManualStep(2, "Configure bundle path", "Set Doctor:Plugins:Attestation:OfflineBundlePath to the bundle location")
.AddManualStep(3, "Transfer bundle", "Copy the bundle to the target system"))
.AddManualStep(3, "Transfer bundle", "Copy the bundle to the target system")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-offline-bundle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -89,7 +90,8 @@ public sealed class OfflineBundleCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Check file existence", $"ls -la {options.OfflineBundlePath}")
.AddShellStep(2, "Export new bundle", "stella attestation bundle export --output " + options.OfflineBundlePath)
.AddManualStep(3, "Verify path", "Ensure the configured path is correct"))
.AddManualStep(3, "Verify path", "Ensure the configured path is correct")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-offline-bundle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -134,7 +136,8 @@ public sealed class OfflineBundleCheck : AttestationCheckBase
.Add("ParseError", parseError))
.WithRemediation(r => r
.AddShellStep(1, "Validate bundle", "stella attestation bundle validate " + options.OfflineBundlePath)
.AddShellStep(2, "Export fresh bundle", "stella attestation bundle export --output " + options.OfflineBundlePath))
.AddShellStep(2, "Export fresh bundle", "stella attestation bundle export --output " + options.OfflineBundlePath)
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-offline-bundle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -167,7 +170,8 @@ public sealed class OfflineBundleCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Export fresh bundle from online system", "stella attestation bundle export --output /path/to/new-bundle.json")
.AddManualStep(2, "Transfer to air-gap environment", "Copy the new bundle to the target system")
.AddManualStep(3, "Update bundle path if needed", "Point configuration to the new bundle file"))
.AddManualStep(3, "Update bundle path if needed", "Point configuration to the new bundle file")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-offline-bundle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -191,7 +195,8 @@ public sealed class OfflineBundleCheck : AttestationCheckBase
})
.WithRemediation(r => r
.AddShellStep(1, "Export fresh bundle", "stella attestation bundle export --output /path/to/new-bundle.json")
.AddManualStep(2, "Schedule regular updates", "Consider automating bundle refresh"))
.AddManualStep(2, "Schedule regular updates", "Consider automating bundle refresh")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-offline-bundle.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -60,7 +60,8 @@ public sealed class RekorConnectivityCheck : AttestationCheckBase
.Add("ConfigKey", "Doctor:Plugins:Attestation:RekorUrl or Sigstore:RekorUrl"))
.WithRemediation(r => r
.AddManualStep(1, "Configure Rekor URL", "Set the Rekor URL in configuration: STELLA_REKOR_URL=https://rekor.sigstore.dev")
.AddManualStep(2, "Or use offline mode", "Set Doctor:Plugins:Attestation:Mode to 'offline' and configure OfflineBundlePath"))
.AddManualStep(2, "Or use offline mode", "Set Doctor:Plugins:Attestation:Mode to 'offline' and configure OfflineBundlePath")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-rekor-connectivity.md"))
.Build();
}
@@ -86,7 +87,8 @@ public sealed class RekorConnectivityCheck : AttestationCheckBase
.WithRemediation(r => r
.AddShellStep(1, "Test endpoint manually", $"curl -I {logInfoUrl}")
.AddManualStep(2, "Verify Rekor URL", "Ensure the URL is correct (default: https://rekor.sigstore.dev)")
.AddManualStep(3, "Check service status", "Visit https://status.sigstore.dev for public Rekor status"))
.AddManualStep(3, "Check service status", "Visit https://status.sigstore.dev for public Rekor status")
.WithRunbookUrl("docs/doctor/articles/attestor/attestation-rekor-connectivity.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build();
}

View File

@@ -122,7 +122,8 @@ public sealed class AuthorityPluginConfigurationCheck : IDoctorCheck
CommandType.FileEdit)
.AddStep(3, "Run setup wizard to configure",
"stella setup --step authority",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/authority-plugin-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -139,7 +140,8 @@ public sealed class AuthorityPluginConfigurationCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Review configuration", "Check Authority:Plugins section for missing values")
.AddStep(2, "Run setup wizard", "stella setup --step authority", CommandType.Shell))
.AddStep(2, "Run setup wizard", "stella setup --step authority", CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/authority-plugin-configured.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -98,6 +98,7 @@ public sealed class AuthorityPluginConnectivityCheck : IDoctorCheck
r.AddManualStep(3, "Check LDAP server", "Verify LDAP server is accessible from this network");
r.AddManualStep(4, "Verify LDAP credentials", "Check Authority:Plugins:Ldap:BindDn and BindPassword");
}
r.WithRunbookUrl("docs/doctor/articles/auth/authority-plugin-connectivity.md");
})
.WithVerification($"stella doctor --check {CheckId}")
.Build();

View File

@@ -81,7 +81,8 @@ public sealed class BootstrapUserExistsCheck : IDoctorCheck
CommandType.FileEdit)
.AddStep(2, "Or run setup wizard to create user",
"stella setup --step users",
CommandType.Shell))
CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/authority-bootstrap-exists.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}
@@ -123,7 +124,8 @@ public sealed class BootstrapUserExistsCheck : IDoctorCheck
.WithCauses(issues.ToArray())
.WithRemediation(r => r
.AddManualStep(1, "Complete configuration", "Set missing bootstrap user fields")
.AddStep(2, "Run setup wizard", "stella setup --step users", CommandType.Shell))
.AddStep(2, "Run setup wizard", "stella setup --step users", CommandType.Shell)
.WithRunbookUrl("docs/doctor/articles/auth/authority-bootstrap-exists.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

View File

@@ -106,7 +106,8 @@ public sealed class SuperUserExistsCheck : IDoctorCheck
"\"Authority\": {\n" +
" \"Bootstrap\": { \"Enabled\": true }\n" +
"}",
CommandType.FileEdit))
CommandType.FileEdit)
.WithRunbookUrl("docs/doctor/articles/auth/users-superuser-exists.md"))
.WithVerification($"stella doctor --check {CheckId}")
.Build());
}

Some files were not shown because too many files have changed in this diff Show More