Skip to content

fix(job-analysis): declare a Python floor its owned dependencies can install - #305

Open
seonghobae wants to merge 7 commits into
developfrom
fix/job-analysis-python-floor-owned-deps
Open

fix(job-analysis): declare a Python floor its owned dependencies can install#305
seonghobae wants to merge 7 commits into
developfrom
fix/job-analysis-python-floor-owned-deps

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Scope

Protected base is develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. This is a metadata/acceptance correctness repair for the Job Analysis service distribution; no runtime domain behavior, database schema, API, or employment-decision semantics change.

Python-floor finding

services/job-analysis-api/pyproject.toml declared requires-python = ">=3.11" while both mandatory owned distributions it pins require >=3.12:

  • packages/hris-kernel/pyproject.toml: requires-python = ">=3.12" (version 0.4.0)
  • packages/keyverse-adapter/pyproject.toml: requires-python = ">=3.12" (version 0.1.0)

A Python 3.11 interpreter therefore cannot install the service's declared dependency closure. Canonical Foundation runs the service tests with owned src directories on PYTHONPATH, which exercises source behavior without proving resolver/installability of the declared distribution closure. The unchanged-base regression fails with assert (3, 12) <= (3, 11); d47e01468e55b365302b1ffaa7e1d5e73a0a95e3 raised the service floor to >=3.12 and added metadata tests.

Internal-pin false-greens found during review

Fresh review of d47e014... found that the new test claimed to prove every declared internal orgmetra-*==version pin was canonical but implemented only assert expected_dependencies <= declared_dependencies. That proves required pins are present, but an extra stale or unknown internal dependency would still pass.

Test-first 361d48bcc15bb8de13df85f5dd08f4aa6b3d1b90 added a negative regression for that extra-pin case while preserving the subset implementation. Its hosted generation was cancelled by immediate successor publication, so no hosted RED is claimed. 66e2fcb93fea5d7d2624d2cbc8859511a119e6bf then classified literal orgmetra-* declarations and required that set to equal the canonical owned name==version set. Foundation 34577568833 reached terminal SUCCESS on that exact head before the next finding; it is historical causal evidence only.

A narrower packaging-identity audit found that literal startswith("orgmetra-") is not a valid distribution-ownership classifier. PyPA's current Names and normalization specification requires comparison after lowercasing and replacing runs of ., _, or - with -; therefore underscore/dot/case variants are equivalent names for lookup/comparison. A stale internal pin using _ or . could have been misclassified as a third-party dependency. Primary specification: https://packaging.python.org/en/latest/specifications/name-normalization/

Test-first b9e1daa73121bf0e6f126c42f8ecda41e8db2e33 captured the underscore-form escape against the literal classifier; its hosted generation was cancelled by successor publication. 2934ca96f73187ede10ed0a0fd08c6cd622fd62e then normalized dependency names for Orgmetra-namespace classification while preserving canonical exact original pins.

That first normalizing parser was itself too narrow: its lookahead admitted extras/direct references/operators/markers but rejected the standards-valid compatibility form requests (>=2.0). PyPA's current Dependency specifiers grammar retains optional parentheses around a version specifier for PEP 345 compatibility and says consumers should accept them even though producers should not generate them: https://packaging.python.org/en/latest/specifications/dependency-specifiers/

Test-first 538de7b45ed497737ec82cdc0f57337196a6cc4c requires an unrelated parenthesized third-party requirement to remain accepted by the ownership classifier; the exact hosted generation was cancelled by immediate successor publication, so no hosted RED is claimed. Minimal successor 648aca54c30ee7879e85faeeab76609c0a70b1e5 deliberately parses only the leading standards-valid distribution-name token needed for ownership classification, normalizes that name, and leaves full PEP 508 validation to packaging/build tooling. This avoids inventing a partial dependency grammar while still failing alternate/unknown Orgmetra declarations against the canonical exact pin set.

The analogous People contract remains owned by #64 and received a non-competing normalization handoff. Repository-wide runtime compatibility remains #260; built wheel/sdist resolver-install acceptance remains #261. Durable baseline wording stays with #100.

