Add low/base/high demand forecasts, service objectives with timestamped observations, and workload operations labor for resource:tenant:coulomb:coulomb-social.
210 lines
7.1 KiB
JSON
210 lines
7.1 KiB
JSON
{
|
|
"schema_version": "0.1",
|
|
"record_kind": "service_objectives_and_usage_observations",
|
|
"resource_id": "resource:tenant:coulomb:coulomb-social",
|
|
"service_id": "coulomb-social",
|
|
"workload_id": "coulomb-social",
|
|
"tenant_id": "tenant:coulomb",
|
|
"environment": "production",
|
|
"cost_attribution_key": "resource:tenant:coulomb:coulomb-social",
|
|
"created_at": "2026-08-12T09:03:47Z",
|
|
"service_objectives": {
|
|
"availability": {
|
|
"target": "99.5_percent_monthly",
|
|
"scope": "HTTPS app.coulomb.social application responses excluding scheduled maintenance and dependency outages (OIDC, apps-pg, cluster)",
|
|
"measurement": "synthetic GET /healthz success ratio + ingress 5xx from platform telemetry when available",
|
|
"notes": "Not a contractual SLA; planning objective for infrastructure options."
|
|
},
|
|
"latency": {
|
|
"healthz_p99_ms": 500,
|
|
"authenticated_html_p95_ms": 1500,
|
|
"space_markdown_render_p95_ms": 3000,
|
|
"notes": "Markdown path includes Forgejo fetch; cold cache may exceed target — track separately."
|
|
},
|
|
"recovery": {
|
|
"rpo_minutes": 60,
|
|
"rto_minutes": 240,
|
|
"notes": "RPO/RTO for app DB via apps-pg backup ownership; content RPO/RTO inherits Forgejo backup policy for bound repos."
|
|
},
|
|
"retention": {
|
|
"app_database_backup_days": 30,
|
|
"application_logs_days": 14,
|
|
"session_cookie": "browser session; no long-lived app refresh tokens in v1",
|
|
"notes": "Backup retention executed by apps-pg/platform; app requires ≥30 days logical recoverability."
|
|
},
|
|
"tenant_isolation": {
|
|
"model": "tenant_id column isolation within instance + instance_per_client deployments",
|
|
"default_tenant": "tenant:coulomb",
|
|
"cross_tenant_list": "forbidden — Space queries filter by session tenant_id",
|
|
"identity": "NetKingdom OIDC (issuer, subject) Member binding; no local passwords"
|
|
},
|
|
"security": {
|
|
"authn": "OIDC public client + session cookies Secure/HttpOnly/SameSite=Lax in prod",
|
|
"secrets": "K8s Secret coulomb-social-env / OpenBao; never in git",
|
|
"content_xss": "bleach-sanitized markdown HTML"
|
|
}
|
|
},
|
|
"observations": [
|
|
{
|
|
"name": "public_healthz",
|
|
"value": "ok",
|
|
"unit": "status",
|
|
"observed_at": "2026-08-12T09:03:47Z",
|
|
"method": "curl -fsS https://app.coulomb.social/healthz",
|
|
"authority": "coulomb-social"
|
|
},
|
|
{
|
|
"name": "public_landing_http_status",
|
|
"value": "200",
|
|
"unit": "http_status",
|
|
"observed_at": "2026-08-12T09:03:47Z",
|
|
"method": "curl -o /dev/null -w status https://app.coulomb.social/",
|
|
"authority": "coulomb-social"
|
|
},
|
|
{
|
|
"name": "demo_fixture_raw_bytes",
|
|
"value": "586",
|
|
"unit": "bytes",
|
|
"observed_at": "2026-08-12T09:03:47Z",
|
|
"method": "GET Forgejo raw docs/space-fixtures/demo/pages/index.md",
|
|
"authority": "coulomb-social + forgejo.coulomb.social public raw"
|
|
},
|
|
{
|
|
"name": "declared_replicas",
|
|
"value": "1",
|
|
"unit": "count",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart values replicaCount",
|
|
"authority": "railiance-apps/charts/coulomb-social/values.yaml"
|
|
},
|
|
{
|
|
"name": "declared_cpu_request_millicores",
|
|
"value": "100",
|
|
"unit": "millicores",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart resources.requests.cpu",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "declared_memory_request_mi",
|
|
"value": "256",
|
|
"unit": "Mi",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart resources.requests.memory",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "declared_cpu_limit_millicores",
|
|
"value": "1000",
|
|
"unit": "millicores",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart resources.limits.cpu",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "declared_memory_limit_mi",
|
|
"value": "1024",
|
|
"unit": "Mi",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart resources.limits.memory",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "media_persistence_enabled",
|
|
"value": "false",
|
|
"unit": "bool",
|
|
"observed_at": "2026-08-12",
|
|
"method": "chart persistence.media.enabled",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "helm_image_tag",
|
|
"value": "7fcd0cf",
|
|
"unit": "git_sha_short",
|
|
"observed_at": "2026-08-12",
|
|
"method": "helm/coulomb-social-values.yaml image.tag",
|
|
"authority": "railiance-apps"
|
|
},
|
|
{
|
|
"name": "portfolio_ready_replicas",
|
|
"value": "1",
|
|
"unit": "count",
|
|
"observed_at": "2026-08-11",
|
|
"method": "Kubernetes API sample in RESOURCE-WP-0003 initial portfolio discovery",
|
|
"authority": "resource-control discovery (reef-railiance)"
|
|
},
|
|
{
|
|
"name": "commissioned_on",
|
|
"value": "2026-08-09",
|
|
"unit": "date",
|
|
"observed_at": "2026-08-11",
|
|
"method": "inventory record lifecycle.commissioned_on",
|
|
"authority": "resource-control/data/resources/coulomb-social-production.json"
|
|
},
|
|
{
|
|
"name": "app_database_gb_logical",
|
|
"value": "unknown",
|
|
"unit": "GB",
|
|
"observed_at": "2026-08-12",
|
|
"method": "not measured this session (kubectl/apps-pg access unavailable)",
|
|
"authority": "coulomb-social — gap; platform may supply"
|
|
},
|
|
{
|
|
"name": "production_member_count",
|
|
"value": "unknown",
|
|
"unit": "count",
|
|
"observed_at": "2026-08-12",
|
|
"method": "not queried (no production DB shell this session)",
|
|
"authority": "coulomb-social — gap"
|
|
},
|
|
{
|
|
"name": "observed_cpu_millicores",
|
|
"value": "unknown",
|
|
"unit": "millicores",
|
|
"observed_at": "2026-08-12",
|
|
"method": "metrics-server sample unavailable this session",
|
|
"authority": "railiance-cluster when sampled"
|
|
},
|
|
{
|
|
"name": "observed_memory_mi",
|
|
"value": "unknown",
|
|
"unit": "Mi",
|
|
"observed_at": "2026-08-12",
|
|
"method": "metrics-server sample unavailable this session",
|
|
"authority": "railiance-cluster when sampled"
|
|
},
|
|
{
|
|
"name": "local_dev_member_count",
|
|
"value": "2",
|
|
"unit": "count",
|
|
"observed_at": "2026-08-12T09:03:47Z",
|
|
"method": "local sqlite Member.objects.count() after pytest/dev use — not production",
|
|
"authority": "coulomb-social workstation (non-prod)"
|
|
}
|
|
],
|
|
"dependency_slo_inheritance": [
|
|
{
|
|
"dependency": "resource:railiance:apps-pg",
|
|
"inherits": ["database backup", "DB RPO/RTO physical path"]
|
|
},
|
|
{
|
|
"dependency": "resource:railiance:reef-railiance:k3s",
|
|
"inherits": ["node availability", "pod scheduling"]
|
|
},
|
|
{
|
|
"dependency": "resource:railiance:forgejo",
|
|
"inherits": ["space markdown durability", "git history"]
|
|
},
|
|
{
|
|
"dependency": "NetKingdom KeyCape / Authelia",
|
|
"inherits": ["authentication availability", "MFA path"]
|
|
}
|
|
],
|
|
"source_evidence": [
|
|
"docs/resource-evidence/service-objectives-and-observations-2026-08.md",
|
|
"docs/deploy.md",
|
|
"docs/identity/smoke.md",
|
|
"docs/adr/ADR-0001-netkingdom-identity.md",
|
|
"docs/adr/ADR-0002-space-content-forgejo-markdown.md"
|
|
]
|
|
}
|