Skip to content

Shared referential quality policy

lexi-referential-v1 owns the rules used by HRX's Jobs, Skills and Job–Skills tabs and the generated-skills workflow. It requires no Supabase dependency and persists no referential data. HRX owns authentication, organization authorization, pagination, storage, dismissed recommendations and human approvals.

Analyze an authorized snapshot

POST /lexi/api/v1/referentials/analyze requires the existing Lexi API key. Provide complete jobs, skills, requirements, referentials, validated_job_ids, optional dgi_ratio/dgi_available and duplicate exclusions. Use referential_id=null for the organization-wide view. Duplicate identifiers, missing association endpoints and unknown versions are rejected. The shared input-safety budgets apply; oversized requests fail rather than being sampled.

checks="deterministic" evaluates rules and exact/fuzzy duplicates without model calls. checks="semantic" separately enriches global duplicate groups through candidate embeddings followed by OpenAI Decisions. Responses expose policy_version, status, unavailable_checks, issues, policy, duplicate_metrics and the three tab projections. Stable rule identifiers are independent of translations. An empty, complete referential is distinct from an unavailable analysis. Malformed internal tab projections fail explicitly rather than silently discarding findings. Semantic processing embeds each distinct label once, using tasks of up to 512 labels (LEXI_SEMANTIC_EMBEDDING_CHUNK_SIZE, at most 2,048 provider inputs). Jobs and skills share bounded embedding concurrency (LEXI_SEMANTIC_EMBEDDING_CONCURRENCY, default 16). There is no 10,000-label cap. Candidate retrieval searches all labels within the same object kind and referential, selecting the union of five nearest neighbors per label. It no longer uses alphabetically adjacent overlapping windows or a cosine acceptance threshold. Matrix work runs off the event loop in bounded row blocks.

Native OpenAI Decisions, resolved through mini, classifies candidate pairs as duplicate, distinct, or insufficient_context using their labels, type and available descriptions. The profile must support Decisions; no provider or model substitution is performed. Calls contain at most 64 pair questions and only the evidence needed for that batch. Every internal pair of a semantic group must be confirmed; overlapping groups are never unioned transitively. Exact-label buckets remain deterministic and are expanded after confirmation. Selected IDs still prefer the highest association count, with ID tie-breaking.

semanticCoverage=scoped_top_k_with_decisions and semanticNeighbors=5 describe the coverage. Complete means every selected candidate was evaluated, not that all possible catalogue pairs were judged. Embedding or decision failures mark the affected kind unavailable and the response partial; deterministic exact findings remain available. Cancellation propagates. Within-job fuzzy checks retain their existing CPU guard and explicit unavailable status.

Rules and tests

Definitions and prompt instructions live in referential_policy.py; referential_analysis.py and referential_duplicates.py evaluate them. Tests below are in tests/lexi/services.

Rules Evaluation / generation Regression evidence
Missing family; family size 3–30 Jobs; family suggestions include populations test_referential_analysis: family bounds 2/3/30/31
Missing or fewer than 3 missions, complete target 5 Jobs; mission suggestions count raw paragraphs/lists centrally Analysis mission parsing and complete/extend tests; existing test_job_missions
Duplicate job titles, exact and semantic Scope-aware duplicate groups, human merge only Analysis duplicate tests
Skill names over 5 words, missing descriptions Skills; catalogue, expansion, assignment, descriptions, repair Analysis 5/6-word and missing-description tests
Exact/semantic skill duplicates; within-job fuzzy duplicates at 0.80 Canonical selection and targeted repair Analysis exclusions and duplicate tests; generation tests
DGI objective 10% Existing available DGI metric; relevant capabilities only Analysis DGI tests
Fewer than 10 skills, target deviation over ±30% Job–Skills; final quantity selection Analysis tolerance tests; parity vectors
Unique-skill/job ratio 2–4 Global granularity; indicative range, repair consolidates or specializes with the shared catalogue Analysis granularity curve; parity vectors; generation granularity tests
Over 50% linked to fewer than 3 or at least 15 jobs Transversality; genuine reuse only Analysis 2/3/14/15 tests; parity vectors
Uniform levels including zero/one skill Job–Skills; independent level judgment Analysis and parity tests
Orphan skills Job–Skills; new skills must be associated; a replacement removes the skills it orphaned Analysis large-scope test; generation projection and replacement tests
Client quantity, groups, hard/soft, levels, locale and wording Existing parameters plus shared instructions at relevant stages Generation quota/scope/level tests; existing Lexi suites

The 40 frozen HRX vectors in test_referential_parity.py cover historical scores, action lists, mixed targets, validation exceptions and ordering. Do not collapse the G/J/Q hook score into the separately displayed 50/25/25 score. Jobs retain 60/40 coverage/size weighting; Skills retain 50/50 DGI/LONG weighting when a DGI driver is available. Without one, LONG alone scores a non-empty catalogue and decides whether its scores are satisfactory; an empty catalogue keeps its neutral 50. LONG is maximal up to 5% long labels and zero at 20%. Score rounding follows JavaScript. Policy metadata includes priorities and the two historical color scales.

Versioned generation

