Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .github/requirements/foundation-compatibility-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Reviewed Foundation compatibility toolchain for CPython 3.12-3.13 on GitHub-hosted Ubuntu x86_64.
# Coverage wheel hashes are the reviewed CPython 3.12 and 3.13 manylinux x86_64 artifacts.
coverage==7.14.2 --hash=sha256:8b4910cce599cd2438f8da65f5ef199a70a1cdb6ab314926df78271ca5954240 --hash=sha256:1d9a1b5813d00ea6151f6ccf64d1fa16892771dfdda12ba87162d15ec4ea3e1e
iniconfig==2.3.0 --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12
packaging==26.2 --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e
pluggy==1.6.0 --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746
Pygments==2.20.0 --hash=sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176
pytest==9.1.1 --hash=sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c
pytest-cov==7.1.0 --hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678
146 changes: 136 additions & 10 deletions .github/workflows/foundation-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
env:
ORGMETRA_EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$ORGMETRA_EXPECTED_HEAD_SHA"
- name: Set up Python
- name: Set up primary Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
Expand All @@ -56,16 +56,19 @@ jobs:
run: |
python -m pip install --require-hashes --no-deps --only-binary=:all: -r .github/requirements/foundation-test.txt
python -m pip check
- name: Run owned unit and service contracts once
- name: Run owned package contracts once
run: |
set -euo pipefail
for pyproject in packages/*/pyproject.toml; do
package_dir="${pyproject%/pyproject.toml}"
[[ -d "$package_dir/src" && -d "$package_dir/tests" ]] || continue
package_name="$(basename "$package_dir")"
PYTHONPATH="$package_dir/src" \
COVERAGE_FILE="/tmp/orgmetra-${package_name}.coverage" \
python -m pytest -c "$pyproject" "$package_dir/tests"
done
- name: Run owned service contracts once
run: |
PYTHONPATH=packages/candidate-evidence/src COVERAGE_FILE=/tmp/orgmetra-candidate-evidence.coverage python -m pytest -c packages/candidate-evidence/pyproject.toml packages/candidate-evidence/tests
PYTHONPATH=packages/hris-kernel/src COVERAGE_FILE=/tmp/orgmetra-hris-kernel.coverage python -m pytest -c packages/hris-kernel/pyproject.toml packages/hris-kernel/tests
PYTHONPATH=packages/keyverse-adapter/src COVERAGE_FILE=/tmp/orgmetra-keyverse-adapter.coverage python -m pytest -c packages/keyverse-adapter/pyproject.toml packages/keyverse-adapter/tests
PYTHONPATH=packages/migration-adapter/src COVERAGE_FILE=/tmp/orgmetra-migration-adapter.coverage python -m pytest -c packages/migration-adapter/pyproject.toml packages/migration-adapter/tests
PYTHONPATH=packages/naruon-adapter/src COVERAGE_FILE=/tmp/orgmetra-naruon-adapter.coverage python -m pytest -c packages/naruon-adapter/pyproject.toml packages/naruon-adapter/tests
PYTHONPATH=packages/offer-approval/src COVERAGE_FILE=/tmp/orgmetra-offer-approval.coverage python -m pytest -c packages/offer-approval/pyproject.toml packages/offer-approval/tests
PYTHONPATH=packages/requisition-review/src COVERAGE_FILE=/tmp/orgmetra-requisition-review.coverage python -m pytest -c packages/requisition-review/pyproject.toml packages/requisition-review/tests
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
- name: Run PostgreSQL contracts in isolated containers
Expand Down Expand Up @@ -116,6 +119,129 @@ jobs:
docker rm --force "$container_name" >/dev/null
trap - EXIT
done
- name: Prove compatibility toolchain provenance
run: |
expected_sha256=cebb36181e8ac995a36d73a02a45094a204ff5adb3cbcdc0c9eccff309ac6aab
actual_sha256="$(sha256sum .github/requirements/foundation-compatibility-test.txt | awk '{print $1}')"
test "$actual_sha256" = "$expected_sha256"
- name: Set up Python 3.12 compatibility runtime
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
check-latest: false
- name: Install reviewed Python 3.12 compatibility toolchain
run: |
python -m pip install --require-hashes --no-deps --only-binary=:all: -r .github/requirements/foundation-compatibility-test.txt
python -m pip check
- name: Execute every package that declares Python 3.12 supported
env:
ORGMETRA_PYTHON_MINOR: "3.12"
run: |
set -euo pipefail
executed=0
for pyproject in packages/*/pyproject.toml; do
package_dir="${pyproject%/pyproject.toml}"
[[ -d "$package_dir/src" && -d "$package_dir/tests" ]] || continue
compatibility_decision="$(
python - "$pyproject" <<'PY'
import sys
import tomllib
from pathlib import Path
from packaging.specifiers import InvalidSpecifier, SpecifierSet
from packaging.version import Version