Exact-head authority

  • base: protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f
  • exact head: 648aca54c30ee7879e85faeeab76609c0a70b1e5
  • state: open · Ready for Review · mechanically mergeable; the unchanged head was admitted from Draft without source/base mutation
  • changed files: service pyproject.toml plus the owned metadata contract test
  • Foundation 34578195004 is terminal SUCCESS; Repository quality job 103195420990 checked out the exact head and passed compilation, Foundation validation/dependency hygiene, owned unit/service contracts, isolated PostgreSQL contracts and read-only validation
  • SAST 34578194933 is terminal SUCCESS on the exact head
  • Security 34578194964 is terminal FAILURE only at the authoritative Dependency Review availability boundary. dependency-review job 103196192506 verified the exact head and then failed at Check dependency review support; the pinned Dependency Review action was skipped. Independent Scorecard 103196192467, OSV 103196192491, and Trivy 103196192518 succeeded but are not substitutes. Fresh current-head canary is on canonical central owner ContextualWisdomLab/.github#810 comment 5632088151
  • required CodeQL 34578194899 is terminal FAILURE in the central consumer-before-producer settlement lane. Python consumer 103196942801 failed enforcement at 08:28:47Z and Actions consumer 103196942778 at 08:35:10Z; authoritative dispatch producer 103200825822 did not start until 08:36:55Z and completed SUCCESS at 08:37:03Z. Fresh current-head canary is on canonical central owner ContextualWisdomLab/.github#2040 comment 5632090449
  • submitted Reviews API evidence contains one APPROVED Noema review, but its own footer binds it to predecessor d47e01468e55b365302b1ffaa7e1d5e73a0a95e3; it is stale after the six ordinary-forward hardening commits and is not current-head approval
  • current inline review-thread inventory is empty
  • Draft → Ready on the unchanged 648aca54... head did not materialize any new exact-head OpenCode/Noema check identity or current-head Reviews API verdict. Existing OpenCode 103197828450 completed at 08:26:45Z and Noema 103196778350 at 08:30:22Z, both before Ready. Fresh lifecycle canary is on ContextualWisdomLab/.github#2045 comment 5632112971

The owned source/metadata acceptance is current-head GREEN; the terminal failures and review-materialization defect above are canonical central-owner incidents and are not reasons to churn this leaf source, weaken gates, or manufacture a verdict. Keep normal merge fail-closed until then-live central required workflows and current-head review governance are admissible.

Acceptance

  1. Job Analysis declares a Python floor compatible with all mandatory owned distributions it pins.
  2. Distribution ownership classification follows canonical Python packaging name normalization, so -, _, ., and case variants cannot evade the internal boundary.
  3. The ownership classifier extracts only the leading distribution name and does not reject otherwise valid PEP 508 forms such as extras, direct references, markers, ordinary specifiers, or compatibility parenthesized version specifiers.
  4. Every classified internal Orgmetra dependency must equal one canonical owned exact name==version pin; missing, stale, alternatively spelled, or unknown internal dependencies fail closed.
  5. Metadata is read without importing/executing package code.
  6. Canonical service tests and repository validation remain current-head GREEN with required coverage/docstring contracts.
  7. A separate distribution-install acceptance tier must prove actual wheel/sdist resolver installability; these metadata tests are not mislabeled as that evidence.
  8. Normal protected integration still requires then-live security/review governance. No predecessor transfer, self/model approval, administrator bypass, no-op retrigger, force-push, destructive rebase, or simple Close.

Summary by CodeRabbit

  • 호환성 변경

    • Job Analysis API의 최소 지원 Python 버전이 3.11에서 3.12로 변경되었습니다.
  • 품질 개선

    • 내부 패키지 의존성이 소유 패키지의 정확한 버전 고정 목록과 일치하는지 더욱 엄격하게 검증합니다.
    • 내부 의존성의 추가 항목 및 이름 별칭을 감지하는 검증이 강화되었습니다.

…install

services/job-analysis-api/pyproject.toml advertised requires-python >=3.11,
but both mandatory owned distributions it pins require >=3.12:
packages/hris-kernel (0.4.0) and packages/keyverse-adapter (0.1.0). A 3.11
interpreter therefore cannot install the service's declared dependency
closure, while source-tree PYTHONPATH test execution hid the contradiction.

Raise the declared floor to >=3.12 and add a metadata regression that reads
the owned package pyprojects, asserts the exact internal pins match the
canonical package names and versions, and asserts the service Python floor is
not below any owned dependency floor. This mirrors the equivalent People API
contract so the same class of stale metadata cannot return unnoticed.
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 229fbcb7-0e0d-4849-913e-83b64c864129

📥 Commits

Reviewing files that changed from the base of the PR and between d47e014 and 648aca5.

📒 Files selected for processing (1)
  • services/job-analysis-api/tests/test_internal_dependency_versions.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

서비스의 최소 Python 버전을 3.12로 변경했습니다. 테스트는 프로젝트 메타데이터를 읽고, 내부 의존성의 정규화된 이름과 정확한 버전 고정을 검증합니다.

Changes

런타임 및 내부 의존성 일관성