Add policy_version, quality_source and skill_group_types to generated-skills requests. Inline quality_context remains supported within the existing request budget. For partial regeneration the source includes selected jobs, all reusable skills, total job population and usage counters for unselected jobs; it excludes unselected job descriptions and missions. resultsNumber is the real final target. The selected job IDs must be unique and belong to the snapshot. Imported catalogues keep their separate provided-skills contract.

Catalogue creation/expansion/assignment, description generation and proficiency inference receive the shared policy. AIHub selects canonical final skills and hard/soft quotas, evaluates, optionally performs one targeted repair and re-evaluates the selection. An invalid repair is discarded; technical failures use the workflow's existing error callback.

The repair prompt requires existing proficiency levels to be preserved unless a level is missing, outside the allowed scale, or contradicted by explicit evidence in the supplied job context. Uniform levels alone do not justify a change, even when a uniform-level warning remains. Duplicate cleanup, skill counts, group quotas and other unrelated findings do not justify changing a valid level.

When the unique-skill/job ratio is outside 2–4, every repair batch also receives the ratio and the 200 most reused skills of the projected referential, within 40,000 characters. A too-high ratio may reuse a shared skill only when it covers the same or a broader capability; a too-low ratio may specialize an overly generic skill. Batches run sequentially on the latest accepted selection. A batch is kept only if it increases neither the number of findings nor the distance of the ratio from the desired range. The completion log reports the ratio before and after repair, without business content.

A replacement (generation_mode replace) is evaluated as HRX persists it: referential skills detached from every job by the replacement are removed from the projection, while skills still used by unselected jobs remain. HRX also keeps an orphan referenced by a validation proposal; the persisted analysis is authoritative in that case. Statistical targets never justify invented missions, arbitrary levels or irrelevant associations.

Partial regeneration preserves unselected associations and stored shared skill metadata. Job identifiers disambiguate homonymous job titles. The success callback includes policy_version and quality_report with remaining issues, semantic findings and completeness. HRX must persist this selection without a second quota calculation. Versionless requests and already-running callbacks retain historical processing.

Family and mission suggestions remain proposals. Skills generation never rewrites imported job families or missions, merges jobs, or restructures families. Those findings can legitimately remain after skills generation.

Delivery and verification

Deploy AIHub before HRX backend, then HRX frontend. No database migration is required. Use synthetic data for validation. New analysis/repair logs contain technical identifiers, exception types and counts, never referential content. HRX disables generation debug. API schema examples are exposed in the generated Lexi HTTP reference.

Bounded transfers without a business volume quota

The generated-skills and referential-analysis workflows do not impose a total job, skill or association count limit. They retain normal per-request safety budgets (50,000 JSON nodes, 2,000,000 total text characters, 200,000 per field, depth 20). Private HRX transfers split input and output into structural fragments of at most 256,000 bytes and fewer than 30,000 nodes per page. Oversized individual records fail explicitly; content is never silently truncated.

A QualityReference contains organization, referential and execution UUIDs, never a caller-selected URL. AIHub uses LEXI_HRX_FUNCTIONS_ORIGIN and LEXI_SKILLS_GENERATION_COMPLETE_API_KEY to call HRX's lexi-quality-transfer. HRX recognizes the existing callback secret and stores pages in the existing private lexi-skill-catalogs bucket. Users can read status and results only after JWT verification and active organization-membership checks. Input pages are removed at completion/failure; result pages remain private in HRX.

Analysis acknowledges with status=pending and its source reference. A background worker loads every page, validates the graph, evaluates it, uploads every result page, then publishes completion. Deterministic and semantic analyses use separate pools (two each per process by default) so a fast deterministic check never waits behind semantic work. One transfer shares a keep-alive connection pool and exchanges up to eight pages at once (LEXI_QUALITY_TRANSFER_CONCURRENCY); input pages are applied in order and completion is published only after every result page is stored. Generation similarly hydrates the source after acknowledgment. Failures use an explicit failed state or the existing generation failure callback. This uses the existing in-process background lifecycle, not a durable distributed queue; process restarts require restarting interrupted work. An owned heartbeat every 30 seconds lets HRX report a missing worker after two minutes without imposing a total analysis-duration deadline. The signal remains active until result uploads finish; its separate storage object cannot overwrite completion. HRX loading and AIHub assembly still consume memory, so absence of an entity quota does not imply infinite capacity.

Generation prompts receive at most 200 relevant reusable skill summaries within 40,000 characters. The full catalogue remains available to deterministic checks. Role batches contain at most 40 jobs; the single repair pass uses at most 10 jobs per call. Text-heavy inputs reduce these sizes further. Each job is considered at most once in the repair pass; there is no recursive repair loop. Provider context limits and individual-record safety limits still apply.

The stored referential's quantity, level scale and hard/soft settings govern an existing referential. HRX pre-fills the wizard and preserves these settings. Jobs without usable generation preserve their previous associations; all-empty output fails. A null definition remains an explicit missing-description finding. Missing levels receive one repair attempt and are rejected if still invalid. A DGI driver computed before catalogue expansion is marked unavailable in the quality report until refreshed; it cannot certify new skills.

Synthetic tests cover 48,000 associations, 100,000 small JSON values, more than 10,000 semantic labels, private source scope checks, failed transfers and a 25-job repair split into three batches. The HRX coverage matrix is maintained in docs/lexi/NB-9113-regles-communes.md in the HRX repository.