Skip to content

feat(hris): add governed Employment work-capacity review - #103

Open
seonghobae wants to merge 8 commits into
developfrom
feat/employment-work-capacity-review
Open

feat(hris): add governed Employment work-capacity review#103
seonghobae wants to merge 8 commits into
developfrom
feat/employment-work-capacity-review

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible gap

Protected develop@9e3e4847510e1e612b48474ba42b177b8ed824df has authoritative Employment and Assignment truth, but no bounded review evidence for a proposed change in one Employment's contracted work capacity before downstream bitemporal mutation. This Orgmetra-only lane adds that boundary without changing compensation, payroll, leave, scheduling, Assignment, or any foreign CWL repository.

Test-first repair sequence

  • RED-contract c5c55827557662b77d99e5f5cd5d4b438f70cb02: package contract, adversarial tests and exact-head workflow were introduced while production review.py was deliberately absent. Runs materialized but were superseded before terminal completion, so no terminal hosted RED is claimed.
  • Implementation 3dab4d8dc57659ffb82991f50099f5defc07808a: added the governed packet, deterministic evidence, docs and artifact-quality lane.
  • Signed-zero regression 53a6998e022cc30067a749254e7cd2c95b0bfe55 → repair af7dd8c4bda2fe177ebcb11590dd0775ccc4ef42: zero capacity now has one canonical evidence representation (0.0000); Decimal('-0.0000') fails closed.
  • Strong system-time regression a411603a0f124920a4d3999fb3d45459b1a0b8d0 → root repair/current head 645d2f3b2db10e2bdfbe60422837a5986d8f39f8: callers can no longer inject or backdate recorded_at. Orgmetra generates system-recorded UTC issuance time inside the constructor, independently from business effective_on and human reviewed_at.

Current contract

EmploymentWorkCapacityReviewPacket binds authoritative tenant/Employment scope, exact finite four-decimal current/proposed capacity ratios, business effective date, human review time, owner-generated system-recorded time, exact SHA-256 employment-terms/capacity-policy/reviewer-identity evidence, distinct requester/reviewer correlations, controlled non-sensitive reason, and bounded evidence version.

The packet remains PII/value-minimized and fixed to employment_work_capacity_review, reviewed_for_authoritative_resolution, not_authorized_to_change_employment_or_compensation, and mandatory human review. It does not classify legal full-time/part-time status, infer suitability/availability for work, or authorize Employment, Assignment, compensation, payroll, leave, or scheduling mutation.

Nil/Max UUID sentinels, malformed digests, runtime subclasses, noncanonical Decimal scale, signed negative zero, actor overlap, review time later than owner-generated issuance, mutable governance constants, and post-issuance field mutation fail closed. Canonical JSON is deterministic and routine repr is redacted. The process-local weak issuance registry is defense in depth only, not durable authorization/signature evidence.

Exact-current-head evidence

Base: develop@9e3e4847510e1e612b48474ba42b177b8ed824df
Head: 645d2f3b2db10e2bdfbe60422837a5986d8f39f8

Every applicable exact-current-head workflow is terminal GREEN:

  • Employment Work Capacity Review Quality 32670611249 — success
  • Foundation CI 32670611206 — success
  • Recovery Rehearsal Quality 32670611211 — success
  • SAST Semgrep 32670611285 — success
  • Security Scan 32670611245 — success

Fresh review verification finds no submitted review and no review thread. GitHub reports the PR open, ready-for-review, and mergeable.

Merge governance

Ready-for-review is not merge authorization. Keep unmerged until a qualifying independent non-author approval exists on this unchanged head and issue #89's enforceable develop protection defect is actually repaired. Immediately before any future merge, refetch exact head, live base, reviews, unresolved threads, effective rules/protection and exact-current-head checks and use expected-head protection only if every live gate is satisfied. Do not self-approve, weaken or simulate protection, manufacture passing evidence, or transfer predecessor checks/reviews.

Summary by CodeRabbit

  • 새 기능

    • 고용 계약상 작업용량 변경을 위한 비권위적 검토 증거 패킷을 추가했습니다.
    • 현재·제안 용량, 적용일, 검토자·요청자, 정책 및 증거 무결성 정보를 기록합니다.
    • 표준 JSON과 SHA-256 기반 변조 감지를 지원하며, 관련 업무 데이터를 직접 변경하지 않습니다.
  • 문서

    • 사용 범위, 제한사항, 재검증 절차와 관련 표준·추적성 정보를 문서화했습니다.
  • 품질 개선

    • 입력 검증, 불변성, 시스템 기록 시각, 커버리지 및 클린 빌드 검증을 자동화했습니다.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d3f8cf3-e5ca-4357-b8f4-736496357b93

📥 Commits

Reviewing files that changed from the base of the PR and between 9e3e484 and 645d2f3.

