Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
0acf072
test(workforce-validation): define governed registry read contract
seonghobae Sep 5, 2026
4966267
feat(workforce-validation): add governed study registry read boundary
seonghobae Sep 5, 2026
3de387e
feat(workforce-validation): export registry owner contract
seonghobae Sep 5, 2026
844c3bc
build(workforce-validation): define covered service package
seonghobae Sep 5, 2026
fbd4d9d
docs(workforce-validation): document registry owner slice
seonghobae Sep 5, 2026
fbbbbe9
build(workforce-validation): mark typed package
seonghobae Sep 5, 2026
3b2fa29
test(workforce-validation): remove unreachable timezone branch
seonghobae Sep 5, 2026
b59f9ca
test(workforce-validation): cover exact scalar and timezone branches
seonghobae Sep 5, 2026
b22383c
test(workforce-validation): pin policy scalar runtime integrity
seonghobae Sep 5, 2026
3fe8092
fix(workforce-validation): detach exact policy evidence before evalua…
seonghobae Sep 5, 2026
2b7cfe4
test(ci): require workforce validation coverage in foundation
seonghobae Sep 5, 2026
b7e23cb
ci(validation): run workforce validation service coverage
seonghobae Sep 5, 2026
0daaf12
test(validation): require structurally immutable study records
seonghobae Sep 5, 2026
b609b0a
fix(validation): make study records structurally immutable
seonghobae Sep 5, 2026
8c50d7d
fix(ci): seal workforce validation workflow manifest
seonghobae Sep 5, 2026
cf498b9
docs(validation): keep Foundation acceptance state current
seonghobae Sep 5, 2026
3853629
test(workforce-validation): reject retained principal rewrites
seonghobae Sep 5, 2026
e0ff347
fix(workforce-validation): make principal evidence immutable
seonghobae Sep 5, 2026
d42eb02
test(workforce-validation): require owner persistence boundary
seonghobae Sep 5, 2026
9dfeca7
feat(workforce-validation): establish owner schema and role
seonghobae Sep 5, 2026
d264b89
docs(workforce-validation): record owner persistence bootstrap
seonghobae Sep 5, 2026
5d4da09
test(workforce-validation): require PostgreSQL owner-schema acceptance
seonghobae Sep 5, 2026
d67abe7
test(workforce-validation): execute owner schema boundary
seonghobae Sep 5, 2026
6970b8c
ci(workforce-validation): execute owner schema contract
seonghobae Sep 5, 2026
a0ccaf0
fix(ci): reseal workforce validation owner-schema contract
seonghobae Sep 5, 2026
83e5c94
fix(ci): restore unrelated manifest seal
seonghobae Sep 5, 2026
7ca30f3
docs(workforce-validation): record PostgreSQL owner-schema gate
seonghobae Sep 5, 2026
f63c6e1
test(workforce-validation): reject NOLOGIN search-path default
seonghobae Sep 5, 2026
7dad37b
test(workforce-validation): exercise SET ROLE search-path semantics
seonghobae Sep 5, 2026
fd87b71
fix(workforce-validation): remove ineffective owner search-path default
seonghobae Sep 5, 2026
a04c8b4
docs(workforce-validation): correct owner-role search-path contract
seonghobae Sep 5, 2026
60f5ba9
test(workforce-validation): reject forged principal storage before auth
seonghobae Sep 5, 2026
4ef7ad1
fix(workforce-validation): revalidate principal storage before auth
seonghobae Sep 5, 2026
9794ff5
test(workforce-validation): reject noncallable read port before auth
seonghobae Sep 5, 2026
ccb5c0c
fix(workforce-validation): validate repository capability statically
seonghobae Sep 5, 2026
1a344f8
test(workforce-validation): lock authorized view evidence
seonghobae Sep 5, 2026
17092c9
fix(workforce-validation): make authorized views structurally immutable
seonghobae Sep 5, 2026
1b1d2e5
test(workforce-validation): require authorized view issuance
seonghobae Sep 5, 2026
b655063
fix(workforce-validation): make study views read-issued only
seonghobae Sep 5, 2026
412c62b
docs(workforce-validation): define authorized view issuance boundary
seonghobae Sep 5, 2026
dfd8038
test(workforce-validation): expose retained UUID alias mutation
seonghobae Sep 5, 2026
a78104c
test(workforce-validation): expose post-authorization UUID target switch
seonghobae Sep 5, 2026
b1c7085
fix(workforce-validation): detach UUID identity storage
seonghobae Sep 5, 2026
6505259
docs(workforce-validation): record UUID storage boundary
seonghobae Sep 5, 2026
23bdae6
test(workforce-validation): expose executable UUID payload
seonghobae Sep 5, 2026
7f7617b
fix(workforce-validation): validate UUID payload before comparison
seonghobae Sep 5, 2026
7c71f81
docs(workforce-validation): record UUID payload validation
seonghobae Sep 5, 2026
dbb0d25
test(workforce-validation): reject importable view issuer
seonghobae Sep 5, 2026
656a0c4
fix(workforce-validation): keep view issuance inside authorized read …
seonghobae Sep 5, 2026
9a83ff0
test(workforce-validation): bind repository capability use
seonghobae Sep 5, 2026
0ac2255
fix(workforce-validation): bind validated repository capability
seonghobae Sep 5, 2026
d219631
test(workforce-validation): cover policy equality tripwire
seonghobae Sep 5, 2026
47c3b19
test(workforce-validation): keep one registry import style
seonghobae Sep 5, 2026
db7ce6b
test(workforce-validation): use protocol-standard attribute trap
seonghobae Sep 5, 2026
14c10e8
test(workforce-validation): reject inherited Protocol repository stub
seonghobae Sep 5, 2026
72ec229
fix(workforce-validation): reject inherited Protocol repository stub
seonghobae Sep 5, 2026
195ffef
fix(foundation): admit workforce validation postgres contract
seonghobae Sep 5, 2026
c91df23
fix(foundation): register workforce validation postgres provenance
seonghobae Sep 5, 2026
e87d28a
fix(foundation): reseal workforce validation postgres provenance
seonghobae Sep 5, 2026
dd95dd7
test(workforce-validation): cover policy field runtime guard
seonghobae Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/foundation-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
PYTHONPATH=packages/selection-review/src COVERAGE_FILE=/tmp/orgmetra-selection-review.coverage python -m pytest -c packages/selection-review/pyproject.toml packages/selection-review/tests
PYTHONPATH=services/job-analysis-api/src:packages/hris-kernel/src:packages/keyverse-adapter/src COVERAGE_FILE=/tmp/orgmetra-job-analysis-api.coverage python -m pytest -c services/job-analysis-api/pyproject.toml services/job-analysis-api/tests
PYTHONPATH=services/people-api/src:packages/hris-kernel/src:packages/keyverse-adapter/src COVERAGE_FILE=/tmp/orgmetra-people-api.coverage python -m pytest -c services/people-api/pyproject.toml services/people-api/tests
PYTHONPATH=services/workforce-validation-api/src:packages/keyverse-adapter/src COVERAGE_FILE=/tmp/orgmetra-workforce-validation-api.coverage python -m pytest -c services/workforce-validation-api/pyproject.toml services/workforce-validation-api/tests
- name: Run PostgreSQL contracts in isolated containers
env:
PGPASSWORD: orgmetra
Expand All @@ -83,6 +84,7 @@ jobs:
test_audit_outbox_hardening_postgres.sh
test_candidate_worker_conversion_postgres.sh
test_validity_study_case_postgres.sh
test_workforce_validation_owner_schema_postgres.sh
test_criterion_observation_scope_postgres.sh
test_people_mutation_idempotency_postgres.sh
test_job_analysis_snapshot_postgres.sh
Expand Down
24 changes: 15 additions & 9 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"files": [
{
"path": ".github/workflows/foundation-ci.yml",
"sha256": "b6a4365936b66803a8112f034c77d53d33301a7a798ed4f68746a4f2d8b081d7",
"bytes": 6651,
"lines": 125
"sha256": "31c6a46cb81513cdaa2a08eed5cb00a57d8b36f15e3c772d230452cdc3329aed",
"bytes": 6974,
"lines": 127
},
{
"path": ".gitignore",
Expand Down Expand Up @@ -359,9 +359,9 @@
},
{
"path": "scripts/foundation-contract-core.mjs",
"sha256": "9b03efbbdffa60a05f5924e8a61b1cbc3cd75c502df428a5920085e8d0bf3603",
"bytes": 28121,
"lines": 688
"sha256": "5dfc54d40820dfc45962dcc91367c57baf6b011e68efc5f6e8d59e7e82145b2a",
"bytes": 28182,
"lines": 689
},
{
"path": "scripts/foundation-contract.mjs",
Expand Down Expand Up @@ -465,11 +465,17 @@
"bytes": 14708,
"lines": 301
},
{
"path": "tests/test_workforce_validation_owner_schema_postgres.sh",
"sha256": "29f0cd8a7d9040ff86095b68fa2f3d0ed54ea3777e5a816d4a79eb6ceafb9339",
"bytes": 2949,
"lines": 76
},
{
"path": "tests/validate_repository.py",
"sha256": "091836b2f68600a30b08f7da2cea8b3bef10201a123da720a7369bf10985eec2",
"bytes": 27237,
"lines": 637
"sha256": "244627252e7392e4dbed98392c132cb86dc8e5ead839a1129298e8d022fcf8eb",
"bytes": 27300,
"lines": 638
}
]
}
3 changes: 2 additions & 1 deletion scripts/foundation-contract-core.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const REQUIRED_FILES = Object.freeze([
'tests/test_audit_outbox_hardening_postgres.sh',
'tests/test_candidate_worker_conversion_postgres.sh',
'tests/test_validity_study_case_postgres.sh',
'tests/test_workforce_validation_owner_schema_postgres.sh',
'tests/test_criterion_observation_scope_postgres.sh',
'tests/test_people_mutation_idempotency_postgres.sh',
'tests/test_job_analysis_snapshot_postgres.sh',
Expand Down Expand Up @@ -685,4 +686,4 @@ export function runCli(rootPath, outputStream = process.stdout, errorStream = pr
}
errorStream.write(`${JSON.stringify({ status: 'failed', error_count: errors.length, errors }, null, 2)}\n`);
return 1;
}
}
44 changes: 44 additions & 0 deletions services/workforce-validation-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Orgmetra Workforce Validation API

This package is the application boundary for the `workforce_validation` bounded context. The current slice exposes one purpose-bound read use case for the existing validity-study registry header and establishes the context-local PostgreSQL ownership bootstrap.

It does **not** query People, Talent Acquisition, Performance Management, Job Architecture, Psychometrics Commons, fast-mlsirm, or TEPP tables. Those contexts remain separate owners. Exact foreign identifiers and immutable specialist result references cross the boundary only through published contracts.

## Current slice

`read_validity_study(...)`:

- accepts structurally immutable authenticated Keyverse identity attributes, not credentials;
- reconstructs and revalidates principal storage before building the access request, so exact tuple type alone is not treated as identity authority;
- requires both exact `UUID` outer type and exact built-in integer UUID payload before any sentinel/range comparison, so a forged exact UUID with executable internal storage is rejected without invoking caller-defined equality behavior;
- stores UUID identity evidence behind the tuple-backed principal/record/view as exact integer payloads and reconstructs fresh UUID objects at public boundaries, so a retained UUID reference cannot rewrite accepted tenant/study/criterion identity through `object.__setattr__`;
- preserves tenant/study authorization targets as immutable integer snapshots across the executable repository call, so a repository cannot make a foreign record self-consistent by mutating the UUID objects it receives;
- inertly verifies that the owner repository exposes a statically callable `read_validity_study` capability before authorization, without executing caller-controlled descriptors;
- evaluates tenant, purpose, operation, scope, resource, and requested fields before persistence;
- calls only a `ValidityStudyReadPort` owned by this context;
- reconstructs persisted registry scalars into structurally immutable owner evidence before target validation and output;
- returns only the fields authorized for the exact study record; UUID-valued projected fields are reconstituted fresh rather than exposing mutable internal UUID aliases;
- issues `ValidityStudyView` only from the authorized read path. Its public constructor fails closed, and the returned tuple-backed projection cannot be rewritten through ordinary assignment or `object.__setattr__`.

`ValidityStudyView` is a data projection, not a durable authorization credential or cryptographic capability. Downstream consequential actions must perform their own purpose-bound authorization and authoritative re-resolution rather than treating the Python runtime type as reusable authority. Low-level interpreter construction is outside the supported public API and is not accepted as proof that authorization occurred.

`services/workforce-validation-api/database/migrations/0001_owner_schema.sql` starts this bounded context's own migration history. It creates the `workforce_validation` schema and deny-default `workforce_validation_role`, revokes public schema access, and intentionally creates or moves no application table yet. The role is a **NOLOGIN migration/schema owner only**; runtime principals must not be granted that owner role. PostgreSQL applies role-level configuration defaults at login and does not re-apply them on `SET ROLE`, so an `ALTER ROLE ... SET search_path` entry on this NOLOGIN role is not treated as a runtime isolation control. The later durable adapter must use a distinct least-privilege runtime role, schema-qualified `workforce_validation` relations, and explicit function-level `search_path` where `SECURITY DEFINER` code is introduced.

Protected foundation migrations still create validity-study tables in the legacy foundation schema, so the next forward-only persistence increment must adopt those records without normalizing `public.validity_study` as a long-lived service contract or breaking existing linkage evidence.

Issue #234 owns the remaining order: durable owner-schema adoption and PostgreSQL adapter, idempotent registration, explicit predictor/sample/decision-policy/analysis-protocol versions, scientific adapters, OpenAPI/gateway exposure, and realistic p95 measurement. Issues #236–#244 retain the current bootstrap trust-boundary findings through exact-head acceptance and protected integration: persisted-record immutability, principal immutability and constructor revalidation, owner-role/runtime-role separation, inert repository-capability validation, immutable minimized output, non-public issuance of that output, detached UUID storage/target snapshots, and exact validation of UUID internal payloads before comparison.

## Test

The Draft branch is admitted to the canonical Foundation quality workflow with the same hash-locked test toolchain and direct source-tree dependency policy used by the existing owner services:

```bash
PYTHONPATH=services/workforce-validation-api/src:packages/keyverse-adapter/src \
COVERAGE_FILE=/tmp/orgmetra-workforce-validation-api.coverage \
python -m pytest -c services/workforce-validation-api/pyproject.toml \
services/workforce-validation-api/tests
```

The same Foundation job also runs `tests/test_workforce_validation_owner_schema_postgres.sh` in its own pinned PostgreSQL 16.14 container. That contract executes the service-local owner migration and checks the exact deny-default role flags, schema owner, absence of ineffective login-only `rolconfig`, actual `SET ROLE` search-path behavior, absence of inherited PUBLIC `USAGE`/`CREATE`, and absence of application relations in the bootstrap schema. The test intentionally demonstrates that `SET ROLE` retains the caller's existing `search_path`; runtime isolation therefore cannot be inferred from owner-role metadata.

Those source contracts are not terminal acceptance by themselves. The slice remains Draft until the exact current head actually executes with 100% owned statement/branch coverage, the PostgreSQL owner-schema contract is GREEN, applicable security workflows are terminal, and the normal review/governance requirements are satisfied. Only then may the next forward-only owner-table adoption and durable adapter be treated as eligible for integration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-- Establish the logical PostgreSQL ownership boundary for workforce_validation.
-- This migration intentionally creates no application table. Legacy foundation
-- validity-study tables stay untouched until an explicit forward-only adoption
-- migration can preserve existing foreign-key and acceptance contracts.

BEGIN;

CREATE ROLE workforce_validation_role NOLOGIN
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
NOREPLICATION
NOBYPASSRLS;

CREATE SCHEMA workforce_validation AUTHORIZATION workforce_validation_role;
REVOKE ALL ON SCHEMA workforce_validation FROM PUBLIC;

-- workforce_validation_role is a migration/schema-owner identity only. Runtime
-- principals must not be granted this owner role. PostgreSQL role-level GUC
-- defaults apply at login and are not re-applied by SET ROLE; because this role
-- is NOLOGIN, an ALTER ROLE ... SET search_path entry would not provide runtime
-- isolation. Future runtime adapters must use a distinct least-privilege role,
-- schema-qualified owner relations, and explicit function-level search_path for
-- any SECURITY DEFINER code.

COMMIT;
41 changes: 41 additions & 0 deletions services/workforce-validation-api/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[build-system]
requires = ["setuptools==82.0.1"]
build-backend = "setuptools.build_meta"

[project]
name = "orgmetra-workforce-validation-api"
version = "0.1.0"
description = "Purpose-bound owner boundary for Orgmetra workforce-validation studies."
readme = "README.md"
requires-python = ">=3.11"
license = { text = "Apache-2.0" }
authors = [{ name = "ContextualWisdomLab" }]
dependencies = [
"orgmetra-keyverse-adapter==0.1.0",
]

[tool.setuptools]
package-dir = {"" = "src"}

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
orgmetra_workforce_validation_api = ["py.typed"]

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = [
"--cov=orgmetra_workforce_validation_api",
"--cov-branch",
"--cov-report=term-missing",
"--cov-fail-under=100",
]

[tool.coverage.run]
branch = true
source = ["orgmetra_workforce_validation_api"]

[tool.coverage.report]
fail_under = 100
show_missing = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Canonical workforce-validation application contracts for Orgmetra."""

from orgmetra_workforce_validation_api.registry import (
ValidationPrincipal,
ValidityStudyIntegrityError,
ValidityStudyNotFound,
ValidityStudyReadPort,
ValidityStudyRecord,
ValidityStudyView,
read_validity_study,
)

__all__ = [
"ValidationPrincipal",
"ValidityStudyIntegrityError",
"ValidityStudyNotFound",
"ValidityStudyReadPort",
"ValidityStudyRecord",
"ValidityStudyView",
"read_validity_study",
]
Loading
Loading