-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add governed performance review packet #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
seonghobae
wants to merge
112
commits into
develop
Choose a base branch
from
feat/governed-performance-review
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
112 commits
Select commit
Hold shift + click to select a range
3d2891c
test: define performance review quality contract
seonghobae fe16e6b
test: add RED governed performance review contract
seonghobae 080b6dc
test: wire RED performance review quality gate
seonghobae 44fa375
feat: implement governed performance review packet
seonghobae b763580
feat: export governed performance review contract
seonghobae e230dcf
docs: explain governed performance review boundary
seonghobae a5f2086
docs: record unreleased performance review slice
seonghobae 9b8d119
docs: record governed performance review decision
seonghobae 13af61c
docs: add APA 7 performance review sources
seonghobae 22d71c6
docs: trace governed performance review slice
seonghobae 7c3aafd
test: make performance scope resolution explicitly unverified
seonghobae ece0932
fix: keep performance scope resolution fail closed
seonghobae aa58be7
docs: make performance scope verification explicit
seonghobae 20e7c34
docs: fail closed on unresolved performance scope
seonghobae 03bccab
docs: trace authoritative performance scope resolution
seonghobae 780a658
fix: preserve fixed performance purpose invariant
seonghobae 467c55b
test: require redacted performance review repr
seonghobae a956a4b
fix: redact performance review evidence repr
seonghobae cd33263
chore: reconcile performance review with protected develop
seonghobae 73fc01f
chore: reconcile performance review with protected develop
seonghobae b3350d5
test: reject ungoverned performance review reasons
seonghobae 3a4cba5
fix: close performance review reason vocabulary
seonghobae 34a85e8
test: require performance review evidence versioning
seonghobae f07779f
fix: bind performance review evidence version
seonghobae 5da8926
docs: document performance evidence versioning
seonghobae 8206de7
docs: bind evidence version in performance ADR
seonghobae d63449b
docs: trace performance evidence version
seonghobae 556d4a9
docs: record performance evidence versioning
seonghobae 9cb8a30
Merge protected develop into performance review lane
seonghobae 6952ecc
chore: reconcile performance review onto develop
seonghobae 4b63972
test: classify opaque worker references as personal data
seonghobae 0774a7f
fix: classify worker correlations as personal data
seonghobae dde9ef0
merge: reconcile performance review with protected develop
seonghobae fba8639
chore: reconcile performance review onto restored develop
seonghobae ce88fb9
test: reject UUIDv1 performance review trust references
seonghobae 75ab918
fix: require UUIDv4 performance review trust references
seonghobae 963a426
docs: define UUIDv4 performance review reference privacy
seonghobae b17c474
docs: record UUIDv4 performance trust-reference decision
seonghobae 6fd2377
docs: record performance reference privacy hardening
seonghobae a59faf0
docs: trace UUIDv4 performance reference regression
seonghobae 17024a3
test: reject correlating tenant UUIDv1 in performance review
seonghobae 4688392
fix: require opaque UUIDv4 tenant identity
seonghobae cf6a91f
docs: bind performance tenant identity to UUIDv4
seonghobae d2f7d2a
docs: record performance tenant UUIDv4 privacy repair
seonghobae 83036d9
docs: trace performance tenant UUIDv4 regression
seonghobae 752b4d0
docs: make performance tenant UUIDv4 part of privacy decision
seonghobae 693bcdf
Merge remote-tracking branch 'refs/remotes/origin/develop' into HEAD
seonghobae 26146ef
test: require performance review to accept core tenant UUIDv7
seonghobae 255d424
fix: honor authoritative tenant UUID contract in performance review
seonghobae 27aaaef
docs: align performance-review tenant identity with core
seonghobae 12ec07e
docs: separate review tenant and packet UUID ownership
seonghobae 921d873
docs: trace review tenant UUID interoperability
seonghobae deeb4c7
docs: record review tenant identity interoperability repair
seonghobae eb15456
chore: integrate protected develop into performance-review lane
seonghobae aca8c1f
chore: reconcile performance review with current develop
seonghobae b867f4c
chore(performance): integrate protected develop after #41
seonghobae a8f3197
chore(performance): integrate protected develop after #43
seonghobae c936e0e
test(performance-review): reject recorded-time subclasses
seonghobae d488bd1
fix(performance-review): require exact recorded-time type
seonghobae 75aa24e
test(performance-review): reject forged string evidence types
seonghobae 7a46910
fix(performance-review): require exact string evidence types
seonghobae 513ee38
test(performance-review): reject forged governance text
seonghobae e27d895
fix(performance-review): require exact governance text
seonghobae 1f99050
test(performance-review): pin recorded-time issuance integrity
seonghobae f501dd4
test(performance-review): cover frozen-time fail-closed paths
seonghobae 9080af6
fix(performance-review): freeze recorded-time evidence
seonghobae 2da67e8
docs(performance-review): record recorded-time integrity repair
seonghobae 4c8e5d1
docs(performance-review): explain frozen recorded time
seonghobae 482d297
docs(performance-review): trace recorded-time integrity
seonghobae 26055e3
test(performance-review): reject post-issuance evidence rewrites
seonghobae c10be95
fix(performance-review): seal issued canonical evidence
seonghobae 307cab2
docs(performance-review): record issuance integrity repair
seonghobae a271a06
docs(performance-review): explain process-local issuance seal
seonghobae fc57873
docs(performance-review): trace issuance tamper evidence
seonghobae a221113
test(performance-review): reject digest string subclasses
seonghobae e4e810e
fix(performance-review): require exact digest text
seonghobae 95a3d7d
docs(performance-review): record strict digest runtime contract
seonghobae f6856cc
docs(performance-review): trace exact digest runtime evidence
seonghobae 2da07d2
test(performance-review): prove trusted issuance and reference-risk gaps
seonghobae 353b77c
fix(performance-review): own recorded time and classify unverified re…
seonghobae 62fc923
test(performance-review): align fixtures with trusted issuance clock
seonghobae 41956f4
test(performance-review): exercise trusted host clock boundary
seonghobae 0888b1e
test(performance-review): stop supplying recorded time in issuance fi…
seonghobae 2625cdd
test(performance-review): use system-owned time in repr fixture
seonghobae 294ad0f
test(performance-review): use system-owned time in string-integrity f…
seonghobae d3b093e
test(performance-review): preserve system-owned time in tenant rebuilds
seonghobae d618da0
docs(performance-review): document trusted time and reference provena…
seonghobae efde52c
docs(performance-review): record trusted issuance and reference-risk …
seonghobae 14aa5a0
docs(adr): harden performance-review issuance and reference provenance
seonghobae 804d596
docs(traceability): bind performance-review time and reference-risk c…
seonghobae 93dda90
docs(adr): index performance-review decision
seonghobae e43ab2d
docs: register active performance-review capability
seonghobae f75dc8d
docs(performance-review): register active capability
seonghobae e011579
docs: remove duplicate performance ADR entry
seonghobae 482bd18
test(performance-review): require free-form feedback exclusion
seonghobae 6617831
fix(performance-review): make feedback exclusion explicit
seonghobae 58086e2
docs(traceability): bind feedback exclusion contract
seonghobae ed5ed70
docs(performance-review): record feedback privacy invariant
seonghobae f2f788f
docs(adr): make feedback exclusion machine-verifiable
seonghobae 7a0e328
test(performance-review): exclude fixed feedback invariant from build…
seonghobae 1aee9c2
test(performance-review): require shared config quality triggers
seonghobae 70123ca
fix(performance-review): retrigger quality on shared config
seonghobae d318941
docs(performance-review): record shared-config gate integrity
seonghobae 34b7777
docs(performance-review): trace shared-config quality evidence
seonghobae ba93d03
test(performance-review): prevent issuance reseal
seonghobae 61ba3ec
fix(performance-review): make issuance registration single-use
seonghobae 21cd2de
docs(performance-review): document single-use issuance
seonghobae 42f3cfe
docs(traceability): bind performance review issuance once
seonghobae ce64f93
docs(adr): require single-use performance review issuance
seonghobae c5ad805
chore(performance-review): record single-use issuance repair
seonghobae 721f13e
test(performance-review): reproduce seal-loss reissuance
seonghobae dbe465d
fix(performance-review): preserve issuance lifecycle after seal loss
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| name: Performance Review Quality | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: | ||
| - develop | ||
| paths: | ||
| - "packages/performance-review/**" | ||
| - ".github/requirements/foundation-test.txt" | ||
| - ".github/workflows/performance-review-quality.yml" | ||
| - ".gitignore" | ||
| - ".python-version" | ||
| - "conftest.py" | ||
| - "packages/conftest.py" | ||
| - "pyproject.toml" | ||
| - "pytest.ini" | ||
| - "setup.cfg" | ||
| - "tox.ini" | ||
| - "docs/adr/0018-governed-performance-review.md" | ||
| - "docs/doctoring/performance-review-references.md" | ||
| - "docs/traceability/performance-review.md" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: performance-review-quality-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| unit: | ||
| name: Performance review contract and 100% coverage | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - name: Checkout exact candidate | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| persist-credentials: false | ||
| - name: Prove exact candidate checkout | ||
| 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 | ||
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | ||
| with: | ||
| python-version: "3.14" | ||
| check-latest: false | ||
| - name: Install reviewed test toolchain | ||
| run: | | ||
| python -m pip install --require-hashes --no-deps --only-binary=:all: -r .github/requirements/foundation-test.txt | ||
| python -m pip check | ||
| - name: Compile performance review package | ||
| run: python -m compileall -q packages/performance-review/src packages/performance-review/tests | ||
| - name: Test performance review with exact statement and branch coverage | ||
| env: | ||
| PYTHONPATH: packages/performance-review/src | ||
| COVERAGE_FILE: /tmp/orgmetra-performance-review.coverage | ||
| run: python -m pytest -c packages/performance-review/pyproject.toml packages/performance-review/tests | ||
| - name: Require clean checkout | ||
| run: | | ||
| git diff --exit-code | ||
| test -z "$(git status --porcelain)" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # ADR 0018: Governed performance-review evidence packet | ||
|
seonghobae marked this conversation as resolved.
|
||
|
|
||
| - Status: Proposed — active PR only | ||
| - Date: 2026-08-19 | ||
|
|
||
| ## Context | ||
|
|
||
| Orgmetra already owns authoritative Employment/Job truth and performance/criterion evidence boundaries, but a buyer-facing review workflow also needs a small pre-rating object that identifies which employment references, review period, performance cycle, criteria, goals, outcome evidence, and reviewer are being considered without copying rating values, narrative feedback, or model output into the envelope. | ||
|
|
||
| A transport-neutral packet cannot prove merely from syntactically valid references that the Person, Employment, Job, cycle, goals, and observation snapshot all resolve to one authoritative temporal scope. Nor can UUIDv4 syntax prove that independently supplied bytes were randomly generated or contain no encoded identifier content. Treating either relationship resolution or reference opacity as established from syntax would create a misleading high-impact evidence boundary. Authoritative relationship/temporal resolution and trusted reference-provenance verification therefore remain required downstream steps before rating. UUIDv1 is still rejected for packet-owned namespaced references because its timestamp/node layout is unnecessary metadata for this boundary. The authoritative tenant identifier is different: it is issued by Orgmetra core, so this leaf package accepts the canonical non-sentinel operational UUID contract owned by that boundary rather than imposing a second version policy. | ||
|
|
||
| System-recorded time is also audit evidence. Accepting an arbitrary caller-supplied historical `generated_at` would let a caller backdate issuance while still passing a future-only validation gate. The packet therefore owns the issuance timestamp and reads it from the host clock during construction rather than accepting it as a public constructor or builder input. | ||
|
|
||
| U.S. OPM performance-management guidance treats performance management as a continuous cycle of planning, monitoring, developing, rating, and rewarding, and describes rating as evaluation against established elements and standards. ISO 30414:2025 Edition 2 provides current human-capital reporting requirements and recommendations across areas including productivity, skills/capabilities, and related workforce governance. Orgmetra uses those sources as design evidence, not as a claim that this packet by itself satisfies any jurisdiction-specific appraisal rule or ISO certification requirement. | ||
|
|
||
| ## Decision | ||
|
|
||
| Introduce a transport-neutral `PerformanceReviewPacket` that remains pre-rating governance evidence. | ||
|
|
||
| The packet MUST bind: | ||
|
|
||
| - a canonical non-sentinel tenant identity under Orgmetra's authoritative operational UUID contract; | ||
| - canonical non-sentinel UUIDv4-shaped namespaced Person, Employment, Job, performance-cycle and performance-review references, rejecting UUIDv1 and other non-v4 suffixes without claiming that UUIDv4 syntax proves opacity; | ||
| - a governed criterion-set UUIDv4-shaped reference plus independent SHA-256 digest; | ||
| - a governed performance-goal-plan UUIDv4-shaped reference plus independent SHA-256 digest; | ||
| - an exact criterion-observation-snapshot UUIDv4-shaped reference plus independent SHA-256 digest; | ||
| - an optional development-plan UUIDv4-shaped reference/digest pair; | ||
| - explicit business review-period dates; | ||
| - one accountable UUIDv4-shaped reviewer, fixed `performance_review` purpose, and a reviewed closed reason code; | ||
| - a **system-owned** precision-preserving issuance timestamp read from the host clock inside the packet boundary, with no caller-supplied `generated_at` parameter; and | ||
| - a bounded positive integer `evidence_version`, defaulting to `1`, that is included in canonical evidence and therefore changes the packet digest when the governed evidence version changes. | ||
|
|
||
| The initial closed reason vocabulary contains only `scheduled_cycle_review`. Arbitrary lower-snake-case values are rejected even when syntactically well formed, because free-form reason text can encode a person name, identifier, or unreviewed decision context. Additional reasons require an explicit governed contract change and regression evidence before they can enter canonical review evidence. | ||
|
|
||
| `evidence_version` accepts only real integers from `1` through `2147483647`; booleans, text, zero, negative values, and overflow values fail closed. The field versions the immutable review evidence envelope and does not itself prove source-version resolution, human approval, or rating completion. | ||
|
|
||
| Because this package cannot prove independently supplied reference provenance, `contains_personal_data` and `contains_direct_person_identifiers` are both fixed to `True`. The latter is deliberately conservative: it means the envelope must be handled as potentially containing direct identifier content until an authoritative issuer/resolver verifies opacity. The packet MUST NOT carry a rating value, free-form feedback, or free-form model output. Those exclusions are machine-verifiable canonical evidence through fixed `contains_rating_value=False`, `contains_free_form_feedback=False`, and `contains_free_form_model_output=False`; mutation-by-copy that attempts to weaken any exclusion fails closed. Direct construction and mutation-by-copy MUST also fail closed unless `human_confirmation_required=True`, `decision_authority="human_review_only"`, `review_state="requires_human_review"`, and `scope_verification_state="requires_authoritative_resolution"` remain intact. | ||
|
|
||
| `scope_verification_state` deliberately cannot be changed to `verified` inside this package. Before rating, the authoritative HRIS/performance boundary must verify reference provenance and opacity, then resolve the Person↔Employment↔Job relation, performance-cycle/review-period alignment, and governed evidence scope using current temporal truth and purpose-bound authorization. UUIDv4 shape alone is not provenance evidence; tenant UUID generation/version/privacy policy likewise remains owned by the authoritative HRIS boundary. | ||
|
|
||
| `generated_at` is constructed from a trusted internal clock adapter. The resulting exact built-in timezone-aware `datetime` is normalized once to UTC and then sealed; future instants, missing/raising offsets, normalization overflow, datetime subclasses, or post-construction non-UTC reinjection fail closed. Tests may replace the internal clock adapter to make canonical bytes deterministic, but production callers cannot provide the issuance timestamp. | ||
|
|
||
| The process-local HMAC issuance seal is registered exactly once for each live packet identity. A separate weak live-issued-identity registry persists for the lifetime of the packet even if current seal bytes are discarded, so seal loss is a fail-closed export condition rather than permission to issue again. Re-entering `__post_init__()` on the same live object after seal loss or after a valid-value rewrite MUST fail before replacement evidence can be installed. Canonical export continues to compare the current deterministic bytes against the original external seal when that seal exists. This registry is in-process mutation defense only and is not a portable signature, distributed uniqueness service, authorization record, or durable audit/outbox substitute. | ||
|
|
||
| Canonical JSON and SHA-256 are immutable correlation evidence only. They do not prove the correctness of source evidence, authoritative cross-record scope, substantive validity or fairness of a criterion, lawful use, human completion, reference provenance, or the final rating. | ||
|
|
||
| ## Consequences | ||
|
|
||
| Buyers can present a review-ready correlation envelope while keeping authoritative Employment/Job and performance evidence separable from the later human rating/feedback event. The envelope itself now carries explicit canonical proof that rating values, free-form feedback, and free-form model output are excluded from this pre-rating evidence boundary. A consumer cannot truthfully treat the packet itself as proof that all referenced records belong to the same employee/job/cycle or that UUIDv4-shaped values are opaque. Until authoritative provenance verification occurs, the packet receives the more restrictive identifier-risk classification rather than a false no-direct-identifier assertion. | ||
|
|
||
| The system-recorded timestamp can no longer be backdated through public packet construction, and one live packet cannot renew its process-local issuance evidence after mutation or after losing its current seal bytes. Hosts still own purpose-bound authorization, durable immutable audit/outbox, retention/export controls, and the authoritative clock/runtime environment. | ||
|
|
||
| This slice adds no database migration, no rating computation, no cross-service table access, and no automated employment decision. The pre-rating packet preserves actor, purpose, reviewed reason, evidence version, conservative identifier-risk classification, system-recorded issuance time, and explicit content-exclusion flags in its immutable correlation evidence; later authoritative rating persistence must independently preserve those values plus human confirmation, audit/outbox, temporal scope, authoritative scope/provenance resolution evidence, and any applicable policy requirements. | ||
|
|
||
| ## References | ||
|
|
||
| See `docs/doctoring/performance-review-references.md`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Performance-review references | ||
|
|
||
| Retrieved August 19, 2026. These references support the active-PR governance boundary in ADR 0018. Orgmetra does not reproduce proprietary ISO text or claim certification. | ||
|
|
||
| International Organization for Standardization. (2025). *ISO 30414:2025 human resource management—Requirements and recommendations for human capital reporting and disclosure* (2nd ed.). https://www.iso.org/standard/30414 | ||
|
|
||
| U.S. Office of Personnel Management. (n.d.). *Performance management cycle*. Retrieved August 19, 2026, from https://www.opm.gov/policy-data-oversight/performance-management/performance-management-cycle/ | ||
|
|
||
| U.S. Office of Personnel Management. (n.d.). *Performance management roadmap: Best practices guide for supervisors*. Retrieved August 19, 2026, from https://www.opm.gov/policy-data-oversight/performance-management/performance-management-toolkit/best-practices/performance-management-roadmap-for-supervisors/ |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.