Skip to content

people-api: wire governed telemetry and prove buyer-path p95 <= 20 ms #257

Description

@seonghobae

Buyer-visible gap

PR #90 defines a privacy-safe People HTTP request-duration boundary but intentionally stops before application assembly, exporter/collector wiring, dashboard/SLO authority, and measured buyer-path latency. Orgmetra therefore cannot yet make the commercial performance claim required for an applicable People API path.

This issue owns the next operability slice after #90 integrates. It must not widen HR domain authority, copy a foreign observability product into Orgmetra, or introduce raw URL/PII labels.

Primary commercial latency contract

The first reproducible p95 gate is the governed worker-read path already owned by PeopleAsgiApp and classified by #90 telemetry:

GET /v1/tenants/{tenant_record_id}/people/{person_record_id}?effective_on=YYYY-MM-DD&purpose=people_read&fields=...

Use the normalized route template /v1/tenants/{tenant_record_id}/people/{person_record_id} in metrics; never the raw path or identifiers. Measure the complete request boundary that a buyer actually traverses for a successful authorized read: ASGI parsing, bearer authentication adapter, purpose-bound authorization, canonical People read port/database work, response serialization, telemetry middleware, exporter enqueue/record call, and connection handling. Do not benchmark a stubbed handler, omit authorization/database time, or subtract telemetry overhead after the fact.

Keep successful reads as the primary stable population and report error/status populations separately rather than mixing fast rejects into the success denominator. Record the requested-field distribution and use approved realistic field sets. The exact-head acceptance target for this primary success population is p95 <= 20 ms. Mutation and confirmed-hire routes retain the same observability/privacy contract but need separate workload distributions; they must not be mixed into the read-path denominator merely to change the percentile.

Required implementation boundary

  1. Wire PeopleHttpTelemetryMiddleware exactly once in the canonical People API application assembly, with middleware ordering explicit and tested so telemetry can never become authorization, mutation, or availability authority.
  2. Preserve the existing bounded dimensions: normalized HTTP method, application-owned route template or None, status, duration, and bounded error type. Never export raw URL paths, tenant/person/candidate identifiers, query values, payloads, prompts, evidence text, credentials, or purpose-bearing PII.
  3. Add a maintained exporter/collector adapter behind the existing sink port; prefer a standards-based OpenTelemetry/OTLP boundary unless a different adapter has an explicit ADR rationale. The domain/service layer must not depend on a vendor dashboard SDK.
  4. Add normal, exporter-down, collector-slow/backpressured, clock-failure, request-error, cancellation, client-disconnect and connection-cleanup E2E coverage. Telemetry failure must leave the governed HR response/exception semantics unchanged and must not leak request values in degradation logs.
  5. Add async load tooling (k6 or an equivalently reproducible harness) for the primary governed worker-read population above. Record request mix, concurrency, arrival model, connection reuse, database state, PostgreSQL/container configuration, hardware/runner class, sample count, test duration, cold/warm treatment, requested-field distribution, authorization behavior and raw summary artifacts. Do not satisfy the gate by shrinking the sample, excluding slow requests, replacing real dependencies with mocks, or using an unrealistic cache warm-up.
  6. Use real/right-cleared or otherwise approved realistic acceptance data/distributions for commercial performance evidence; synthetic-only fixtures remain unit-test evidence, not final buyer acceptance. Persist no benchmark PII in public artifacts.
  7. If p95 exceeds 20 ms, profile query/I/O/authorization/serialization/runtime/framework/telemetry costs before changing architecture. Keep the measurement population and denominator stable while optimizing; use Rust-first only for a demonstrated hot path where the existing stack is causal.
  8. Update OPERABILITY, TEST_STRATEGY, SECURITY/THREAT_MODEL as needed, TRACEABILITY, and docs/product-technical-gap-baseline.md through its canonical docs: maintain durable product-technical gap baseline #100 single-writer owner. Any exporter/dashboard/SLO or <=20 ms wording must be backed by executable current-head collection and benchmark evidence.

Acceptance

  • feat(operability): add privacy-safe People HTTP telemetry #90 or a verified successor is integrated into protected history; no mutable-parent source copy.
  • Application assembly wires telemetry exactly once and is exercised through current-head E2E, including failure isolation, cancellation/disconnect and cleanup.
  • Exact owned production statement/branch coverage remains 100% for the added code.
  • Privacy/cardinality tests prove no raw path, query values, HR identifiers, credentials, payloads, purposes or backend exception text enter metric labels/logs.
  • A reproducible end-to-end artifact proves successful authorized governed worker reads at p95 <= 20 ms for the stated workload and environment without denominator/sample/exclusion tricks.
  • Separate result tables preserve success/error/status and route-family populations; mutation/hire latency is not blended into the primary read gate.
  • Foundation/SAST/Security/CodeQL and qualifying independent review are current for the exact head.

Until these conditions are met, Orgmetra may describe #90 as a telemetry boundary but must not claim a live People API exporter, dashboard, SLO, or <=20 ms buyer-path performance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions