Reference · Catalog

Non-Functional Requirements Catalog

Every quantitative budget, threshold, and quality attribute CyberOS commits to. 10 ISO/IEC 25010 categories — Performance Efficiency, Reliability, Security, Usability & Accessibility, Maintainability, Functional Suitability, Compliance, Observability, Privacy, Scalability — each carrying a measurable target and a verification method (T = Test, I = Inspection, D = Demo, A = Analysis).

NFRs total
SEC (Security)
PERF (Performance)
10
Categories
of NFRs match current filters.
PERF

Performance Efficiency

Latency budgets, throughput ceilings, cost limits · 18 NFRs
NFR-AI-002 p99 < 10ms; p95 < 5ms for cost-ledger pre-call admission check P0 Verify: T

AI Gateway cost-ledger pre-call check overhead — p99 < 10ms

Before every upstream provider call, the AI Gateway MUST consult the per-tenant cost-ledger to verify the projected token-cost does not exceed the tenant's monthly budget remainder.

Measurement
Histogram metric `ai_gateway_cost_ledger_admit_seconds` emitted by `services/ai-gateway/src/cost/ledger.rs::admit()`.
Modules
AI
Priority
MUST
Owner
CTO
NFR-AI-007 p95 time-to-first-byte (TTFB) < 2s for streaming /v1/chat/completions, cache-miss path P0 Verify: T

AI Gateway streaming first-byte latency — p95 < 2s for non-cached completions

For streaming chat-completion requests on the cache-miss path, the AI Gateway MUST emit the first SSE event to the caller at p95 < 2s and p99 < 4s measured from inbound HTTP request received to first SSE data line written to the response stream.

Measurement
Histogram `ai_gateway_streaming_ttfb_seconds{route, cache_hit, model_alias}` emitted by `services/ai-gateway/src/streaming/sse.rs`. Buckets: 0.05, 0.1, 0.25, 0.5, 1, 2, 4, 8.
Modules
AI
Priority
MUST
Owner
CTO
NFR-AUTH-001 p95 < 50ms for verify_jwt + RBAC admit on /v1/admin/* routes P0 Verify: T

AUTH admin endpoint admission latency — verify_jwt + RBAC check < 50ms p95

The AUTH service MUST complete the admission pipeline `verify_jwt → RBAC.check → admit` at p95 < 50ms and p99 < 100ms measured at the service ingress, over a 14-day rolling window, for every `/v1/admin/*` route.

Measurement
Histogram `auth_admit_latency_seconds{route, result}` emitted by `services/auth/src/middleware/admit.rs` over the verify→check→admit span.
Modules
AUTH
Priority
MUST
Owner
CTO
NFR-AUTH-003 Single-key verify p99 < 1ms; multi-key (during 7-day rotation) p99 < 5ms P0 Verify: T

AUTH JWT signature verification time — < 1ms p99 single key; < 5ms p99 with 7-day rotation window

AUTH JWT signature verification using the active EdDSA (Ed25519) signing key MUST complete at p99 < 1ms on the production hardware profile (2-vCPU, 4GB RAM container).

Measurement
Histogram `auth_jwt_verify_seconds{key_id, result}` per verify; buckets 0.0001, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.025.
Modules
AUTH
Priority
MUST
Owner
CTO
NFR-CHAT-001 p95 < 100ms, p99 < 250ms from CHAT POST /api/v4/posts to DB commit ack P0 Verify: T

CHAT message persist latency — p95 < 100ms from send to DB ack

From the moment a CHAT POST request lands on the Mattermost fork, the message MUST be committed to durable Postgres storage and the DB ack returned at p95 < 100ms and p99 < 250ms, measured at the application span.

Measurement
Histogram `chat_message_persist_seconds{channel_type, has_attachments}` per POST.
Modules
CHAT
Priority
MUST
Owner
CTO
NFR-CHAT-002 p95 < 200ms from DB persist ack to message delivered to every connected WebSocket subscriber on the channel P0 Verify: T

CHAT WebSocket fanout latency — p95 < 200ms from persist to all subscribed clients

After a message is committed to Postgres (NFR-CHAT-001), the WebSocket fanout MUST deliver it to every currently-connected subscriber on the channel at p95 < 200ms and p99 < 500ms.

Measurement
Histogram `chat_ws_fanout_latency_seconds{cross_pod}` per (message, subscriber) pair; rolled up to worst-case-per-message.
Modules
CHAT
Priority
MUST
Owner
CTO
NFR-CHAT-003 p95 < 2s, p99 < 5s from chat message persist to memory bridge put committed P0 Verify: T

CHAT memory bridge replication lag — p95 < 2s from chat message to memory put

After a chat message is committed to CHAT Postgres (NFR-CHAT-001), the memory bridge plugin MUST replicate the message to memory at p95 < 2s and p99 < 5s, measured from chat commit to memory bridge put ack.

Measurement
Histogram `chat_memory_bridge_lag_seconds` per bridged message.
Modules
CHAT
Priority
MUST
Owner
CTO
NFR-CUO-200 p95 < 5s; p99 < 15s end-to-end `cyberos-cuo harness report --since 30d` on a chain of up to 10⁶ rows + 250 skills P0 Verify: T

harness report generation MUST complete in p95 < 5s over a 10⁶-row audit chain

The `cyberos-cuo harness report` command MUST produce a complete markdown report from a memory audit chain of up to 10⁶ rows in p95 < 5s and p99 < 15s wall-clock time on a single-core x86_64 machine with 8 GB RAM.

Measurement
wall-clock duration of `compute_report()` (excluding markdown formatting + disk write)
Modules
cuo
Priority
MUST
Owner
CTO
NFR-CUO-001 p95 < 3s for full cuo/ + skill/ filesystem catalog scan + validation P0 Verify: T

CUO catalog scan latency — full persona+workflow scan completes < 3s

The CUO supervisor's filesystem catalog scan (`modules/cuo/cuo/catalog.py::scan_catalog()`) MUST complete a full pass over `cuo/<persona>/<workflow>.md` + `skill/public/<skill>/SKILL.md` at p95 < 3s for a catalog of up to 500 personas and 5000 workflows.

Measurement
Histogram `cuo_catalog_scan_latency_seconds{stage=walk|parse|validate}` — surfaces which sub-step dominates.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-008 p95 < 1.5s for cyberos-cuo route <natural-language> P1 Verify: T

CUO route decision latency — natural-language → persona+workflow < 1.5s

The CUO router (`cyberos-cuo route "<query>"`) MUST return a persona+workflow decision at p95 < 1.5s and p99 < 3s for the default Phase-1 two-stage routing algorithm (persona match → workflow match within persona).

Measurement
Histogram `cuo_route_latency_seconds{stage=persona_match|workflow_match|llm, invoker}`.
Modules
CUO
Priority
SHOULD
Owner
CTO
NFR-EMAIL-001 p95 < 30s from SMTP MAIL FROM to inbox-row visible in user UI P0 Verify: T

EMAIL inbound delivery latency — SMTP receipt to inbox visible < 30s p95

Inbound emails reaching the Stalwart MTA MUST be parsed, classified, indexed, and visible in the recipient's inbox UI within 30s p95 and 90s p99.

Measurement
Histogram `email_inbound_delivery_latency_seconds{stage=receive|auth_check|camel|index|notify}`.
Modules
EMAIL
Priority
MUST
Owner
CTO
NFR-KB-007 p95 < 60s from doc save to fresh rendered HTML served to all readers P1 Verify: T

KB render cache TTL — rendered HTML MUST refresh within 60s of doc save

The KB server-side renderer (`TASK-KB-002`) MUST cache rendered HTML keyed by `(doc_id, doc_version, theme)` for fast serving.

Measurement
Histogram `kb_render_cache_stale_after_save_seconds`.
Modules
KB
Priority
SHOULD
Owner
CTO
NFR-MEMORY-001 p95 < 1s; p99 < 3s end-to-end Layer-1 commit to Layer-2 visibility P0 Verify: T

memory Layer-2 ingest lag — p95 < 1s from Layer-1 commit to l2_memory row visible

From the moment a row is committed to a Layer-1 memory store (per-actor SQLite append-log), the row MUST be visible in the global `l2_memory` Postgres table at p95 < 1s and p99 < 3s.

Measurement
Histogram `memory_layer2_ingest_lag_seconds{tenant_id, actor_id}` measured per ingested row as `(l2_committed_at - l1_committed_at)`.
Modules
memory
Priority
MUST
Owner
CTO
NFR-MEMORY-004 cyberos-memory doctor full invariant pass completes < 30s on a 100k-row test store P0 Verify: T

memory doctor invariant runtime — full invariant pass < 30s on 100k-row store

The `cyberos-memory doctor` command MUST complete a full invariant scan in < 30s on a Layer-2 store of 100,000 rows. The scan includes: chain-anchor verification (NFR-MEMORY-002), cursor consistency (NFR-MEMORY-003), per-tenant RLS sanity, and PII pre-ingest detection (NFR-MEMORY-007).

Measurement
Histogram `memory_doctor_scan_seconds{result, rows_n}` per run.
Modules
memory
Priority
MUST
Owner
CTO
NFR-OBS-003 Tail sampler CPU overhead < 2% of collector CPU; sampling rates exact per TASK-OBS-006 policy P0 Verify: T

Tail-sampling efficiency — 100% errors + 10% normal; sampler CPU overhead < 2%

The OTel collector tail-sampler MUST apply the TASK-OBS-006 policies (100% errors, 100% 5xx, 100% slow, 100% flagged-tenants, 10% normal) and the measured sampling rates MUST match the policy targets within ±1% over a 1-hour window.

Measurement
Collector self-metric `otelcol_processor_tail_sampling_count_traces_sampled{policy}` divided by `otelcol_processor_tail_sampling_count_traces_seen` per minute. Should match policy targets ±1%.
Modules
OBS
Priority
MUST
Owner
CTO
NFR-OKR-004 p95 < 2s from check-in submit to visible in the OKR dashboard P1 Verify: T

OKR KR check-in latency — manual check-in MUST persist within 2s

Manual KR check-ins (`TASK-OKR-005`) MUST persist + appear in the OKR dashboard within 2s p95.

Measurement
Histogram `okr_checkin_persist_latency_ms`.
Modules
OKR
Priority
SHOULD
Owner
CEO
NFR-SKILL-002 p95 < 25ms for capability admit (token check + policy lookup + decision) P0 Verify: T

SKILL capability broker admit latency — grant decision p95 < 25ms

The SKILL capability broker MUST answer admit requests (skill requests cap X for tenant Y) at p95 < 25ms, p99 < 75ms, measured at the broker's `/admit` ingress over a 14-day rolling window.

Measurement
Histogram `skill_broker_admit_latency_seconds{decision, capability}` p50/p95/p99.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-SKILL-009 p95 < 2s, p99 < 5s for first-invocation of a skill not in cache P1 Verify: T

SKILL cold-start latency — bundle pull + manifest parse + capability admit < 2s

First invocation of a skill not already in local cache MUST complete the cold-start steps (`registry pull → manifest parse → schema validate → capability admit → runtime ready`) at p95 < 2s and p99 < 5s.

Measurement
Histogram `skill_cold_start_latency_seconds{step=pull|parse|admit|ready}` — surfaces which step is the bottleneck.
Modules
SKILL
Priority
SHOULD
Owner
CTO
REL

Reliability

Availability targets, DR, backup RPO/RTO · 45 NFRs
NFR-AI-001 p95 < 5s from primary upstream error to first byte from secondary provider P0 Verify: T

AI Gateway provider failover latency budget — p95 < 5s from primary error to secondary first chunk

The AI Gateway MUST route to a secondary provider when the primary provider returns a connection error, HTTP 5xx, or fails to emit a first byte within the primary timeout budget (default 8s; configurable per route).

Measurement
Histogram metric `ai_gateway_failover_latency_seconds{primary_provider, secondary_provider, route}` emitted by `services/ai-gateway/src/router.rs` on every provider switch.
Modules
AI
Priority
MUST
Owner
CTO
NFR-AI-003 Open within 30s of 3rd error; first recovery probe at exactly 60s post-open P0 Verify: T

AI Gateway circuit-breaker trip policy — 3 errors in 30s opens; recovery probe at 60s

The AI Gateway circuit-breaker per (provider, route) tuple MUST transition from CLOSED → OPEN when 3 consecutive upstream errors occur within a 30-second sliding window. Errors counted: connection-failure, HTTP 5xx, HTTP 429 with no `Retry-After`, and provider-emitted timeouts.

Measurement
Gauge `ai_gateway_circuit_state{provider, route}` ∈ {0=closed, 1=half_open, 2=open}.
Modules
AI
Priority
MUST
Owner
CTO
NFR-AI-008 Reconciled token count within 0.5% of provider-reported usage, averaged over 1000 calls P0 Verify: T

AI Gateway token-count post-call reconcile accuracy — within 0.5%

After every upstream provider call, the AI Gateway MUST reconcile the locally-projected token count (used for cost-ledger admit per NFR-AI-002) against the provider-reported usage in the response `usage` field.

Measurement
Gauge `ai_gateway_token_count_drift_pct{provider, model_alias}` — rolling 1000-call average delta. Alarm at > 0.5%.
Modules
AI
Priority
MUST
Owner
CFO
NFR-AUTH-005 RoleMatrix refresher runs every AUTH_RBAC_REFRESH_SECS (default 60s); 3 consecutive failures triggers alert P0 Verify: T

AUTH RoleMatrix refresh cadence — ≤ 60s revocation latency; alert on 3 consecutive failures

The `services/auth/src/rbac/refresher.rs` background task MUST call `RoleMatrix::load_from_db()` every `AUTH_RBAC_REFRESH_SECS` seconds (default 60s, floor 5s).

Measurement
Counter `auth_rbac_refresh_total{result}` where result ∈ {`success`, `error`}.
Modules
AUTH
Priority
MUST
Owner
CTO
NFR-AUTH-008 Idempotency keys retained 24h; cleanup sweeper runs hourly removing expired keys P0 Verify: T

AUTH Idempotency-Key TTL — 24-hour replay window; hourly cleanup sweeper

Idempotency-Key handling on admin POST endpoints (per TASK-AUTH-001 §1 #6) MUST retain seen keys for exactly 24 hours from first-seen-at timestamp.

Measurement
Gauge `auth_idempotency_keys_total` — current row count. Sev-3 alarm at > 1M.
Modules
AUTH
Priority
MUST
Owner
CTO
NFR-CRM-002 100% of activity-feed reads return events in strict committed-at order; no out-of-order P0 Verify: T

CRM activity-feed ordering — feed MUST be strictly chronologically consistent

Activity events (call, email, meeting, note, stage-change) for an account/contact/deal MUST be displayed in the feed in strict `committed_at` order (newest first).

Measurement
Counter `crm_feed_out_of_order_total` — must be 0.
Modules
CRM
Priority
MUST
Owner
CSO-Sales
NFR-CRM-003 Quarterly: score AUC vs actual won/lost outcomes ≥ 0.70; score drift trigger ≤ 5pp P1 Verify: T

CRM lead-scoring drift — score model MUST be re-evaluated quarterly against actual outcomes

The lead-scoring model (`TASK-CRM-006`) MUST be re-evaluated quarterly against actual won/lost outcomes; AUC ≥ 0.70 to remain in production.

Measurement
Quarterly AUC against held-out outcomes.
Modules
CRM
Priority
SHOULD
Owner
CSO-Sales
NFR-CRM-008 100% of won deals create or link to a PROJ engagement within 24h P0 Verify: T

CRM conversion-to-engagement integrity — closed deal MUST link to a PROJ engagement

When a deal transitions to `won`, a PROJ engagement MUST be created or linked within 24h.

Measurement
Counter `crm_won_deal_engagement_linked_total`.
Modules
CRM
Priority
MUST
Owner
COO
NFR-CUO-201 stripe collision rate ≤ 2⁻³² (8-hex SHA-256 truncation birthday bound); open/ glob check p95 < 10ms over ≤ 1000 open proposals P0 Verify: T

stripe-dedup MUST be deterministic + collision-bounded + check < 10ms p95

`cuo.core.stripe.compute_stripe(skill_name, signal_id, evidence_rows)` MUST be deterministic — same inputs across processes, sessions, and OS versions produce the same stripe id (verified by repeating the call with identical args and asserting string equality).

Measurement
Determinism: `test_stripe_determinism` in `modules/cuo/tests/test_refinement_proposal.py` already verifies — same evidence → same stripe across two calls in the same process.
Modules
cuo
Priority
MUST
Owner
CTO
NFR-CUO-202 classify_proposal: 100% deterministic across runs; 0% mutation of any file; test-gate failure → 100% queue (never auto-apply) P0 Verify: T

proposal classifier MUST be deterministic + read-only + test-gate-blocking

`cuo.core.proposal_applier.classify_proposal(proposal_path, skill_root)` MUST be deterministic — same proposal body + same target SKILL.md → same `Classification` dataclass across runs / processes / sessions.

Measurement
Determinism (already covered by TASK-CUO-202 tests): not a separate benchmark — `test_classify_is_read_only` + `test_bump_levels` together prove classification stability.
Modules
cuo
Priority
MUST
Owner
CTO
NFR-CUO-003 100% of workflows dispatch to exactly one handler; 0 fallback-to-default in production P0 Verify: T

CUO handler dispatch correctness — workflow pattern maps to single handler

Every workflow declaring a `pattern:` in its frontmatter MUST dispatch to exactly one Handler subclass (`LinearHandler | TimeCriticalHandler | PerInstanceHandler | MultiOutputHandler | SequentialApprovalHandler | PersonaPairHandler`) — there is no "default" fallback.

Measurement
CI metric `cuo_workflows_missing_pattern_count` — must be 0.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-004 100% of invoker selection follows the documented ladder; explicit selection always honoured P0 Verify: T

CUO LLM invoker fallback ladder — MockInvoker → SubprocessInvoker → LLMInvoker

The CUO supervisor's `select_invoker("auto")` function MUST prefer in priority order: (a) `SubprocessInvoker` if `cyberos-skill` binary is on `$PATH`, else (b) `MockInvoker`.

Measurement
Counter `cuo_invoker_selected_total{invoker, mode=auto|explicit}`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-007 100% of replayed chains match original step count + skill chain + outcome P1 Verify: T

CUO replay safety — replayed chain MUST produce same audit row count + order

Replaying a previously-executed chain (via `cyberos-cuo execute --replay <chain_id>`) MUST produce the same `step_count`, same `skill_chain`, same `outcome` as the original.

Measurement
Counter `cuo_replay_attempt_total{result=success|version_gone|mismatch}`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-009 100% of step failures with declared compensations execute the rollback in reverse order P0 Verify: T

CUO per-step rollback — failed step MUST trigger declared compensations in reverse order

When a chain step fails AND the chain declares `rollback: <skill_id>` per step, all completed steps' rollback skills MUST execute in strict reverse order before the chain exits.

Measurement
Counter `cuo_rollback_attempt_total{step_index, result=success|failed|timeout}`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-010 0 lost checkpoints after process crash; recovery resumes from last fsync'd checkpoint P0 Verify: T

CUO LangGraph Postgres checkpointer durability — checkpoint writes MUST be fsync'd

LangGraph state checkpoints MUST be written to Postgres with `synchronous_commit = on`; checkpoint writes that return success are durable.

Measurement
Histogram `cuo_checkpoint_write_latency_seconds`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-DOC-005 100% of IDV methods (VNeID, eIDAS, AATL, email-link) reachable from each tenant region P0 Verify: T

DOC IDV method coverage — all 4 declared methods MUST be reachable per tenant

The four declared IDV methods (`vneid`, `eidas`, `aatl`, `email_link`) MUST all be reachable + functional for every tenant in supported regions; outages are tracked per method per region.

Measurement
Per-method availability gauges (hourly probe + monthly aggregate).
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-006 100% of tracked-expiry documents fire alerts at the four scheduled cadences within ±1 day P0 Verify: T

DOC expiry alert latency — alerts MUST fire at 90/30/7/1 day(s) before document expiry

Documents with `expiry_at:` metadata MUST trigger alerts at 90, 30, 7, and 1 day(s) before expiry, each within ±1 day of the scheduled point.

Measurement
Counter `doc_expiry_alert_fired_total{cadence}`.
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-007 100% of renewal drafts preserve original terms (parties, scope, term length) modulo explicit deltas P1 Verify: T

DOC renewal-draft accuracy — generated renewal MUST preserve original terms unless flagged

The renewal-proposal CUO workflow (`TASK-DOC-009`) MUST generate a renewal draft that preserves the original document's core terms unless the workflow explicitly flags a delta.

Measurement
Sample audit: CLO-Legal reviews 10% of generated drafts for unexpected mutations; counter `doc_renewal_unexpected_mutation_total`.
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-008 100% of sequential-signing workflows complete in declared signer order; 0 out-of-order signatures P0 Verify: T

DOC signing workflow integrity — multi-party sign MUST complete in declared order

Multi-party signing flows declared as `sequence: ordered` MUST require signers to sign in declared order; signer N cannot sign before signers 1..N-1 have completed.

Measurement
Counter `doc_sign_order_violation_total` — must be 0.
Modules
DOC
Priority
MUST
Owner
CTO
NFR-EMAIL-005 ≥ 99% of incoming messages with In-Reply-To are correctly merged into the parent thread P0 Verify: T

EMAIL thread merge correctness — In-Reply-To + References MUST group messages correctly

Inbound messages carrying `In-Reply-To` or `References` headers MUST be merged into the parent thread when the parent exists in the tenant's inbox.

Measurement
Counter `email_thread_merge_total{method=header|subject|new}`.
Modules
EMAIL
Priority
MUST
Owner
CTO
NFR-HR-004 100% of member leave balances match accrual - usage within ±0.01 days P0 Verify: T

HR leave-balance accuracy — accrued - used = balance within ±0.01 days

Per-member per-leave-type balance MUST satisfy: `accrued - used - corrections = current_balance`, within ±0.01 days.

Measurement
Daily reconciliation: `hr_leave_balance_drift_days{member, leave_type}` — must be < 0.01.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-HR-007 100% of onboarding sagas reach terminal state; crashes recover from last step P0 Verify: T

HR onboarding saga durability — every step MUST be replayable; crashes recoverable

The HR onboarding saga (`TASK-HR-007`) MUST persist step state in a durable journal — process crashes resume at last completed step.

Measurement
Counter `hr_onboarding_saga_total{outcome}`.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-MCP-004 100% of task state transitions follow the spec FSM; 0 backward transitions P1 Verify: T

MCP task primitive lifecycle — task state transitions MUST be linear + auditable

Tasks (per the spec `tasks` primitive) MUST transition through states `pending → running → (succeeded | failed | cancelled)` — no backward transitions; no state outside the closed set.

Measurement
Histogram `mcp_task_lifetime_seconds{outcome}`.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MCP-008 p95 < 2s for server heartbeat; 99.5% monthly availability per server P0 Verify: T

MCP server heartbeat availability — registered servers MUST respond within 2s

Every registered MCP server MUST respond to the gateway's heartbeat probe (`ping` or equivalent) within 2s p95.

Measurement
Histogram `mcp_server_heartbeat_latency_seconds{server_id}`.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MEMORY-005 Two consecutive `cyberos-memory export` runs on an unchanged store produce identical SHA-256 hashes on the output bundle P1 Verify: T

memory deterministic export bit-identity — two runs on same store produce byte-identical zip

The `cyberos-memory export <tenant_id>` command MUST produce a deterministic ZIP bundle: two runs against the same Layer-2 state MUST produce byte-identical output (verified by SHA-256 of the zip file).

Measurement
Test artifact archive — `tests/memory/export_determinism/expected_hashes.txt` lists expected SHA-256s for a battery of test stores.
Modules
memory
Priority
MUST
Owner
CTO
NFR-OBS-004 p95 < 30s from Alertmanager rule fire to CUO runbook surfaced to on-call P0 Verify: T

Alert-to-CUO-runbook routing latency — p95 < 30s from rule fire to runbook surface

From the moment a Prometheus alert rule transitions to `firing`, the CyberOS routing pipeline MUST surface the matched CUO runbook to the on-call surface (Slack channel + CUO supervisor) at p95 < 30s and p99 < 60s.

Measurement
Histogram `obs_alert_to_runbook_seconds` measured from Alertmanager's `startsAt` to the Slack-webhook delivery timestamp on the routed message.
Modules
OBS
Priority
MUST
Owner
CTO
NFR-OKR-003 100% of auto-progress computations within ±2% of independent per-KR computation P0 Verify: T

OKR auto-progress accuracy — batch-computed progress MUST match per-KR sample within ±2%

The nightly auto-progress batch (`TASK-OKR-004`) MUST produce per-KR progress values within ±2% of an independent re-computation.

Measurement
Daily reconciliation: batch values vs sample-recomputed; counter `okr_progress_delta_pct{kr}` histogrammed.
Modules
OKR
Priority
MUST
Owner
CEO
NFR-OKR-006 100% of cycles advance phase per schedule; 0 stuck or auto-jumped phases P0 Verify: T

OKR cycle-phase advance correctness — cycle phases MUST advance per declared schedule

OKR cycles MUST advance through declared phases: `draft → active → mid-cycle-check → final-check → retro-draft → closed` on the declared schedule.

Measurement
Counter `okr_cycle_phase_transition_total{from, to}`.
Modules
OKR
Priority
MUST
Owner
CEO
NFR-OKR-008 100% of child objectives have a resolvable parent; 0 orphan trees P0 Verify: T

OKR objective cascade integrity — child objectives MUST chain to parent at all times

Objectives declaring `parent: <objective_id>` MUST reference a real, active objective in the same tenant.

Measurement
Counter `okr_orphan_child_total` — must be 0.
Modules
OKR
Priority
MUST
Owner
CEO
NFR-PROJ-001 100% of concurrent edit sets converge within 2s of last network exchange P0 Verify: T

PROJ Yjs CRDT convergence — concurrent edits MUST converge to identical state across all clients

Concurrent edits to the same project artifact (issue, brief, cycle plan) via Yjs CRDT MUST converge to byte-identical state across all connected clients within 2s after the last network exchange.

Measurement
Histogram `proj_yjs_convergence_latency_seconds` — measured by synthetic multi-client probes.
Modules
PROJ
Priority
MUST
Owner
CTO
NFR-PROJ-002 100% of unbilled time entries reflect the current rate-card within 60s of rate change P0 Verify: T

PROJ billable cascade correctness — rate-card change MUST propagate to all unbilled time

When a rate-card row is created/updated/deactivated, all unbilled time entries falling under that rate-card's scope MUST recompute their `billable_amount` within 60s.

Measurement
Histogram `proj_billable_cascade_latency_seconds` — time from rate change to last entry recomputed.
Modules
PROJ
Priority
MUST
Owner
CFO
NFR-PROJ-003 100% of memory_link references resolve; 0 dangling links in production P0 Verify: T

PROJ memory_link integrity — every memory_link MUST resolve to a real memory row

Every `memory_link` field on a PROJ entity (issue, decision-anchor, cycle review) MUST reference a real, accessible memory row by its `(tenant_id, actor_id, seq)` triple.

Measurement
Counter `proj_memory_link_create_failed_total{reason=row_missing|tenant_mismatch}` — write-time gate.
Modules
PROJ
Priority
MUST
Owner
CTO
NFR-PROJ-006 100% of Gantt critical-path computations match a reference CPM implementation P1 Verify: T

PROJ Gantt critical path correctness — CPM algorithm MUST match reference output

The Gantt view's critical-path-method (CPM) computation MUST match a reference implementation for any dependency graph the UI accepts (acyclic, single-source, single-sink, or general DAG).

Measurement
Counter `proj_gantt_cpm_mismatch_total` — must be 0.
Modules
PROJ
Priority
SHOULD
Owner
CTO
NFR-PROJ-009 100% of issue state transitions match the FSM; 0 illegal transitions in production P0 Verify: T

PROJ issue state machine — transitions MUST conform to the declared FSM

Issue state transitions MUST conform to the FSM declared in `modules/proj/state-machine.yaml`: states + allowed transitions + required roles.

Measurement
Counter `proj_issue_illegal_transition_total{from, to}` — must be 0.
Modules
PROJ
Priority
MUST
Owner
CTO
NFR-RES-006 Flag agreement with COO confirmation ≥ 95% over a 4-week sample P1 Verify: T

RES capacity-flag accuracy — flag MUST match human-confirmed over/under state ≥ 95% of time

The capacity flags (over-alloc, under-alloc) MUST match COO's human assessment of the same member ≥ 95% of the time over a 4-week rolling sample.

Measurement
Weekly: COO samples 10 flags + 10 unflagged; computes agreement rate.
Modules
RES
Priority
SHOULD
Owner
COO
NFR-REW-001 100% of payroll runs are bit-identical on rerun with same inputs + parameter version P0 Verify: T

REW comp-formula determinism — same inputs MUST produce same payroll output across reruns

The monthly payroll compute (`TASK-REW-005`) MUST produce byte-identical outputs when rerun with the same `{member_set, parameter_version, period, 3p_income_set}` tuple.

Measurement
Hash comparison on every recompute; counter `rew_payroll_recompute_hash_mismatch_total` — must be 0 if inputs unchanged.
Modules
REW
Priority
MUST
Owner
CFO
NFR-REW-003 100% conservation: |pool_in - (pool_distributed + carry_over)| < 1 VND per quarter P0 Verify: T

REW bonus-pool conservation — pool inflow MUST equal sum of distributions + carry-over

The bonus-pool ledger (`TASK-REW-007`) MUST satisfy: every inflow row sums to the same total as the corresponding outflow rows (distribution) plus the carry-over balance, per quarter.

Measurement
Per-quarter `rew_bp_conservation_delta_vnd` — must be ≤ 1.
Modules
REW
Priority
MUST
Owner
CFO
NFR-REW-006 100% of payslips satisfy gross - (PIT + SI + other deductions) = net within ±1 VND P0 Verify: T

REW gross/net reconciliation — gross - deductions MUST equal net for every payslip

Every payslip row MUST satisfy the identity: `gross_vnd - (pit_vnd + si_employee_vnd + advance_recovery_vnd + other_deductions_vnd) = net_vnd`, within ±1 VND tolerance for rounding.

Measurement
Per-cycle counter `rew_payslip_reconciliation_fail_total{period}` — must be 0.
Modules
REW
Priority
MUST
Owner
CFO
NFR-REW-007 100% of VietQR batches verifiable: |sum(batch.amounts) - sum(payslip.nets)| = 0 P0 Verify: T

REW VietQR payroll batch integrity — batch hash MUST match sum of payslip nets

Each VietQR payroll batch MUST be cryptographically tied to the payslip set it disburses: the batch row carries a SHA-256 hash of the canonical-sorted payslip-net list.

Measurement
Counter `rew_vietqr_hash_mismatch_total` — must be 0.
Modules
REW
Priority
MUST
Owner
CFO
NFR-SKILL-003 99.95% monthly availability for GET /v2/<bundle>/manifests/<ref> + blobs/<digest> P0 Verify: A

SKILL OCI registry availability — 99.95% read SLO for bundle pulls

The SKILL OCI registry MUST serve manifest reads (`GET /v2/<name>/manifests/<ref>`) and blob reads (`GET /v2/<name>/blobs/<digest>`) at ≥ 99.95% monthly availability measured at the public ingress.

Measurement
Synthetic prober every 60s from 3 regions hitting `GET /v2/cyberos-skill-task-author/manifests/latest`.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-SKILL-007 deterministic-flag skills produce byte-identical outputs over 100 reruns with fixed seed P1 Verify: T

SKILL deterministic-output mode — fixed seed produces byte-identical output

Skills declaring `deterministic: true` in their manifest frontmatter MUST produce byte-identical outputs when invoked twice with the same `{inputs, seed, capabilities}` tuple.

Measurement
CI gate per `deterministic: true` skill: rerun 5 times with same seed; assert all outputs hash-match.
Modules
SKILL
Priority
SHOULD
Owner
CTO
NFR-TEN-001 100% of tenant-create sagas reach terminal state (committed | rolled-back); 0 stuck-in-progress P0 Verify: T

TEN provisioning saga reliability — every tenant create MUST be transactional

Tenant provisioning MUST run as a saga with all-or-nothing semantics: every step succeeds and the tenant is committed, OR any step fails and all prior steps roll back.

Measurement
Counter `ten_provisioning_saga_total{outcome=committed|rolled_back|timeout}`.
Modules
TEN
Priority
MUST
Owner
CTO
NFR-TEN-005 Re-running export with same parameters produces byte-identical bundle hash P0 Verify: T

TEN signed bundle determinism — same tenant export MUST produce same hash

The signed-bundle export (`TASK-TEN-105`) MUST be deterministic — re-running with the same `{tenant_id, export_at}` produces byte-identical output (same SHA-256).

Measurement
Counter `ten_bundle_export_hash_mismatch_total` — must be 0 on re-runs.
Modules
TEN
Priority
MUST
Owner
CTO
NFR-TEN-007 Metered amounts accurate within ±0.1% vs ground-truth reconciliation P0 Verify: T

TEN four-axis metering precision — users/storage/AI/seats measured within ±0.1%

The four metering axes (active users, storage GB-month, AI tokens, seats) MUST report values accurate to within ±0.1% of ground-truth (independent recount from DB).

Measurement
Daily reconciliation: `ten_metering_drift_pct{axis}` — must be < 0.1%.
Modules
TEN
Priority
MUST
Owner
CFO
NFR-TEN-009 99.5% monthly availability for VND-billing initiation + settlement P0 Verify: A

TEN VND domestic rail uptime — VND-billing path MUST maintain 99.5% monthly availability

The VND domestic billing rail (NAPAS + bank integration) MUST maintain 99.5% monthly availability for initiation + settlement.

Measurement
Synthetic prober (60s cadence) against payment initiation endpoint.
Modules
TEN
Priority
MUST
Owner
CFO
SEC

Security

Zero-trust, crypto, compliance gates · 25 NFRs
NFR-AI-006 Property test: 0 cross-tenant cache hits over 10,000 random JWT pairings P0 Verify: T

AI Gateway per-tenant cache cross-leak — zero cross-tenant reads under 10k random JWTs

The AI Gateway prompt/completion cache MUST key every entry by `(tenant_id, persona_version, prompt_hash, model_alias)` — never just `prompt_hash`. The `tenant_id` is taken from the verified JWT, not from any caller-supplied parameter.

Measurement
Property test `services/ai-gateway/tests/cache_cross_tenant_leak_test.rs` (T) runs the 10k-pair generator on every PR; assertion: zero cross-tenant hits.
Modules
AI
Priority
MUST
Owner
CTO
NFR-AUTH-002 Property test: 0 cross-tenant rows returned across 1000 random tenant_id pairings on every RLS-protected table P0 Verify: T

AUTH RLS cross-tenant leak — zero rows leaked under property test sweep of 1k random tenants

Every tenant-scoped Postgres table MUST carry a Row-Level Security (RLS) policy `tenant_id = current_setting('app.tenant_id')::uuid` applied to SELECT, UPDATE, DELETE.

Measurement
Counter `auth_rls_unscoped_query_total` — should always be zero. Sev-0 alarm on any non-zero.
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-AUTH-004 HIBP API call wrapped in 2s hard timeout; timeout never blocks signup; audit row emitted on every timeout P0 Verify: T

AUTH HIBP API timeout policy — 2s hard timeout; fail-open with audit row on timeout

The HaveIBeenPwned (HIBP) k-anonymity API call MUST be wrapped in a 2s hard timeout. If HIBP doesn't respond in 2s, the call is aborted.

Measurement
Counter `auth_hibp_timeout_total` — incremented on every 2s abort. Sev-3 alarm at > 10/hour.
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-AUTH-006 Accept TOTP codes within ±1 30s step (90s window); reject ±2; rate-limit 5 attempts per minute P0 Verify: T

AUTH TOTP drift tolerance — accept ±1 step; reject ±2; rate-limit retries

The TOTP verify endpoint MUST accept codes within ±1 30-second step (effectively a 90-second window: current ± 30s).

Measurement
Counter `auth_totp_verify_total{result}` where result ∈ {`success`, `fail_outside_window`, `fail_invalid_code`, `rate_limited`}.
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-AUTH-007 Rotation operation completes with at least one active key on JWKS at all times; old key marked retired but honored for verify for 7 days P0 Verify: T

AUTH signing-key rotation — active key always present; old key honored 7 days post-rotation

The AUTH signing-key rotation procedure MUST ensure at least one key with `status=active` is present in JWKS at every moment during rotation — there is never a window where JWKS is empty or has no active key.

Measurement
Gauge `auth_signing_keys_active_count` — should always be ≥ 1. Sev-0 alarm on 0.
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-AUTH-009 Password hashing uses bcrypt cost ≥ 12; production override via AUTH_BCRYPT_COST env P0 Verify: I

AUTH bcrypt cost — ≥ 12 rounds; tunable via AUTH_BCRYPT_COST env

Password hashing in AUTH MUST use bcrypt with cost factor ≥ 12 (default 12; configurable via `AUTH_BCRYPT_COST` env var).

Measurement
Histogram `auth_password_hash_seconds` — at cost 12 expect ~250ms; at cost 13 expect ~500ms. Alerts at < 100ms (cost too low) and > 1000ms (cost too high or CPU contention).
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-AUTH-010 OIDC state tokens expire 10 minutes after issuance; single-use; CSRF-bound to session P0 Verify: T

AUTH OIDC state-token TTL — 10-minute hard expiry; CSRF-resistant; one-shot

OIDC `state` parameters issued during the Authorization Code flow MUST expire exactly 10 minutes after issuance. The callback handler rejects expired states with HTTP 400 `state_expired`.

Measurement
Counter `auth_oidc_state_consumed_total{result}` where result ∈ {`success`, `expired`, `replayed`, `csrf_mismatch`, `invalid_mac`}.
Modules
AUTH
Priority
MUST
Owner
CSO
NFR-CRM-006 100% of account-bank changes emit a signed audit row + trigger CFO notification P0 Verify: T

CRM bank-config audit — account banking changes MUST emit signed audit row

Changes to an account's banking info (bank, branch, account number, beneficiary name) MUST emit a signed audit row with `{actor_id, account_id, old_banking_hash, new_banking_hash, changed_at}`.

Measurement
Counter `crm_bank_change_total{actor_role}`.
Modules
CRM
Priority
MUST
Owner
CFO
NFR-DOC-009 100% of imported signed docs verified at import; invalid signatures flagged + quarantined P0 Verify: T

DOC third-party import validation — imported signed docs MUST be signature-verified

Documents imported from third-party providers (DocuSign, Adobe Sign, etc.) MUST have their signatures verified at import time against the issuing CA chains.

Measurement
Counter `doc_import_signature_status_total{status=valid|invalid|unsigned}`.
Modules
DOC
Priority
MUST
Owner
CTO
NFR-EMAIL-002 Recall ≥ 95% on the platform's adversarial prompt-injection email corpus P0 Verify: T

EMAIL CaMeL prompt-injection blocking — recall ≥ 95% on the held-out adversarial set

The CaMeL dual-LLM defence (`TASK-EMAIL-005`) MUST detect prompt-injection content in inbound mail at recall ≥ 95% on the platform's held-out adversarial corpus (200+ samples curated by CISO).

Measurement
Per-quarter benchmark: recall + FP rate against held-out + legitimate corpus.
Modules
EMAIL
Priority
MUST
Owner
CISO
NFR-EMAIL-004 100% of outbound emails pass DKIM + SPF + DMARC alignment for the tenant's sending domain P0 Verify: T

EMAIL DKIM/SPF/DMARC pass-through — outbound mail MUST be DMARC-aligned

Every outbound email MUST carry a valid DKIM signature aligned to the tenant's sending domain; the platform refuses to send unsigned mail.

Measurement
Hourly synthetic mail-to-self DMARC pass rate per tenant.
Modules
EMAIL
Priority
MUST
Owner
CTO
NFR-EMAIL-006 100% of CaMeL pipeline runs maintain LLM separation; 0 untrusted-content-with-tools events P0 Verify: T

EMAIL dual-LLM separation — quarantined LLM MUST NOT see untrusted content + tool surface

The CaMeL dual-LLM architecture MUST maintain strict separation: the "privileged" LLM has tool access but never sees raw email body; the "quarantined" LLM sees raw body but has zero tool access.

Measurement
Counter `email_camel_quarantined_tool_attempt_total` — must be 0.
Modules
EMAIL
Priority
MUST
Owner
CISO
NFR-EMAIL-008 100% of bulk sends (>100 recipients) carry a recorded approval; 0 auto-sent bulks P0 Verify: T

EMAIL bulk-send approval — sends > 100 recipients MUST require explicit approval

Outbound sends with > 100 unique recipients MUST be paused for explicit approval by a tenant role granted `email:bulk:approve`.

Measurement
Counter `email_bulk_send_attempt_total{result=approved|paused|rejected}`.
Modules
EMAIL
Priority
MUST
Owner
CTO
NFR-KB-002 p95 < 60s from revoke action to refused-access at any edge P0 Verify: T

KB share-link revocation — revoked link MUST stop working within 60s globally

Revoking a KB share link MUST propagate to all read paths (origin + CDN + cached link tables) within 60s p95.

Measurement
Histogram `kb_share_link_revocation_propagation_seconds`.
Modules
KB
Priority
MUST
Owner
CTO
NFR-MCP-002 100% of tools annotated destructive=true gate behind human approval; 0 silent destructions P0 Verify: T

MCP tool annotation gating — destructive ops require explicit human approval annotation

Every MCP tool exposed by CyberOS MUST declare annotations: `{destructive: bool, readOnly: bool, openWorld: bool}`.

Measurement
Counter `mcp_destructive_call_attempt_total{tool, approved}` — surfaces approval rates.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MCP-003 100% of MCP-bound tokens carry aud=mcp:<server-id>; cross-audience use rejected P0 Verify: T

MCP audience-bound tokens — OAuth tokens MUST be aud-scoped to the MCP server

Tokens issued for use against an MCP server MUST carry the JWT `aud` claim equal to `mcp:<server-id>` (e.g., `mcp:cyberos-projects`).

Measurement
Counter `mcp_token_aud_mismatch_total{server_id, token_aud}`.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MCP-005 100% of elicitation prompts pass injection-safety lint; clients can always decline P1 Verify: T

MCP elicitation prompt safety — server-issued prompts MUST be scoped + escapable

MCP elicitation prompts (server → client requests for additional info) MUST NOT contain instructions that override the host shell's own system prompt or behaviour rules.

Measurement
Counter `mcp_elicitation_lint_block_total{server, reason}`.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MCP-007 100% of authorization-code requests carry valid PKCE challenge; implicit grant disabled P0 Verify: T

MCP OAuth PKCE — authorization code flow MUST require PKCE; no implicit grant

The MCP-AUTH endpoint MUST require PKCE (RFC 7636) for every authorization code request — `code_challenge` + `code_challenge_method=S256` are mandatory.

Measurement
Counter `mcp_oauth_pkce_missing_total` — must be 0.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MEMORY-002 100% of l2_memory reads re-verify the chain anchor; any mismatch quarantines the row and sev-1 alerts P0 Verify: T

memory chain-anchor verification — every l2_memory read re-checks anchor; mismatch → quarantine

Every read from `l2_memory` MUST re-verify the row's chain anchor (hash of `(prev_chain_hash, payload_canonical_json)`) against the on-row `chain_hash` column.

Measurement
Counter `memory_l2_anchor_verify_total{result}` where result ∈ {`ok`, `mismatch`}.
Modules
memory
Priority
MUST
Owner
CSO
NFR-MEMORY-003 Property test: 0 cross-tenant cursor influence under 1000 random advance sequences P0 Verify: T

memory per-tenant cursor isolation — cursor advance for tenant A never affects tenant B

The Layer-2 ingest cursor (`services/memory/src/layer2/cursor.rs`) MUST be scoped per (tenant_id, actor_id) — there is no global cursor that crosses tenants.

Measurement
Per-tenant gauge `memory_layer2_cursor_pos{tenant_id, actor_id}`.
Modules
memory
Priority
MUST
Owner
CSO
NFR-OBS-006 Tenant A user views ONLY tenant A data in Grafana; zero cross-tenant leakage under property test P0 Verify: T

OBS compliance view scoping — per-tenant RLS-equivalent on Grafana proxy

The tenant-aware Grafana proxy MUST rewrite every PromQL, LogQL, and TraceQL query to inject a `tenant_id=<tenant_from_jwt>` filter before forwarding to Prometheus, Loki, or Tempo respectively (NFR-OBS-008 covers the AST coverage).

Measurement
Counter `obs_proxy_unscoped_query_total{role}` — should be zero for any role lacking `tenant_scope=global`.
Modules
OBS
Priority
MUST
Owner
CSO
NFR-OBS-008 100% of PromQL, LogQL, TraceQL queries through the proxy carry an injected tenant_id filter (verified per-query-language test suite) P0 Verify: T

Grafana proxy AST-injection coverage — PromQL + LogQL + TraceQL all rewritten with tenant_id

The tenant-aware Grafana proxy MUST parse incoming queries into the language-specific AST (PromQL, LogQL, TraceQL) — MUST NOT use regex-based rewriting which is bypassable via comment-injection.

Measurement
Counter `obs_proxy_ast_parse_failed_total{language}` — should be near-zero; high values indicate AST parser drift.
Modules
OBS
Priority
MUST
Owner
CSO
NFR-OKR-002 100% of custom-SQL KRs carry both signatures + readonly DB role P0 Verify: T

OKR custom-SQL co-sign — custom-SQL KRs MUST require CTO + objective-owner co-sign

KRs using `custom-sql` progress source MUST be co-signed by CTO + the objective owner before activation; the SQL is reviewed for safety + correctness.

Measurement
Counter `okr_custom_sql_activation_total{has_both_signatures}`.
Modules
OKR
Priority
MUST
Owner
CTO
NFR-SKILL-008 0 cap-bypass incidents in 90 days; 100% of attempted escapes blocked + audited P0 Verify: T

SKILL sandbox isolation — skill execution MUST NOT escape declared capabilities

A skill MUST NOT access any platform resource (DB, network, filesystem, secrets) outside the capabilities declared in its manifest and granted by the broker.

Measurement
Counter `skill_cap_bypass_attempt_total{skill, denied_call, syscall_or_host}`.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-TEN-006 100% of hostile-override terminations carry CEO + CLO signatures within 24h window P0 Verify: T

TEN hostile-override approval window — emergency termination requires CEO + CLO co-sign

Hostile termination (TASK-TEN-202) — used when a tenant is committing abuse and the normal 90-day FSM is too slow — MUST require both CEO and CLO-Legal signatures within a 24-hour window.

Measurement
Counter `ten_hostile_override_total{tenant, signers_count}` — single-signer = 0.
Modules
TEN
Priority
MUST
Owner
CTO
USAB

Usability & Accessibility

WCAG, keyboard, i18n, readability · 4 NFRs
NFR-KB-003 Recall@10 ≥ 90% on the platform's labeled query/document corpus P1 Verify: T

KB semantic search recall — bge-m3 + rerank MUST hit recall@10 ≥ 90%

KB semantic search (`TASK-KB-005` bge-m3 + `TASK-KB-006` rerank) MUST achieve recall@10 ≥ 90% on the platform's labeled evaluation corpus (1000+ query/doc pairs).

Measurement
Per-quarter benchmark: recall@10, MRR, latency p95.
Modules
KB
Priority
SHOULD
Owner
CTO
NFR-KB-004 Recall ≥ 99% for known-keyword queries; p95 latency < 200ms P0 Verify: T

KB lexical search recall — FTS5 + pgroonga MUST cover known-keyword queries at ≥ 99%

Lexical search (FTS5 for SQLite tier; pgroonga for Postgres tier) MUST find documents containing exact keyword matches at recall ≥ 99% — known-keyword queries should not silently miss documents.

Measurement
Per-quarter benchmark: recall on known-keyword test set.
Modules
KB
Priority
MUST
Owner
CTO
NFR-KB-005 100% of tagged runbooks surface in top-3 for canonical incident-keyword queries P1 Verify: T

KB runbook-tag accuracy — runbook docs MUST be findable by incident-keyword + tag combo

Documents tagged `kind:runbook` MUST be retrievable via the API `?tag=runbook&query=<incident-keyword>` and rank in the top-3 results for the keyword.

Measurement
Per-quarter benchmark: top-3 accuracy on canonical incident queries.
Modules
KB
Priority
SHOULD
Owner
CTO
NFR-PROJ-007 0 critical/serious axe-core violations per page; 100% page coverage in CI P0 Verify: T

PROJ a11y-ci gate — every page MUST pass axe-core with 0 critical/serious issues

Every PROJ page MUST pass `axe-core` with 0 critical and 0 serious violations in the CI a11y-ci gate.

Measurement
Per-page counter `proj_axe_violation_count{page, severity}` — critical/serious must be 0.
Modules
PROJ
Priority
MUST
Owner
CTO
MAINT

Maintainability

CI speed, coverage, schema deprecation · 16 NFRs
NFR-CHAT-004 Fork rebased onto upstream minor monthly; major version quarterly; security CVEs within 14 days P0 Verify: I

CHAT Mattermost fork upstream-merge cadence — monthly minor rebase; quarterly major

The CyberOS Mattermost fork MUST be rebased onto upstream minor releases at least monthly (the first business day after the upstream minor ships).

Measurement
File inspection — `MATTERMOST_UPSTREAM_VERSION.md` must be current; quarterly audit.
Modules
CHAT
Priority
SHOULD
Owner
CTO
NFR-CRM-001 100% of account/contact/deal rows satisfy schema + relational invariants P0 Verify: T

CRM account-contact-deal schema invariants — required fields + closed enum + relational integrity

The three core CRM tables (`account`, `contact`, `deal`) MUST enforce required fields + closed enum values declared in `modules/crm/schema/`.

Measurement
CI metric `crm_schema_violation_count` — must be 0.
Modules
CRM
Priority
MUST
Owner
CSO-Sales
NFR-CRM-007 100% of deal-stage transitions create audit rows; history immutable P0 Verify: T

CRM deal-stage history — every stage change MUST be append-only audited

Every deal stage transition MUST create an append-only audit row with `{deal_id, from_stage, to_stage, actor_id, changed_at, reason?}`.

Measurement
Counter `crm_deal_stage_transition_total{from, to}`.
Modules
CRM
Priority
MUST
Owner
CSO-Sales
NFR-CUO-006 100% of workflow frontmatter parses; failed parses produce {file,line,reason} error P0 Verify: T

CUO workflow-pattern parsing — YAML safe-load + closed enum + clean error reporting

Workflow YAML frontmatter MUST parse with `yaml.safe_load()` (no full YAML loader, no arbitrary tag execution).

Measurement
Counter `cuo_workflow_parse_error_total{file, reason}`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-EMAIL-003 BIMI VMC + DNS record validated weekly; alert ≥ 30 days before expiry P1 Verify: A

EMAIL BIMI freshness — VMC + BIMI record MUST stay valid; auto-alert on expiry

The tenant's BIMI Verified Mark Certificate (VMC) + DNS BIMI record MUST be validated weekly via the platform's BIMI prober.

Measurement
Gauge `email_bimi_vmc_days_until_expiry{tenant}`.
Modules
EMAIL
Priority
SHOULD
Owner
CTO
NFR-HR-001 100% of member rows satisfy required-field + uniqueness invariants P0 Verify: T

HR member schema invariants — required fields + closed enum types + unique member_id

The HR `member` table MUST enforce: required fields (`member_id, full_name, email, employment_status, hire_date, contract_type`); closed enum for `employment_status` and `contract_type`.

Measurement
CI metric `hr_member_schema_violation_count` — must be 0.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-KB-001 100% of document saves produce a version row; history immutable; retention ≥ 1 year P0 Verify: T

KB document versioning history — every save MUST create an immutable version row

Every document save MUST create an immutable version row in `kb_document_version` carrying `{doc_id, version_no, author_id, saved_at, body_hash, body_blob_ref}`.

Measurement
Counter `kb_document_save_total{result}`.
Modules
KB
Priority
MUST
Owner
CTO
NFR-KB-006 100% of `translation_of:` docs reference an existing source; sync lag ≤ 24h after source change P1 Verify: T

KB translation parity — translated doc MUST reference + lag source by ≤ 24h

Documents with `translation_of: <doc_id>` frontmatter MUST point to a real source document in the same tenant.

Measurement
Counter `kb_translation_dangling_total` — must be 0.
Modules
KB
Priority
SHOULD
Owner
CTO
NFR-OKR-001 100% of KRs use the closed enum types; 100% of numeric KRs are computable from declared source P0 Verify: T

OKR objective-KR schema invariants — KR types closed enum; numeric KRs measurable

KR types MUST be a closed enum: `numeric`, `binary`, `milestone-progress`, `custom-sql`. Ad-hoc types are rejected at create time.

Measurement
CI metric `okr_kr_invalid_type_count` — must be 0.
Modules
OKR
Priority
MUST
Owner
CEO
NFR-OKR-005 100% of digest recipient lists reflect terminations + role changes within 24h P1 Verify: T

OKR digest-recipient freshness — Monday digest list MUST match current tenant roster

The Monday OKR digest (`TASK-OKR-006`) MUST be delivered only to currently-active members; terminated members MUST be removed within 24h of HR transition.

Measurement
Counter `okr_digest_sent_to_terminated_total` — must be 0.
Modules
OKR
Priority
SHOULD
Owner
CHRO
NFR-PROJ-004 100% of mid-cycle additions/removals tracked + visible in the cycle review draft P1 Verify: T

PROJ cycle-window enforcement — work added mid-cycle MUST be flagged + tracked

Cycle windows (default 2-week sprint, configurable) MUST be persisted with `{start_at, end_at, frozen_at}` where `frozen_at` is the moment scope is closed.

Measurement
Per-cycle counters: `proj_cycle_added_post_freeze_total`, `proj_cycle_removed_post_freeze_total`.
Modules
PROJ
Priority
SHOULD
Owner
CTO
NFR-PROJ-008 0 raw hex or raw px values in PROJ component CSS/JSX; tokens consumed exclusively P0 Verify: T

PROJ design-tokens drift — UI MUST consume tokens; raw hex/px values are CI-banned

PROJ UI component source (`apps/proj/src/`) MUST NOT contain raw hex color values (`#...`), raw RGB/HSL strings, or raw pixel values for spacing/typography.

Measurement
CI metric `proj_raw_color_value_count` — must be 0.
Modules
PROJ
Priority
MUST
Owner
CTO
NFR-RES-007 100% of terminated members removed from active allocations within 24h of termination effective date P0 Verify: T

RES member-departure handling — terminated members MUST be removed from active allocations within 24h

When a member's HR record transitions to `terminated` with effective date D, all active allocations MUST be ended by D + 24h.

Measurement
Counter `res_terminated_member_active_alloc_total` — must trend to 0 within 24h.
Modules
RES
Priority
MUST
Owner
COO
NFR-SKILL-001 100% of published manifests pass schema validation; 0 unknown-field tolerance P0 Verify: T

SKILL manifest schema invariants — required-field gate + semver discipline

Every SKILL bundle published to the OCI registry MUST carry a top-level `SKILL.md` whose YAML frontmatter parses cleanly and contains the closed set of required keys: `name`, `version`, `description`, `inputs`, `outputs`, `capabilities`, `audit`.

Measurement
Counter `skill_publish_validation_failure_total{stage=client|server, error_code}` per failed publish.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-SKILL-006 0 author skills exist without a sibling audit skill; CI gates publish P0 Verify: T

SKILL fine-tune loop integrity — author+audit pair MUST stay in lockstep

Every author skill at `skill/public/<name>/` MUST have a sibling audit skill at `skill/public/<name>-audit/` carrying matching version + same set of declared outputs.

Measurement
CI metric `skill_pair_drift_count` — counts authors without audits; must be 0 to merge.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-SKILL-010 100% of skill outputs validate against their declared output contract P0 Verify: T

SKILL output contract conformance — produced output MUST match declared schema

Every skill output MUST match the JSON Schema declared in `outputs:` of its `SKILL.md` frontmatter, validated by the runtime before the output is handed back to the caller.

Measurement
Counter `skill_output_schema_check_total{skill, result=pass|fail}`.
Modules
SKILL
Priority
MUST
Owner
CTO
FUNC

Functional Suitability

Functional correctness, determinism · 2 NFRs
NFR-CHAT-005 Hybrid Vietnamese search (lexical + diacritic-folded + vector) recall@10 ≥ 0.90 on VN test corpus P0 Verify: T

CHAT VN-search recall floor — hybrid lexical + diacritic-folded recall@10 ≥ 0.90

The CHAT search endpoint MUST support Vietnamese diacritic-folding: a query "Nguyen" MUST match messages containing "Nguyễn". Conversely, a query with full diacritics MUST match diacritic-less messages.

Measurement
Recall@10 reported quarterly to `docs/audits/chat-vn-search-recall/YYYY-Q*.json`.
Modules
CHAT
Priority
MUST
Owner
CTO
NFR-MEMORY-008 Hybrid lexical + vector search recall@10 ≥ 0.85 on the memory search test corpus P0 Verify: T

memory search API recall floor — lexical hybrid recall@10 ≥ 0.85 on test corpus

The `services/memory/src/search.rs` search API MUST achieve recall@10 ≥ 0.85 on the curated memory search test corpus (`services/memory/tests/fixtures/search_corpus_v*.jsonl`).

Measurement
Recall@10 reported quarterly to `docs/audits/memory-search-recall/YYYY-Q*.json`.
Modules
memory
Priority
MUST
Owner
CTO
COMP

Compliance

Regulatory, legal, audit obligations · 32 NFRs
NFR-AI-009 100% of upstream calls route to a provider region matching the tenant residency policy P0 Verify: T

AI Gateway residency pinning enforcement — provider region matches tenant policy 100%

Every tenant MUST carry a residency policy field `residency_region` ∈ {`apac`, `eu`, `us`, `global`} on the tenants table. The AI Gateway reads this from the JWT or from a cached lookup.

Measurement
Counter `ai_gateway_region_match_total{tenant_region, provider_region, match}` per call.
Modules
AI
Priority
MUST
Owner
CSO
NFR-CHAT-006 100% of messages where subject is author OR recipient are included; memory chain proof attached P0 Verify: T

CHAT DSAR message export completeness — every message subject authored OR received + chain proof

A CHAT DSAR (Data Subject Access Request) export for subject `S` MUST include every message in the platform where `S` is either the author OR a member of the channel (recipient) at the time the message was posted.

Measurement
Counter `chat_dsar_exports_total{result}` per request.
Modules
CHAT
Priority
MUST
Owner
CSO
NFR-CRM-004 100% of large deals (> threshold) carry CFO signature before close P0 Verify: T

CRM win-loss approval — deals > threshold MUST be approved by CFO before close

Deals with `amount_vnd > tenant.large_deal_threshold` MUST require CFO signature before transitioning to `won` or `lost`.

Measurement
Counter `crm_large_deal_no_approval_attempt_total` — must be 0.
Modules
CRM
Priority
MUST
Owner
CFO
NFR-CRM-005 100% of VN business accounts carry a GDT MST validation within last 90 days P0 Verify: T

CRM MST validation freshness — VN business accounts MUST have MST validated within 90 days

Accounts marked `account_type: vn_business` MUST have their MST (tax ID) validated against the GDT lookup within the last 90 days.

Measurement
Gauge `crm_account_mst_age_days{tenant}` — max should be < 90.
Modules
CRM
Priority
MUST
Owner
CFO
NFR-CUO-002 100% of executed chains produce 1 row per step + 1 summary row; reconciliation drift < 0.001% P0 Verify: T

CUO memory audit-chain emission — every chain execution MUST emit ≥ 2 rows

Every CUO chain execution with `--memory-emit` flag set MUST emit one `kind=cuo.step` row per executed step plus one `kind=cuo.chain.end` summary row carrying `{persona, workflow, step_count, started_at, ended_at, outcome}`.

Measurement
Counter `cuo_memory_emit_attempt_total{stage=step|summary, result=success|fail}`.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-CUO-005 100% of audit rows carry persona_slug, persona_version, workflow_slug, workflow_version P0 Verify: T

CUO persona-version stamping — every chain MUST record persona+workflow version

Every CUO chain audit row MUST carry `{persona_slug, persona_version, workflow_slug, workflow_version}` — both slug and version, both for persona and workflow.

Measurement
Counter `cuo_audit_missing_version_total` — must always be 0.
Modules
CUO
Priority
MUST
Owner
CTO
NFR-DOC-001 100% of EU-jurisdiction signatures carry a valid QES attestation from a recognised QTSP P0 Verify: T

DOC eIDAS QTSP attestation — signatures MUST be QES-grade for EU jurisdiction docs

Signatures applied to documents tagged `jurisdiction: EU` MUST be Qualified Electronic Signatures (QES) per eIDAS Regulation EU 910/2014, backed by a QTSP from the EU trusted list.

Measurement
Counter `doc_signature_total{jurisdiction, signature_class}` — assert EU + non-QES = 0.
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-002 100% of PAdES-LT documents restamped at least 30 days before any contained timestamp expires P0 Verify: T

DOC PAdES-LT timestamp freshness — restamp before any timestamp expiry

Documents signed with PAdES-LT (Long-Term) MUST be restamped (PAdES-LTA extension) at least 30 days before any contained timestamp or CRL nears its validity end.

Measurement
Gauge `doc_pades_lt_days_until_restamp_needed{doc_id}` — min across all timestamps.
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-003 100% of VN-jurisdiction signatures chain to a NEAC-recognised CA P0 Verify: T

DOC VN-CA signature compliance — Vietnamese signatures MUST chain to NEAC root

Documents tagged `jurisdiction: VN` MUST be signed with certificates that chain to a National Electronic Authentication Centre (NEAC) recognised root CA.

Measurement
Counter `doc_signature_total{jurisdiction=VN, ca_recognised}` — assert non-recognised = 0.
Modules
DOC
Priority
MUST
Owner
CLO-Legal
NFR-DOC-004 100% of VNeID-verified signers carry the VNeID identifier in the signature attestation P1 Verify: T

DOC VNeID linkage — identity-verified signers MUST be bound to VNeID identifier

When a signer's identity is verified via VNeID (Vietnamese national digital ID), the resulting signature MUST carry the VNeID identifier in the attestation block.

Measurement
Counter `doc_vneid_signature_total`.
Modules
DOC
Priority
SHOULD
Owner
CLO-Legal
NFR-HR-002 100% of contract changes create new versioned row; 0 in-place edits P0 Verify: T

HR contract-history immutability — contract changes MUST create new versions, never edit old

Contract changes (promotion, comp change, role change) MUST create a new contract row with `effective_from` timestamp; the prior row is closed with `effective_to`.

Measurement
Counter `hr_contract_in_place_edit_attempt_total` — must be 0.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-HR-005 100% of in-flight HR cases preserve their original policy version P1 Verify: T

HR policy-version compatibility — policy changes MUST be backward-compatible for in-flight cases

HR policies (leave, working hours, OT rates) MUST be versioned; in-flight cases (a leave request submitted under v1) MUST be evaluated against v1 even after v2 ships.

Measurement
Counter `hr_policy_version_mismatch_total` — case evaluated under wrong version; must be 0.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-HR-006 100% of accrual corrections carry approver signature + structured reason P0 Verify: T

HR accrual-correction audit — every manual leave adjustment MUST require reason + approver

Manual leave-accrual corrections (overrides of the automatic accrual) MUST be approved by a member with `hr:leave:adjust` permission.

Measurement
Counter `hr_accrual_correction_total{reason_code, approver_role}`.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-HR-008 100% of terminations carry both signatures within 72h; expired approvals require resubmission P0 Verify: T

HR termination signoff window — termination MUST be signed by CHRO + line manager within 72h

Termination workflow MUST require both CHRO + line-manager signatures within a 72h rolling window.

Measurement
Counter `hr_termination_total{kind, signers_count}`.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-HR-009 100% of perf-signal rows retained ≥ 7 years; 0 unauthorized deletions P0 Verify: T

HR performance history retention — performance signals MUST be retained ≥ 7 years

Performance signals (reviews, ratings, 360s, PIPs) MUST be retained ≥ 7 years post-member-termination.

Measurement
Gauge `hr_perf_record_oldest_age_years` — must be ≥ 7 for terminated members.
Modules
HR
Priority
MUST
Owner
CHRO
NFR-MCP-001 100% pass on official MCP conformance suite for spec version 2025-11-25 P0 Verify: T

MCP protocol compliance — runtime MUST conform to spec 2025-11-25

The CyberOS MCP runtime MUST implement the JSON-RPC 2.0 message envelope, capability negotiation, and tool/resource/prompt primitives per the MCP spec version 2025-11-25.

Measurement
CI: full conformance suite pass/fail per spec version.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MCP-006 100% of names pass SEP-986 validator; non-conforming names blocked at registration P0 Verify: T

MCP SEP-986 naming compliance — all server/tool identifiers MUST match SEP-986 regex

Every MCP server, tool, resource, and prompt name MUST conform to the SEP-986 naming pattern: `^[a-z][a-z0-9_-]{0,63}$` (lowercase ASCII, digits, underscore, hyphen, leading letter, max 64 chars).

Measurement
Counter `mcp_name_reject_total{reason=pattern|collision|length}`.
Modules
MCP
Priority
MUST
Owner
CTO
NFR-MEMORY-006 Signed Tree Head (STH) published every 24h OR 100MB of new rows, whichever occurs first P1 Verify: T

memory STH publication frequency — consolidate every 24h or 100MB whichever first

The memory consolidation process MUST publish a Signed Tree Head (STH) — a Merkle root over the consolidated window's rows, signed by the platform key — every 24 hours of wall-clock time OR every 100MB of new rows ingested since the last STH, whichever threshold is hit first.

Measurement
Counter `memory_sth_published_total{result}` per STH attempt.
Modules
memory
Priority
MUST
Owner
CSO
NFR-OBS-007 100% of fired alerts carry the four-field custody manifest; CI verifies on every release P0 Verify: T

Chain-of-custody manifest completeness — every alert carries trace_id + alertmanager_id + runbook_id

Every Alertmanager-routed alert MUST carry the four-field chain-of-custody manifest:

Measurement
Counter `obs_alert_custody_manifest_complete_total{result}` where result ∈ {`complete`, `incomplete`}. Incomplete should be zero.
Modules
OBS
Priority
MUST
Owner
CSO
NFR-OKR-007 100% of closed cycles carry a CEO-signed retro before close P0 Verify: T

OKR retro-approval gate — quarterly retro MUST be CEO-signed before closing

A cycle MUST NOT advance to `closed` without a CEO-signed retro.

Measurement
Counter `okr_cycle_close_no_retro_attempt_total` — must be 0.
Modules
OKR
Priority
MUST
Owner
CEO
NFR-RES-002 100% of allocation mutations produce an audit row with before/after delta P0 Verify: T

RES allocation-change history — every allocation mutation MUST emit an audit row

Every change to a member's allocation (create, update, deactivate) MUST emit a memory audit row carrying `{member_id, project_id, before_pct, after_pct, actor_id, reason?, changed_at}`.

Measurement
Counter `res_allocation_audit_row_total{operation=create|update|deactivate}`.
Modules
RES
Priority
MUST
Owner
COO
NFR-RES-003 100% of VN overtime hours carry recorded worker consent + supervisor signoff P0 Verify: T

RES OT consent capture — VN overtime MUST require + persist worker consent

VN-resident workers' overtime MUST NOT be allocated without explicit, recorded consent of the worker, per the VN labour code OT cap (`TASK-RES-005`).

Measurement
Counter `res_ot_consent_missing_total` — must be 0.
Modules
RES
Priority
MUST
Owner
CHRO
NFR-RES-004 100% of hiring memos carry both signatures before role goes to recruiting P1 Verify: T

RES hiring-memo signoff — CUO-generated memo MUST have hiring-manager + CHRO co-sign

The hiring-memo CUO workflow (`TASK-RES-004`) MUST produce a memo signed by both the hiring manager + CHRO before the role is published to recruiting channels.

Measurement
Counter `res_hiring_memo_published_total{has_both_signatures}`.
Modules
RES
Priority
MUST
Owner
CHRO
NFR-REW-002 100% of monthly runs within ±1 VND of a manual sample of 5 members per period P0 Verify: T

REW payroll-cycle accuracy — monthly run MUST close within +/- 1 VND vs hand-verified sample

Each monthly payroll run MUST be sample-verified: 5 random members' gross/SI/PIT/net amounts hand-computed by the CFO + an external accountant and compared against the system output.

Measurement
Per-cycle attestation memo (mandatory artifact).
Modules
REW
Priority
MUST
Owner
CFO
NFR-REW-004 100% of P3 distributions carry CFO + CHRO signatures; no auto-execute without both P0 Verify: T

REW P3 distribution audit — quarterly distribution MUST have CFO+CHRO co-sign before execution

Every P3 quarterly distribution MUST be approved by both CFO and CHRO via signed approval rows before execution; single signature is insufficient.

Measurement
Counter `rew_p3_single_signer_attempt_total` — must be 0.
Modules
REW
Priority
MUST
Owner
CFO
NFR-REW-008 100% of payslips use the correct VN tax tables; non-VN residents flagged as out-of-scope P1 Verify: T

REW locale handling — payslip currency + tax tables MUST match member residency

The REW compute path MUST apply VN PIT + SI tables only to members with `residency = VN`; non-VN residents are flagged out-of-scope and excluded from the standard compute.

Measurement
Counter `rew_locale_mismatch_total{member_residency, expected}` — must be 0.
Modules
REW
Priority
MUST
Owner
CFO
NFR-SKILL-004 100% of skill invocations produce a Layer-1 row within 1s; reconciliation drift < 0.001% P0 Verify: T

SKILL audit-chain coverage — every skill invocation MUST emit ≥ 1 memory row

Every skill invocation (success, denial, error) MUST result in at least one Layer-1 memory row carrying `{tenant_id, actor_id, skill_name, skill_version, capability_used, started_at, ended_at, outcome, output_digest?}`.

Measurement
Counter `skill_audit_emit_attempt_total{outcome}` and `skill_audit_emit_success_total`.
Modules
SKILL
Priority
MUST
Owner
CTO
NFR-SKILL-005 100% pass rate against GDT MST + NAPAS VietQR + GDT hoadondientu sandboxes weekly P0 Verify: T

SKILL VN-bundle compliance — MST/VietQR/HoaDon skills MUST pass external validator

The three Vietnamese-locale skills (`vn-mst-validate`, `vn-bank-transfer`, `vn-vat-invoice`) MUST pass a weekly end-to-end validation run against their respective external authorities: GDT MST lookup endpoint, NAPAS VietQR specification validator, and GDT hoadondientu sandbox.

Measurement
CI metric per skill: `skill_vn_validator_pass_count` and `skill_vn_validator_fail_count` per weekly run.
Modules
SKILL
Priority
MUST
Owner
CFO
NFR-TEN-002 100% of tenant writes land in pinned region; cross-region writes audited + blocked P0 Verify: T

TEN four-residency pinning — tenant data MUST stay in pinned region; 0 cross-region writes

Each tenant MUST be pinned to exactly one of the four declared residencies (VN, SG, EU, US) at provision time; the pin is immutable post-provision.

Measurement
Counter `ten_cross_region_write_total{tenant, source_region, target_region}` — must be 0.
Modules
TEN
Priority
MUST
Owner
CTO
NFR-TEN-003 100% of plan-quota violations either blocked OR queued with operator-visible state P0 Verify: T

TEN plan-tier enforcement — over-quota operations MUST be blocked or queued

Plan tiers (Free, Pro, Business, Enterprise) declare numeric quotas (users, projects, storage GB, API calls/month).

Measurement
Counter `ten_quota_block_total{tenant, plan, quota_kind}`.
Modules
TEN
Priority
MUST
Owner
CFO
NFR-TEN-004 100% of offboarded tenants follow the 90-day FSM with declared milestones P0 Verify: T

TEN 90-day offboarding FSM — termination MUST advance through declared states

Tenant offboarding MUST advance through the FSM: `requested → grace_30d → final_export → cold_storage_60d → permanent_delete`.

Measurement
Per-state counter `ten_offboarding_state_total{state}`.
Modules
TEN
Priority
MUST
Owner
CLO-Legal
NFR-TEN-008 100% of tenant lifecycle events (create/upgrade/offboard/delete) reach the durable audit store P0 Verify: T

TEN audit-event durability — tenant lifecycle events MUST never be lost

Tenant lifecycle events MUST land in the durable audit store with at-least-once + idempotent semantics.

Measurement
Counter `ten_lifecycle_event_emit_total{event}`.
Modules
TEN
Priority
MUST
Owner
CTO
OBS

Observability

Metrics, logging, tracing, alerting · 8 NFRs
NFR-AI-010 Drift alert fires within 24h of cosine deviation > 0.30 on a persona's eval set P1 Verify: T

AI persona-version drift detection — LangSmith cosine deviation > 0.30 triggers alert

Every active CUO persona MUST carry a versioned eval set (≥ 50 representative prompts per persona) committed under `modules/cuo/personas/<role>/evals/v<N>.jsonl`.

Measurement
LangSmith dataset `cyberos-persona-drift-<role>` updated continuously from the 1% sample.
Modules
AI
Priority
SHOULD
Owner
CTO
NFR-OBS-001 100% of services emit RED metrics; CI fails if a service lacks the cyberos-obs-sdk middleware P0 Verify: I

RED metric coverage — every service emits rate/error/duration via cyberos-obs-sdk

Every CyberOS backend service MUST emit the three RED metric families on every public route: `request_rate_total{route, method, status}`, `request_errors_total{route, method, error_class}`, `request_duration_seconds{route, method, status}` (histogram).

Measurement
Prometheus query `count by (service) (request_rate_total)` lists services emitting RED. Expected: equal to count of deployed services from the manifest.
Modules
OBS
Priority
MUST
Owner
CTO
NFR-OBS-002 100% of cross-service requests carry an unbroken traceparent chain ≥ 2 hops P0 Verify: T

Trace continuity — W3C traceparent propagates across ≥ 2 service hops; CI test enforces

Every CyberOS backend service MUST propagate the W3C `traceparent` and `tracestate` HTTP headers on outbound calls (server → service → service) and on NATS subjects (via the `traceparent` message header).

Measurement
Counter `obs_trace_propagation_gap_total{from_service, to_service}` emitted when an inbound request lacks `traceparent` but came from a known-internal source.
Modules
OBS
Priority
MUST
Owner
CTO
NFR-OBS-005 AI traces queryable for 90 days; filter by persona_version returns results in < 5s P1 Verify: I

LangSmith AI-trace retention — 90-day window, queryable by persona_version

Every AI Gateway call (1% sample per NFR-AI-010 + 100% of error/slow calls per NFR-OBS-003) MUST be exported to LangSmith with tags `{tenant_id, persona_version, route, model_alias, status}`.

Measurement
LangSmith project-config audit (`docs/compliance/langsmith-config.md`) lists current retention; reviewed quarterly.
Modules
OBS
Priority
SHOULD
Owner
CTO
NFR-PROJ-005 Calibration freshness ≤ 7 days; 100% of teams refreshed within their cadence P1 Verify: T

PROJ estimate-calibration freshness — calibration data MUST refresh weekly

Per-team estimate calibration (`TASK-PROJ-013`) MUST refresh weekly using closed issues from the prior cycle window.

Measurement
Gauge `proj_team_calibration_age_days{team}` — must be ≤ 7.
Modules
PROJ
Priority
SHOULD
Owner
CTO
NFR-PROJ-010 p95 < 4h from blocker condition to dashboard surfacing P1 Verify: T

PROJ blocker detector latency — blocker MUST surface within 4h of cause

The blocker detector (`TASK-PROJ-011`) MUST surface blockers (issues stalled > 3d, missing assignee, missing estimate, etc.) within 4h of the triggering condition becoming true.

Measurement
Histogram `proj_blocker_detection_latency_seconds` — condition true → surfaced.
Modules
PROJ
Priority
SHOULD
Owner
CTO
NFR-RES-001 p95 < 1h from allocation change to over/under flag visibility P1 Verify: T

RES matrix-trigger latency — over/under flags MUST surface within 1h of capacity change

The capacity-demand matrix (`TASK-RES-001`) MUST refresh on allocation, hiring, or scope mutations within 1h.

Measurement
Histogram `res_matrix_refresh_latency_seconds`.
Modules
RES
Priority
SHOULD
Owner
COO
NFR-RES-005 100% of Monday digests include data current through prior Sunday 23:59 local tenant time P1 Verify: T

RES weekly digest freshness — Monday digest MUST include data through Sunday EOD

The Monday capacity digest MUST include allocation data current through the prior Sunday 23:59 (tenant local time).

Measurement
Counter `res_digest_send_total{tenant, on_time}`.
Modules
RES
Priority
SHOULD
Owner
COO
PRIV

Privacy

PII handling, data residency, GDPR · 6 NFRs
NFR-AI-004 Recall ≥ 99% on the VN-PII test corpus; refreshed quarterly P0 Verify: T

VN-PII detector recall floor — recall ≥ 99% on quarterly refresh corpus

The Vietnamese PII detector plugin MUST achieve recall ≥ 99% on the curated VN-PII test corpus (`services/ai-gateway/tests/fixtures/vn_pii_corpus_v*.jsonl`) covering: CMND/CCCD national IDs, MST tax IDs, Vietnamese bank account numbers, Vietnamese phone numbers (mobile + landline), full names with diacritics, and Hanoi/HCMC street addresses.

Measurement
Test harness `services/ai-gateway/tests/vn_pii_recall_test.rs` loads the JSONL corpus, runs each example through the detector, and computes recall per category and overall.
Modules
AI
Priority
MUST
Owner
CSO
NFR-AI-005 ZDR attestation last-verified-at age ≤ 7 days per active provider P0 Verify: I

ZDR attestation freshness — re-verified weekly per provider

For every upstream AI provider used by the gateway, an active Zero Data Retention (ZDR) attestation MUST be on file under `docs/compliance/zdr-attestations/<provider>/YYYY-MM-DD.{pdf,sha256}`.

Measurement
Cron job `deploy/compliance/zdr-attestation-check.sh` runs nightly; for each provider it fetches the current ZDR URL, computes SHA-256, compares to the on-file attestation hash, and updates `zdr_attestation_last_verified_at` if the hash matches.
Modules
AI
Priority
MUST
Owner
CSO
NFR-EMAIL-007 100% of DSAR exports include all related messages; reconciliation = 0 missing rows P0 Verify: T

EMAIL DSAR export completeness — export MUST contain all subject's messages + metadata

A DSAR export for a data subject MUST include all email messages where the subject appears in `From`, `To`, `Cc`, `Bcc`, or as referenced in body text via PII matching.

Measurement
Counter `email_dsar_export_request_total{result=success|partial|failed}`.
Modules
EMAIL
Priority
MUST
Owner
CPO-Privacy
NFR-HR-003 100% of CCCD-photo reads carry a logged access reason; 0 bypassed reads P0 Verify: T

HR CCCD-photo access logging — every read MUST be logged with reason; sev-1 on bypass

Every read of a CCCD (Vietnamese national ID) photo MUST be logged with `{accessor_id, accessed_at, member_id, reason_code, justification}`.

Measurement
Counter `hr_cccd_access_total{reason_code}`.
Modules
HR
Priority
MUST
Owner
CPO-Privacy
NFR-MEMORY-007 100% of l2_memory rows have been through PII detection at recall ≥ 99% before commit P0 Verify: T

memory PII pre-ingest gate — Presidio + VN-PII recall ≥ 99% before row hits Layer 2

Every row entering `l2_memory` MUST first pass through the PII detection pipeline: Presidio (English) followed by the VN-PII plugin (Vietnamese, NFR-AI-004 recall floor).

Measurement
Counter `memory_pii_pre_ingest_total{pii_class, redacted}` per detection.
Modules
memory
Priority
MUST
Owner
CSO
NFR-REW-005 0 memory rows referencing REW comp tables; CI gate enforces per DEC-036 P0 Verify: T

REW memory exclusion — comp data MUST NOT land in memory Layer-1 or Layer-2

Per DEC-036, comp/payroll data (salary, bonus, 3P income, distributions) MUST NOT be written to memory Layer-1 or Layer-2 — REW maintains its own segregated audit log.

Measurement
CI metric `rew_memory_exclusion_gate_violations` — must be 0.
Modules
REW
Priority
MUST
Owner
CFO
SCAL

Scalability

Growth ceilings, shard strategy · 1 NFRs
NFR-CUO-203 compute_workflow_metrics + evaluate_workflow_signals: O(N) in row count; p95 < 2s wall-clock at N=10⁶ rows × W=50 workflows P0 Verify: T

workflow signal eval MUST be O(N) — p95 < 2s at 10⁶ audit rows

`cuo.core.workflow_evolution.compute_workflow_metrics(rows)` MUST be O(N) in the total audit-row count — single pass, dict insertion, no nested re-iteration of `rows`.

Measurement
Linearity: NEW benchmark `modules/cuo/tests/bench_workflow_evolution.py` runs `compute_workflow_metrics` against synthetic chains of N ∈ {10³, 10⁴, 10⁵, 10⁶} rows.
Modules
cuo
Priority
MUST
Owner
CTO

No NFRs match the current filters. to see the full catalog.

Generated by tools/docs-site/render-nfr-catalog.mjs from tools/docs-site/data/nfrs.json. Build is deterministic — same input → byte-identical output.