📒 Files selected for processing (11)
  • .github/workflows/employment-work-capacity-review-quality.yml
  • docs/adr/0103-governed-employment-work-capacity-review.md
  • docs/doctoring/employment-work-capacity-review-references.md
  • docs/traceability/employment-work-capacity-review.md
  • packages/employment-work-capacity-review/CHANGELOG.md
  • packages/employment-work-capacity-review/README.md
  • packages/employment-work-capacity-review/pyproject.toml
  • packages/employment-work-capacity-review/src/orgmetra_employment_work_capacity_review/__init__.py
  • packages/employment-work-capacity-review/src/orgmetra_employment_work_capacity_review/review.py
  • packages/employment-work-capacity-review/tests/test_review.py
  • packages/employment-work-capacity-review/tests/test_system_recorded_time.py

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


📝 Walkthrough

Walkthrough

Employment work-capacity review 패킷 패키지와 관련 문서, 테스트, GitHub Actions 품질 워크플로를 추가했다. 패킷은 입력 검증, canonical 증거, SHA-256 무결성, 시스템 기록 시각을 지원하며 운영 데이터를 변경하지 않는다.

Changes

Employment work-capacity review

Layer / File(s) Summary
검토 계약과 패키지 설정
docs/adr/0103-..., docs/doctoring/..., docs/traceability/..., packages/employment-work-capacity-review/{README.md,CHANGELOG.md,pyproject.toml}
패킷의 비권위 범위, 권한 경계, 증거 요구사항, 기록 규칙과 테스트·커버리지 설정을 정의한다.
패킷 생성과 증거 무결성
packages/employment-work-capacity-review/src/...
입력 형식과 검토 상태를 검증한다. 패킷을 생성하고, canonical 증거와 SHA-256 digest를 관리한다. 시스템이 recorded_at을 생성한다.
패킷 계약 테스트
packages/employment-work-capacity-review/tests/*
유효한 생성, 입력 오류, actor 분리, 시간 검증, 직렬화, 발행 후 변조 탐지, digest 재생성과 시스템 기록 시각을 검증한다.
격리 빌드와 품질 게이트
.github/workflows/employment-work-capacity-review-quality.yml
고정된 Python 환경에서 wheel을 빌드한다. 격리된 virtualenv에 설치한 뒤 의존성, import 경계, test extra, 테스트, 커버리지와 clean checkout 상태를 검사한다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 645d2

This PR adds a bounded, non-mutating employment work-capacity review packet with deterministic evidence and system-generated issuance time. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant 호출자
  participant 패킷빌더 as build_employment_work_capacity_review_packet
  participant 패킷 as EmploymentWorkCapacityReviewPacket
  participant 증거 as Canonical 증거

  호출자->>패킷빌더: 검토 입력 전달
  패킷빌더->>패킷: 시스템 recorded_at으로 생성
  패킷->>증거: 정규화 및 SHA-256 digest 생성
  증거-->>패킷: canonical 문서와 digest 반환
  패킷-->>호출자: 검증된 패킷 반환
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
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 제목은 거버넌스가 적용된 Employment work-capacity review 추가라는 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ 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 feat/employment-work-capacity-review

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.

@seonghobae
seonghobae marked this pull request as ready for review August 23, 2026 23:06

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 potential issues.

Open in Devin Review

Comment on lines +128 to +132
def _validate_utc_timestamp(value: object, field_name: str) -> datetime:
"""Require an exact built-in datetime whose timezone is the UTC singleton."""
if type(value) is not datetime or value.tzinfo is not timezone.utc:
raise ValueError(f"{field_name} must be an exact built-in UTC datetime")
return value

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: UTC check requires the exact singleton

_validate_utc_timestamp (review.py:130) rejects any reviewed_at whose tzinfo is not the timezone.utc singleton. A numerically-UTC datetime built from timezone(timedelta(0)) or ZoneInfo("UTC") fails. This strictness is intentional, but callers that normalize via astimezone(ZoneInfo("UTC")) will be rejected.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +272 to +280
def _verified_payload(self) -> dict[str, object]:
"""Return one verified snapshot or fail closed after post-issuance mutation."""
payload = self._payload()
digest = sha256(_canonical_json(payload).encode("utf-8")).hexdigest()
with self._issuance_lock:
issued_digest = self._issuance_digests.get(self)
if issued_digest != digest:
raise ValueError("Employment work-capacity evidence was modified after issuance")
return payload

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Tamper detection is process-local only

The issuance digest lives in an identity-keyed WeakKeyDictionary (review.py:181-184, 241-242), so tamper detection works only for packets created in the current process. A packet obtained via deserialization has no stored digest, so _verified_payload at review.py:272-280 raises 'modified after issuance' on every access. The PR frames this as defense-in-depth, not durable evidence.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@seonghobae
seonghobae marked this pull request as draft August 24, 2026 15:41
@seonghobae
seonghobae marked this pull request as ready for review August 24, 2026 15:41
@seonghobae seonghobae closed this Aug 24, 2026
@seonghobae seonghobae reopened this Aug 24, 2026
@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please review the current unchanged head against protected develop. Local exact-head verification: all owned package suites pass at 100% statement/branch coverage.

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