pyproject = Path(sys.argv[1])
project = tomllib.loads(pyproject.read_text(encoding="utf-8")).get("project", {})
requires_python = project.get("requires-python")
if not isinstance(requires_python, str) or not requires_python.strip():
raise SystemExit(f"{pyproject}: project.requires-python is required")
runtime = Version(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
try:
supported = runtime in SpecifierSet(requires_python)
except InvalidSpecifier as exc:
raise SystemExit(
f"{pyproject}: invalid project.requires-python: {requires_python!r}"
) from exc
print("supported" if supported else "unsupported")
PY
)"
if [[ "$compatibility_decision" == "unsupported" ]]; then
continue
fi
if [[ "$compatibility_decision" != "supported" ]]; then
printf 'Unexpected compatibility decision for %s: %s\n' "$pyproject" "$compatibility_decision" >&2
exit 1
fi
package_name="$(basename "$package_dir")"
python -m compileall -q "$package_dir/src" "$package_dir/tests"
PYTHONPATH="$package_dir/src" \
COVERAGE_FILE="/tmp/orgmetra-${package_name}-${ORGMETRA_PYTHON_MINOR}.coverage" \
python -m pytest -c "$pyproject" "$package_dir/tests"
executed=$((executed + 1))
done
if [[ "$executed" -eq 0 ]]; then
printf 'No owned package declared Python %s support; compatibility evidence would be vacuous.\n' "$ORGMETRA_PYTHON_MINOR" >&2
exit 1
fi
- name: Set up Python 3.13 compatibility runtime
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"
check-latest: false
- name: Install reviewed Python 3.13 compatibility toolchain
run: |
python -m pip install --require-hashes --no-deps --only-binary=:all: -r .github/requirements/foundation-compatibility-test.txt
python -m pip check
- name: Execute every package that declares Python 3.13 supported
env:
ORGMETRA_PYTHON_MINOR: "3.13"
run: |
set -euo pipefail
executed=0
for pyproject in packages/*/pyproject.toml; do
package_dir="${pyproject%/pyproject.toml}"
[[ -d "$package_dir/src" && -d "$package_dir/tests" ]] || continue
compatibility_decision="$(
python - "$pyproject" <<'PY'
import sys
import tomllib
from pathlib import Path
from packaging.specifiers import InvalidSpecifier, SpecifierSet
from packaging.version import Version

pyproject = Path(sys.argv[1])
project = tomllib.loads(pyproject.read_text(encoding="utf-8")).get("project", {})
requires_python = project.get("requires-python")
if not isinstance(requires_python, str) or not requires_python.strip():
raise SystemExit(f"{pyproject}: project.requires-python is required")
runtime = Version(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
try:
supported = runtime in SpecifierSet(requires_python)
except InvalidSpecifier as exc:
raise SystemExit(
f"{pyproject}: invalid project.requires-python: {requires_python!r}"
) from exc
print("supported" if supported else "unsupported")
PY
)"
if [[ "$compatibility_decision" == "unsupported" ]]; then
continue
fi
if [[ "$compatibility_decision" != "supported" ]]; then
printf 'Unexpected compatibility decision for %s: %s\n' "$pyproject" "$compatibility_decision" >&2
exit 1
fi
package_name="$(basename "$package_dir")"
python -m compileall -q "$package_dir/src" "$package_dir/tests"
PYTHONPATH="$package_dir/src" \
COVERAGE_FILE="/tmp/orgmetra-${package_name}-${ORGMETRA_PYTHON_MINOR}.coverage" \
python -m pytest -c "$pyproject" "$package_dir/tests"
executed=$((executed + 1))
done
if [[ "$executed" -eq 0 ]]; then
printf 'No owned package declared Python %s support; compatibility evidence would be vacuous.\n' "$ORGMETRA_PYTHON_MINOR" >&2
exit 1
fi
- name: Print exact manifest repair data
if: failure()
run: python tests/validate_repository.py --print-manifest
Expand Down
102 changes: 102 additions & 0 deletions docs/traceability/foundation-python-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Foundation Python compatibility traceability

## Authority

- Repository: `ContextualWisdomLab/Orgmetra`
- Protected parent snapshot: `develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f`
- Canonical repair issue: #258
- Maturity: `implemented_on_active_pr`

## Finding

Protected Foundation CI executes repository-owned Python quality on CPython 3.14, while several merged
packages declare `requires-python = ">=3.12"`. Structured Interview Plan #40 also carried real CPython
3.12/3.13 execution in its historical package-local workflow. Protected #161 correctly retired package-local
quality workflows, but adopting that deletion without replacement evidence would weaken the declared runtime
contract.

Three follow-up reviews found separate fail-open defects in the first compatibility implementation. Metadata
parser failures could be reclassified as unsupported-package skips; PEP 440 was evaluated against a fabricated
`major.minor.0` rather than the executed interpreter patch; and an owned `packages/*/pyproject.toml` could
escape package acceptance if either `src/` or `tests/` disappeared. Those paths now fail closed.

Exact-head Foundation run `34050838082` exposed a fourth defect in the implementation shape. Python 3.12 and
3.13 were introduced as a second matrix job, but protected repository policy intentionally constrains
Foundation to one job to avoid recreating the previous matrix-driven Actions admission pressure. The two
compatibility jobs themselves passed, while the canonical runner/queue contract failed before repository
validation. Compatibility evidence is therefore kept, but it executes sequentially inside the existing
`quality` job rather than widening the job graph.

Exact head `79e8757515673144b68687517360cf493e93ccb8` then produced a complete Foundation GREEN in run
`34053906336`: the one `Repository quality` job passed exact checkout, runner-image proof, Foundation validation,
dependency hygiene, primary package/service/PostgreSQL contracts, Python 3.12 compatibility, Python 3.13
compatibility, and clean-checkout proof.

A fifth review found a provenance gap despite that GREEN. The compatibility requirement file was hash-locked at
the package line level, but the file itself was not part of the canonical Foundation manifest inventory. A
reviewed dependency set could therefore change without changing the manifest unless another tracked artifact
bound it. The active successor now makes that binding explicit: the manifest-sealed Foundation workflow verifies
SHA-256 `cebb36181e8ac995a36d73a02a45094a204ff5adb3cbcdc0c9eccff309ac6aab` for
`.github/requirements/foundation-compatibility-test.txt` before either compatibility runtime can install it.
The workflow itself is resealed in `manifest.json`, so the dependency input is transitively integrity-bound
without adding a second quality owner or mutable external source.

A package-local workflow is not restored. The capability remains owned by
`.github/workflows/foundation-ci.yml`.

## Decision

Foundation keeps one `quality` job on pinned `ubuntu-24.04`. That job runs the primary CPython 3.14 package,
service, and PostgreSQL contracts, proves the reviewed compatibility-toolchain file digest, then switches to
CPython 3.12 and CPython 3.13 in sequence with `actions/setup-python`. Each compatibility runtime installs the
same reviewed hash-locked compatibility toolchain and executes every package whose `project.requires-python`
includes the actual interpreter patch. No compatibility matrix or second Foundation job is permitted.

Primary and compatibility package execution discover `packages/*/pyproject.toml` rather than naming packages
in workflow logic. For each compatibility runtime, Foundation reads `project.requires-python` with `tomllib`
and `packaging.specifiers.SpecifierSet`, evaluates it against
`sys.version_info.major.minor.micro`, and permits a skip only when a syntactically valid constraint excludes
that exact executed release. Missing, blank, non-string, malformed TOML, invalid specifiers, or parser failures
terminate the compatibility execution. Every selected package is compiled and runs its own pytest
configuration, preserving its exact statement and branch coverage gate.

The repository-quality hygiene contract independently enumerates every `packages/*/pyproject.toml` and
requires both `src/` and `tests/`. Its self-regression constructs missing-`src` and missing-`tests` fixtures and
requires both to fail closed. Non-Python directories without a `pyproject.toml` remain outside this contract.

The primary CPython 3.14 toolchain remains bound by `.github/requirements/foundation-test.txt`. CPython
3.12/3.13 use `.github/requirements/foundation-compatibility-test.txt`, installed with
`--require-hashes --no-deps --only-binary=:all:` and reviewed wheel hashes for both compatibility runtimes. The
compatibility file's complete bytes are additionally pinned by the manifest-sealed Foundation workflow before
installation.

## Invariants

- `.github/workflows/foundation-ci.yml` remains the only repository quality owner.
- Foundation expands to exactly one repository-owned job; compatibility must not add a matrix or second job.
- The Foundation job uses `ubuntu-24.04`; `ubuntu-latest` remains rejected by executable regression.
- CPython 3.12 and 3.13 compatibility executes sequentially after the primary CPython 3.14 quality contracts.
- The compatibility requirement file must match the reviewed SHA-256 before either compatibility install.
- Compatibility discovery is package-neutral and contains no Interview Plan or Selection Monitoring switch.
- Every discovered owned Python package has both `src/` and `tests/`; incomplete layout is a Foundation
failure rather than an accepted skip.
- Invalid or missing `project.requires-python` metadata fails closed; only a valid constraint excluding the
actual executed interpreter patch may skip a package.
- Patch-sensitive PEP 440 constraints are evaluated against the executed release, never a fabricated `.0`.
- Each compatibility runtime fails if no owned package actually declares that runtime supported.
- Repository-local packages are not installed into the checkout as an implicit dependency workaround.
- Package-local quality workflows retired by protected #161 remain retired.

## Scope boundary

This change proves declared compatibility for Python packages under `packages/`. The two HTTP services
currently declare Python 3.11 support but remain a separate #260 service-runtime contract. No Python 3.11
service-compatibility claim is made by #258 or #40.

## Adoption

After this capability is integrated on protected `develop`, #40 can discard
`.github/workflows/interview-plan-quality.yml`, retain its `requires-python = ">=3.12"` declaration and
package tests, and receive Python 3.12/3.13/3.14 evidence through Foundation without adding a package name to
shared workflow logic. #42 should likewise adopt the protected generic package execution rather than copying
its mutable shared-dispatcher implementation.
8 changes: 4 additions & 4 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": "27fd3f2a69181e6a31b49ab2a3d394bfc8dca2b8ef5e9ce39324273f7962773d",
"bytes": 11708,
"lines": 251
},
{
"path": ".gitignore",
Expand Down Expand Up @@ -472,4 +472,4 @@
"lines": 637
}
]
}
}
Loading
Loading