Layer / File(s) Summary
런타임 하한 메타데이터
services/job-analysis-api/pyproject.toml, services/job-analysis-api/tests/test_internal_dependency_versions.py
requires-python 하한을 >=3.12로 변경했습니다. 테스트 헬퍼는 tomllib로 프로젝트 메타데이터를 읽고 Python 하한을 파싱합니다.
내부 의존성 및 런타임 검증
services/job-analysis-api/tests/test_internal_dependency_versions.py
orgmetra- 네임스페이스 의존성만 정규화한 뒤 소유 패키지의 name==version 집합과 정확히 비교합니다. 추가 내부 고정과 정규화된 별칭을 거부하고, 외부 패키지의 괄호 PEP 508 지정자를 허용합니다.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 648ac

The service now declares the dependency-required Python 3.12 floor, with metadata checks guarding its owned dependency pins. No merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 Job Analysis 서비스의 Python 최소 버전을 상향하고 owned dependencies의 설치 요구 사항과 일치시키는 주요 변경을 정확히 설명합니다. 간결하고 구체적입니다.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/job-analysis-python-floor-owned-deps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cwl-noema-review cwl-noema-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noema LLM review

The change correctly raises the service Python floor to >=3.12 to match the floors of its owned runtime dependencies (orgmetra-hris-kernel and orgmetra-keyverse-adapter). The new test reads each package's actual pyproject metadata and verifies that the service floor covers every owned package floor, protecting against stale or incompatible pins. The floor bump is both necessary and sufficient per the test assertions, and no regressions or correctness issues were found.

Reviewed changed lines

  • services/job-analysis-api/pyproject.toml:10 (RIGHT): The requires-python floor is raised from >=3.11 to >=3.12 to align with the owned package floors enforced by the new test.
  • services/job-analysis-api/tests/test_internal_dependency_versions.py:48 (RIGHT): The assertion enforces that the service Python floor is >= each owned package floor, making the >=3.12 bump necessary and preventing future installability regressions.

Adversarial validation

  • services/job-analysis-api/pyproject.toml:10 (RIGHT) falsified: Raising requires-python to >=3.12 could break installation on Python 3.11 environments that previously worked. — The new test test_job_analysis_api_python_floor_covers_owned_runtime_dependencies reads the actual pyproject files of orgmetra-hris-kernel and orgmetra-keyverse-adapter and asserts their minimum Python floors are <= the service floor. Both packages declare floors that require >=3.12, so they cannot install on 3.11 regardless of this change. The service floor bump to >=3.12 therefore only reflects the mandatory requirement of its owned dependencies, and 3.11 was never actually installable.
  • services/job-analysis-api/tests/test_internal_dependency_versions.py:48 (RIGHT) falsified: The new floor-coverage test could be circular or fail to catch a dependency floor raised above the service floor. — The test calls _project_metadata on the package paths (line 13) to read the current pyproject data from disk, then _minimum_python_version extracts the exact floor. The assertion at line 48 compares each package floor to the service floor. If a package floor were > service floor, the assertion would fail. This is not circular because the metadata is sourced directly from the owned packages, not from the service's own declaration.
  • Residual risk: Minimal residual risk; the test relies on exact >=major.minor parsing and would require updating if the contract changes to a different specifier format.

Findings

  • No blocking findings.
  • Result: APPROVE
  • Head SHA: d47e01468e55b365302b1ffaa7e1d5e73a0a95e3
  • Reviewer credential: noema-review-github-app-refresh
  • Actor: cwl-noema-review[bot]

@seonghobae
seonghobae marked this pull request as draft September 11, 2026 08:06
@seonghobae

Copy link
Copy Markdown
Contributor Author

Lane verification at adversarial head 648aca54

Ran the canonical job-analysis quality invocation locally on the pushed head (648aca54, the 6 hardening commits on top of d47e0146):

PYTHONPATH=services/job-analysis-api/src:packages/hris-kernel/src:packages/keyverse-adapter/src \
COVERAGE_FILE=/tmp/orgmetra-job-analysis-api.coverage \
uv run --no-project --with pytest --with pytest-cov python -m pytest \
  -c services/job-analysis-api/pyproject.toml services/job-analysis-api/tests

Result: 73 passed, 100% statement+branch coverage (594 stmts, 210 branches, 0 missed). npm run validate EXIT=0 (55/55).

The added tests (exact owned-dependency set, normalized/aliased internal distribution names, extra-drift rejection, parenthesized specifiers, and PEP 508 name classification without narrowing) all hold GREEN at this head. Source is green; the only remaining reds are the shared control-plane checks (CodeQL compatibility analysis, dependency-review support probe, opencode-review verdict), which are external to this repository.

@seonghobae
seonghobae marked this pull request as ready for review September 11, 2026 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant