Skip to main content
Glama

PeopleLens AI

Governed People Analytics with an AI that knows what it must not answer.

An authorial project by LevelInteligencIA — People Analytics · Data Engineering · Data Quality · Data Governance · AI/MCP.

351 tests passing · 35 ADRs · 18 KPI contracts · 87 data quality checks · 6 MCP capabilities


1. What is PeopleLens AI?

PeopleLens AI turns heterogeneous, inconsistent, low-quality HR data into a governed analytical layer, and exposes it through a natural-language interface that knows what it can answer and, more importantly, what it cannot.

The difference from a typical "chat with your HR data" demo is the direction of authority. Here, the AI never defines a metric, never calculates one, and never decides whether an answer is trustworthy. It reads language and it communicates results. Everything in between is governed.

Related MCP server: agentic-ops-builder

2. The business problem

HR data rarely arrives ready. It comes from multiple systems, in different formats, with divergent names for the same concept, missing fields, duplicates, inconsistent IDs, invalid dates and broken referential integrity. On top of that, organizations change: the same area changes name, structure and owner across the years.

The practical result is familiar to anyone who has led People Analytics:

  • every analyst calculates turnover slightly differently;

  • nobody can say where a number came from;

  • leadership stops trusting the function.

Adding an LLM to that foundation does not solve the problem. It industrializes it, because now the wrong number arrives fluently and with confidence.

3. Core thesis

AI should not define or calculate People KPIs. People Analytics defines and governs them.

Everything in this repository follows from that sentence. The LLM is a semantic parser, not an analyst: it converts a question into a structured Intent and stops. It has no field in which to write SQL, a table name, a tool name or a number — not because it is forbidden, but because the contract has no such field.

4. Architecture

flowchart TD
    S[Source systems] --> R[Raw · immutable]
    R --> P[Profiling]
    P --> ST[Standardization]
    ST --> M[Mapping · DE/PARA]
    M --> DQ[Data Quality · 87 checks]
    DQ --> Q[Quarantine & Exceptions]
    Q --> AM[Analytical Model · L3]
    AM --> SL[Semantic / KPI Layer · L4]
    SL --> CK[Certified KPIs]
    CK --> MCP[MCP · 6 read-only capabilities]
    MCP --> AG[PeopleLens Agent]
    AG --> LLM[LLM Interpreter]

    style R fill:#1f2937,color:#fff
    style DQ fill:#1f2937,color:#fff
    style SL fill:#1f2937,color:#fff
    style MCP fill:#1f2937,color:#fff

Layered pipeline: L0 raw → L1 standardized → L2 conformed → L3 analytical → L4 semantic. Raw is immutable. Every transformed value keeps traceability to its original value, its source system and the rule applied.

5. Governance model

Layer

Responsibility

People Analytics

defines the KPI

Data

calculates it

Governance

certifies it

MCP

controls access to it

Agent

orchestrates the investigation

LLM

communicates the result

Six roles, one direction of authority. The LLM sits at the end of that chain, never at the start.

6. Trust model

Trust is a lattice, never an invented number:

trust_answer = min(trust_data, kpi_status_ceiling, actor_ceiling)

Status

Band

Meaning

CERTIFIED

score ≥ 0.95

approved by a named owner, on a recorded date

LIMITED

score ≥ 0.70

answerable, with declared caveats

BLOCKED

below

not answerable; the refusal explains why

CERTIFIED is not computable. It is recorded human approval, with an owner and a date. A pipeline cannot promote itself.

Current KPI catalog: 5 CERTIFIED, 8 DECLARED, 5 BLOCKED — 18 contracts.

7. AI boundaries

What the LLM cannot reach, and why it structurally cannot:

Cannot

Why it is impossible, not merely forbidden

read raw data

the agent's closed context carries catalog, vocabulary and policy — no data values

write SQL

the Intent has no such field, and the semantic query rejects unknown keys

calculate a KPI

no field of the Intent is numeric; answers cite values from an envelope

modify the Truth Layer

the MCP exposes six capabilities, none of them a write

pick the tool

selection comes from a declared matrix, not from the model

silently suppress an ambiguity

RESOLVE recomputes and overwrites whatever the model proposed

correct data silently

no transformation drops its provenance

The agent may investigate the data, but it cannot alter the truth of the data.

The LLM's output is treated as untrusted input (ADR-0035): it is validated locally even when the provider enforces a schema, and an unknown field rejects the entire Intent rather than being ignored.

8. Smart Refusal

A refusal is a result, not a protocol error — and never a closed door. Every refusal states what would resolve it.

The agent refuses when:

  • the period is not supported by the KPI (wrong grain, outside coverage);

  • a dimension or member is not in the governed vocabulary;

  • the evidence does not sustain the requested response level;

  • the KPI is blocked by governance.

Sixteen declared refusal classes, including KPI_BLOQUEADO, TERMO_DESCONHECIDO, GRAIN_INCOMPATIVEL, PERIODO_FORA_DE_COBERTURA, POPULACAO_ABAIXO_DO_MINIMO and NIVEL_SEM_EVIDENCIA.

The showcase case: "What was turnover for Tecnologia in Q2 2026?" returns zero data calls. turnover_rate is annual, so there is no quarterly version; and no department is called "Tecnologia". The answer offers the valid departments and the valid periods, and never silently resolves "Tecnologia" to "Engineering" — a wrongly mapped term is invisible, an unmapped one is visible.

9. MCP capabilities

Six, all read-only. No generic execute_sql, no query_database, no write.

Capability

Answers

get_kpi

the governed value for a slice

compare_kpi

the governed variation between two periods

breakdown_kpi

the value broken down by permitted dimensions

get_kpi_definition

the contract: what it measures, how it is governed

get_trust

the confidence, and what would raise it

get_lineage

the chain from the number back to the source

Every response is an envelope with one of four outcomes: ANSWER, REFUSAL, SUPPRESSED, ERROR.

10. Agent loop

UNDERSTAND → RESOLVE → PLAN → ACT → OBSERVE → INTERPRET → DECIDE → RESPOND

There is deliberately no VALIDATE step. Trust, response ceiling, minimum-n and governed states arrive already decided in the envelope; a step called "validate" would invite the agent to re-evaluate what has been decided, and re-evaluating is halfway to disagreeing.

PLAN is an artifact, not reasoning (ADR-0034). It exists before the first MCP call, and each step declares capability, reason and objective. That is what makes "why did the agent call this?" answerable six months later.

Every execution ends with one of ten declared stop_reason values.

11. LLM Interpreter

Model

gpt-5.6-luna (OpenAI)

Output

structured output, strict: true

Schema

intent/1.1, closed field set; an unknown field rejects the whole Intent

Boundary

the LLM ends before schema validation and RESOLVE

Fallback

deterministic RuleInterpreter, on structural failure or budget exhaustion — always declared, never silent

Empirical evaluation: 16 of 17 cases, 4 of 4 PT-BR ↔ EN-US semantic equivalence, no fallback, no retry. The single case that failed exposed a contract gap rather than a model error — the model declined to invent a comparison base that the governed vocabulary did not declare, which is the correct behaviour. See docs/llm_interpreter_p03_report.md.

12. Demonstrated scenarios

Validated end-to-end with the real LLM and the real MCP.

Question

Result

A

"What was turnover for Customer Service in 2025?"

factual answer, FACT, trust CERTIFIED, one MCP call

B

"Which area had the highest turnover in 2025?"

ranking via breakdown_kpi, with minimum-n suppression applied

C

"What was turnover for Tecnologia in Q2 2026?"

smart refusal, zero data calls, valid options offered

D

"How did turnover for Customer Service change between 2024 and 2025?"

governed comparison, 2025 against 2024 — explicitly declared, never derived

Scenario D is the reason intent/1.1 exists. The earlier contract could only express relative comparison bases, so a question naming two periods silently fell back to "previous period" and compared 2024 against 2023. The fix was not to make the plan guess better: it was to let the contract carry both periods (RF-02).

13. Privacy

Suppression by minimum n, declared per KPI contract (currently 5 or 20 depending on the metric), plus complementary suppression so that a suppressed cell cannot be recovered by subtracting the visible ones.

The agent cannot work around it: the harness blocks the sequence of narrowing queries that would reconstruct a suppressed slice, and it blocks it before the call, not after.

14. Data quality

87 declared checks, run by a purpose-built runner — checks live in configuration, never in code.

Dimension

Checks

Validity

21

Consistency

16

Completeness

15

Referential Integrity

12

Uniqueness

9

Reconciliation

8

Timeliness

6

Three attributes govern each check, answering three different questions: threshold (when it fails), severity (what happens to the failing row) and finding_class (what kind of problem it is).

Severity

Effect

BLOCKER

row goes to quarantine, never enters the analytical model

CRITICAL

row enters, and the check lowers the KPI trust score

WARNING

recorded and monitored, does not affect trust

INFO

observability only

Governance pendencies are named members, never nulls: UNMAPPED, DECISAO_PENDENTE, TRADUCAO_PENDENTE, SEM_CHAVE_DE_ORIGEM, FORA_DO_UNIVERSO, AINDA_NAO_OCORREU, ANTERIOR_A_SERIE, INDETERMINADA. A pending decision that hides as a null is a decision nobody will ever make.

15. Data lineage

KPI  →  business rule  →  analytical table  →  source system

get_lineage walks that chain, linked by trace_id across four logs: agent_run_log (why it was called) → mcp_call_log (who called) → semantic_query_log (what was asked) → l3_run_id (which load).

16. Synthetic data disclaimer

The dataset is entirely synthetic. It describes a fictional company, NOVAORA, with roughly ten years of HR history across five LATAM countries.

It does not represent any real company, country, population or demographic statistic. It was generated deliberately messy, to reproduce the data problems described in section 2 — and it was never optimized to produce favourable DEI results.

17. Bilingual product direction · Direcionamento bilíngue

The product is designed for PT-BR and EN-US. The same question in either language must produce the same semantic Intent: language changes neither the KPI, nor the period, nor the dimension, nor governance, nor the calculation.

Governed values are never translated. "Customer Service" stays "Customer Service" in both languages; display labels are an interface concern, not a licence for the model to invent or translate a dimension member.

Em português: o PeopleLens é desenhado para operar em PT-BR e EN-US. A equivalência semântica entre os dois idiomas foi validada empiricamente (4 de 4 pares). A camada de interface bilíngue está registrada como requisito futuro (RF-01) e ainda não foi implementada. A documentação de arquitetura do projeto está em português, em docs/.

18. Tech stack

Language

Python 3.11

Dataframes

Polars

Query engine

DuckDB

Storage

Parquet + zstd, SQLite for governance logs

Config

YAML, declarative — rules live in configuration, not in code

LLM

OpenAI SDK, structured output (lazy import; the suite runs without it)

Tests

pytest — 351 tests

19. Project status

Architecture and core agent flow implemented and validated.

Phase

Status

F0–F7 · pipeline, quality, analytical model, semantic layer

implemented

MCP v0.1 · six read-only capabilities

implemented

Agent Harness + Loop

implemented

LLM Interpreter v0.1

implemented, evaluated with the real model

RF-02 · explicit period comparison (intent/1.1)

implemented

User interface

not implemented

ADRs 0024–0035 are recorded as Proposta (proposed) and await formal acceptance as a block.

20. Roadmap

Short and honest. None of the below is implemented.

  • Interface / demo — there is no UI; the agent is exercised through the harness and scripts.

  • RAG for governed definitions — ADR-0016 already limits RAG to context and definitions, never to numbers. Not built.

  • Richer visual exploration — breakdowns and comparisons rendered visually.

  • Bilingual interface layer (RF-01) — registered, not implemented.

  • Wave 2 source systems — the DQ catalog covers wave 1 today.

  • Trust threshold calibration — thresholds are declared PROVISIONAL.


Documentation

Architecture documentation lives in docs/, written in Portuguese.

Document

Covers

docs/adr/

35 Architecture Decision Records, with the rejected alternatives

docs/F6_analytical_model.md

analytical model: grain, temporality, provenance

docs/F7_semantic_layer.md

semantic contract between People Analytics, data and AI

docs/MCP_SPEC_v0.1.md

the six capabilities and the envelope

docs/AGENT_HARNESS_SPEC_v0.1.md

harness, loop and policies

docs/LLM_INTERPRETER_SPEC_v0.1.md

the LLM contract and its boundaries

docs/llm_interpreter_p03_report.md

empirical evaluation of the model

docs/f5_data_quality.md

the 87 checks, severity and quarantine


PeopleLens AI · LevelInteligencIA · synthetic data, fictional company.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables querying HR data like recent hires, employee details, departments, and PTO balances through natural language in an MCP client.
    -
  • F
    license
    C
    quality
    B
    maintenance
    Enables natural language interaction with UKG Pro Workforce Management APIs. It detects intent, resolves missing inputs, hydrates related objects, and returns complete, validated operational answers across scheduling, timekeeping, attendance, and more.
    1
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural language queries to be converted into policy-verified SQL, vector search, and knowledge graph plans, with evidence-backed answers and an audit log.
    1
    Apache 2.0