Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a5fe20b
test(offer-response): define exact coverage contract
seonghobae Aug 22, 2026
d96827e
test(offer-response): add RED candidate response regressions
seonghobae Aug 22, 2026
156ac03
ci(offer-response): add exact-head quality lane
seonghobae Aug 22, 2026
159a618
feat(offer-response): implement candidate-originated evidence boundary
seonghobae Aug 22, 2026
79e0588
feat(offer-response): publish governed response contract
seonghobae Aug 22, 2026
ba27d6f
fix(offer-response): remove unreachable timezone branch
seonghobae Aug 22, 2026
58f6081
docs(offer-response): explain candidate response boundary
seonghobae Aug 22, 2026
690bffc
docs(offer-response): record initial governed evidence slice
seonghobae Aug 22, 2026
891728a
docs(offer-response): add protected-truth traceability
seonghobae Aug 22, 2026
dae436b
docs(offer-response): record primary standards evidence
seonghobae Aug 22, 2026
f40c03c
test(offer-response): exercise final type without dead binding
seonghobae Aug 22, 2026
d68dd85
test(candidate-offer-response): reject rewritten creation seal
seonghobae Aug 22, 2026
57efd1d
fix(candidate-offer-response): move issuance seal outside writable pa…
seonghobae Aug 22, 2026
2de5495
test(candidate-offer-response): cover opaque identity references
seonghobae Aug 22, 2026
ccc2700
test(candidate-offer-response): isolate Keyverse actor contract
seonghobae Aug 22, 2026
cbd0f94
fix(candidate-offer-response): honor opaque Keyverse actor IDs
seonghobae Aug 22, 2026
06f1fee
docs(candidate-offer-response): align Keyverse actor contract
seonghobae Aug 22, 2026
a67c994
docs(candidate-offer-response): document OIDC subject semantics
seonghobae Aug 22, 2026
60dbc16
docs(candidate-offer-response): trace external actor ownership
seonghobae Aug 22, 2026
a6e0ad4
docs(candidate-offer-response): record identity contract repair
seonghobae Aug 22, 2026
38a66d2
test(candidate-response): require installed-wheel quality execution
seonghobae Aug 22, 2026
9f47a83
fix(candidate-response): test exact installed wheel hermetically
seonghobae Aug 22, 2026
2300c0a
docs(candidate-response): record installed-artifact quality contract
seonghobae Aug 22, 2026
71b9185
test(candidate-offer-response): reproduce checked-emitted snapshot race
seonghobae Aug 24, 2026
76ffd4c
fix(candidate-offer-response): emit the verified canonical snapshot
seonghobae Aug 24, 2026
274ba7c
docs(candidate-offer-response): record checked-snapshot integrity repair
seonghobae Aug 24, 2026
5070f34
docs(traceability): bind candidate response export to checked snapshot
seonghobae Aug 24, 2026
a0015c6
fix(candidate-offer-response): fail closed on cloned packet exports
seonghobae Aug 25, 2026
bfd068f
docs(traceability): bind shadow-rejection bar to host re-resolution
seonghobae Aug 25, 2026
a72463a
fix(talent): normalize offset overflow to the governed timestamp error
seonghobae Aug 25, 2026
b9d09ba
chore(talent): adopt protected develop non-destructively
seonghobae Sep 6, 2026
c62dd2c
fix(talent): consolidate candidate response quality lane
seonghobae Sep 6, 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
39 changes: 39 additions & 0 deletions .github/workflows/foundation-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,45 @@ 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 candidate offer response installed-artifact contract
run: |
printf '%s\n' 'setuptools==84.0.0 --hash=sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670' > /tmp/orgmetra-candidate-offer-response-build.txt
python -m pip install --require-hashes --no-deps --only-binary=:all: -r /tmp/orgmetra-candidate-offer-response-build.txt
rm -rf /tmp/orgmetra-candidate-offer-response-build /tmp/orgmetra-candidate-offer-response-dist /tmp/orgmetra-candidate-offer-response-venv
cp -a packages/candidate-offer-response /tmp/orgmetra-candidate-offer-response-build
mkdir -p /tmp/orgmetra-candidate-offer-response-dist
python -m pip wheel --no-deps --no-build-isolation --wheel-dir /tmp/orgmetra-candidate-offer-response-dist /tmp/orgmetra-candidate-offer-response-build
test "$(find /tmp/orgmetra-candidate-offer-response-dist -maxdepth 1 -type f -name '*.whl' | wc -l)" -eq 1
python -m venv /tmp/orgmetra-candidate-offer-response-venv
/tmp/orgmetra-candidate-offer-response-venv/bin/python -m pip install --require-hashes --no-deps --only-binary=:all: -r "$GITHUB_WORKSPACE/.github/requirements/foundation-test.txt"
wheel_path="$(find /tmp/orgmetra-candidate-offer-response-dist -maxdepth 1 -type f -name '*.whl' -print -quit)"
wheel_sha="$(sha256sum "$wheel_path" | awk '{print $1}')"
printf 'orgmetra-candidate-offer-response[test] @ file://%s --hash=sha256:%s\n' "$wheel_path" "$wheel_sha" > /tmp/orgmetra-candidate-offer-response-install.txt
/tmp/orgmetra-candidate-offer-response-venv/bin/python -m pip install --require-hashes --no-deps -r /tmp/orgmetra-candidate-offer-response-install.txt
/tmp/orgmetra-candidate-offer-response-venv/bin/python -m pip check
/tmp/orgmetra-candidate-offer-response-venv/bin/python - <<'PY'
from importlib.metadata import metadata
from pathlib import Path
import coverage
import pytest
import pytest_cov
import orgmetra_candidate_offer_response

venv_root = Path("/tmp/orgmetra-candidate-offer-response-venv").resolve()
module_path = Path(orgmetra_candidate_offer_response.__file__).resolve()
if not module_path.is_relative_to(venv_root):
raise SystemExit(f"package imported outside isolated environment: {module_path}")
for module in (coverage, pytest, pytest_cov):
dependency_path = Path(module.__file__).resolve()
if not dependency_path.is_relative_to(venv_root):
raise SystemExit(
f"test dependency imported outside isolated environment: {dependency_path}"
)
if "test" not in (metadata("orgmetra-candidate-offer-response").get_all("Provides-Extra") or []):
raise SystemExit("built distribution does not expose the reviewed test extra")
PY
cd /tmp
COVERAGE_FILE=/tmp/orgmetra-candidate-offer-response.coverage /tmp/orgmetra-candidate-offer-response-venv/bin/python -m pytest -c "$GITHUB_WORKSPACE/packages/candidate-offer-response/pyproject.toml" "$GITHUB_WORKSPACE/packages/candidate-offer-response/tests"
- name: Run owned unit and 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
Expand Down
33 changes: 33 additions & 0 deletions docs/doctoring/candidate-offer-response-references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Candidate Offer Response — Standards and Research Notes

## Evidence status

These references inform the candidate-response trust boundary. They do **not** claim that Orgmetra, an identity provider, or a customer deployment is NIST-certified, NIST-conformant, SOC 2 certified, or compliant with any employment law merely because the design cites them.

## Design implications

1. **Identity must be evidence, not a caller assertion.** NIST SP 800-63 Revision 4 is the current final Digital Identity Guidelines suite (July 2025) and treats identity proofing, authentication, federation, security, privacy, and customer experience as risk-managed digital identity functions. Orgmetra therefore records only an opaque candidate actor plus identity-resolution evidence and requires authoritative re-resolution before relying on the response.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
2. **Minimize candidate data at the response boundary.** NIST Privacy Framework 1.0 is a risk- and outcome-based enterprise privacy framework. The candidate-response packet excludes candidate PII, compensation values and free-form decline reasons because those values are unnecessary to prove the response event itself.
3. **Do not invent a UUID version for an external identity.** OpenID Connect Core defines `sub` as a case-sensitive, locally unique, never-reassigned subject string of at most 255 ASCII characters and relies on the `(iss, sub)` pair for stable cross-issuer identity. Keyverse protected-main product requirements likewise make exact `(identity_provider, subject)` the strongest matching evidence and require RPs to validate issuer and subject; they do not publish a UUIDv4-only subject contract. Orgmetra's protected Keyverse adapter therefore accepts a namespaced opaque `actor_reference`. Candidate-offer-response preserves that owner boundary: its `candidate_actor_reference` is bounded namespaced opaque text and is re-resolved authoritatively before consequential use.
4. **Packet-owned references keep their explicit identifier contract.** RFC 9562 is the current standards-track UUID specification and obsoletes RFC 4122. Orgmetra-owned packet/evidence correlation references in this slice use canonical non-sentinel UUIDv4 suffixes; the Orgmetra tenant identifier remains an authoritative operational UUID and may use the repository's UUIDv7 convention. The UUIDv4 rule is not projected onto the externally owned candidate actor.
5. **Acceptance is not employment authority.** Digital identity evidence establishes who acted; it does not establish that an approved offer is still eligible, unique, unsuperseded, or sufficient to create employment. Those facts stay at their authoritative Orgmetra boundaries and must be re-resolved before consequential mutation.

## APA 7 references

Davis, K., Peabody, B., & Leach, P. (2024). *Universally unique IDentifiers (UUIDs)* (RFC 9562). Internet Engineering Task Force. https://doi.org/10.17487/RFC9562

National Institute of Standards and Technology. (2020). *NIST Privacy Framework: A tool for improving privacy through enterprise risk management, version 1.0* (NIST CSWP 10). U.S. Department of Commerce. https://doi.org/10.6028/NIST.CSWP.10

Temoshok, D., Proud-Madruga, D., Choong, Y.-Y., Galluzzo, R., Gupta, S., LaSalle, C., Lefkovitz, N., & Regenscheid, A. (2025). *Digital identity guidelines* (NIST Special Publication 800-63-4). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-63-4

OpenID Foundation. (2014). *OpenID Connect Core 1.0 incorporating errata set 2*. https://openid.net/specs/openid-connect-core-1_0.html

## Primary-source verification

- CSRC records SP 800-63-4 with document date **July 2025** (`Date Published: July 2025`, document-history final entry `07/31/25`); NIST's public announcement of the final suite followed on August 1, 2025. The two dates refer to different events and are both retained here.
- Official CSRC author order for SP 800-63-4: David Temoshok, Diana Proud-Madruga, Yee-Yin Choong, Ryan Galluzzo, Sarbari Gupta, Connie LaSalle, Naomi Lefkovitz, Andrew Regenscheid. The APA entry preserves this exact order.
- NIST published final SP 800-63 Revision 4 in July 2025; it supersedes SP 800-63-3.
- NIST Privacy Framework 1.0 was published January 16, 2020 and remains the final 1.0 publication while newer Privacy Framework work is developed separately.
- RFC 9562 was published May 2024 as an IETF Standards Track RFC and obsoletes RFC 4122.
- OpenID Connect Core specifies `sub` as a case-sensitive string, not a UUID, and makes `(iss, sub)` the stable identity pair available to the relying party.
- Keyverse protected `main` documents exact `(identity_provider, subject)` matching and issuer/subject validation without a UUIDv4-only subject guarantee; Orgmetra does not mutate Keyverse to change that contract.
43 changes: 43 additions & 0 deletions docs/traceability/candidate-offer-response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Candidate Offer Response Traceability

## State legend

- **Protected-main truth**: already present on protected `develop` when this lane was cut.
- **Active PR**: implemented only on the candidate-offer-response branch until merged.
- **Dependency contract**: read-only interface owned elsewhere.
- **Out of scope**: intentionally not claimed by this slice.

## Requirement mapping

| Requirement | State | Evidence |
|---|---|---|
| Human offer approval is separate from candidate response | Protected-main truth | `packages/offer-approval`; ADR 0017 |
| Candidate-to-worker/confirmed-hire materialization is separately governed | Protected-main truth | `database/migrations/0009_candidate_worker_conversion_governance.sql`; People mutation boundary |
| Candidate response binds exact approved-offer and offer-terms digests | Active PR | `packages/candidate-offer-response/src/orgmetra_candidate_offer_response/response.py` |
| Acceptance and decline are both candidate-originated, closed-vocabulary evidence | Active PR | `response_code` allow-list plus adversarial tests |
| Employer-side shadow rejection is contractually barred, and the bar is enforced only by mandatory host-side re-resolution | Active PR | `candidate_actor_reference` and `identity_resolution_reference` are mandatory and no employer actor vocabulary exists, but the packet does not itself authenticate the candidate; fixed `scope_verification_state=requires_authoritative_resolution` makes consequential use without authoritative re-resolution a contract violation for downstream callers |
| Candidate actor correlation follows the published identity-owner boundary rather than an invented UUID version | Active PR + dependency contract | protected-main `packages/keyverse-adapter` accepts namespaced opaque actor references; `test_external_identity_reference_contract.py` proves a non-UUID Keyverse-compatible actor reference remains valid |
| Candidate response never directly authorizes hire or employment mutation | Active PR | fixed `employment_effect=not_authorized_to_hire`; governed `next_action` |
| Candidate identity is re-resolved before consequential downstream use | Active PR + dependency contract | fixed `scope_verification_state=requires_authoritative_resolution`; Keyverse remains read-only |
| Candidate PII, compensation values and free-form decline reasons are excluded | Active PR | fixed false sensitivity flags and canonical payload tests |
| Evidence preserves candidate response time and system-recorded time | Active PR | detached UTC `responded_at` / `recorded_at`; chronology regression |
| Caller-defined scalar/time subclasses cannot forge canonical evidence | Active PR | exact runtime type checks and hostile-subclass regressions |
| Post-construction rewriting invalidates evidence | Active PR | creation-time canonical digest seal plus mutation regressions |
| Canonical export emits the same snapshot that passed integrity validation | Active PR | `_assert_integrity()` returns the checked canonical bytes; `test_checked_snapshot_integrity.py` reproduces an interleaving valid-value rewrite and requires the previously checked snapshot to be emitted |
| Exact 100% owned statement/branch coverage | Active PR | canonical `.github/workflows/foundation-ci.yml` builds the candidate-offer-response wheel, installs it by exact SHA-256 into an isolated venv, and executes `packages/candidate-offer-response/tests`; `test_artifact_execution.py` keeps the retired leaf workflow from returning |
| Keyverse credentials or source state are never persisted here | Dependency contract | existing `packages/keyverse-adapter`; candidate-response packet stores opaque identity-resolution evidence only |
| Actual identity proofing/authentication assurance selection | Out of scope | authoritative identity owner / relying-party risk assessment |
| Offer eligibility, expiry, supersession and authoritative uniqueness | Out of scope for packet; required next step | owning talent-acquisition/offer workflow must re-resolve before action |
| Employment creation, assignment creation, compensation execution, offer delivery | Out of scope | existing owning HRIS boundaries |

## Architecture alignment

This slice does not introduce a new cross-service persistence path or a new architecture decision. It implements the existing Orgmetra principles in ADR 0001 (authoritative HRIS record), ADR 0006 (governed immutable audit/outbox evidence), ADR 0008 (purpose-bound PII authorization), and ADR 0017 (governed offer approval). It therefore adds no competing numbered ADR and does not edit the active canonical ADR index.

Keyverse remains read-only. The candidate actor is validated as a bounded namespaced opaque reference compatible with Orgmetra's protected-main Keyverse adapter; the response packet does not infer, rewrite, or constrain Keyverse's underlying OIDC `sub` to UUIDv4. `identity_resolution_reference` remains an Orgmetra-owned correlation reference with its explicit UUIDv4 contract and digest.

The candidate-response canonicalizer validates one payload snapshot against the process-local issuance seal and returns that same snapshot. It does not validate one read and then serialize the mutable object again. This preserves checked-versus-emitted audit integrity even if a same-process caller uses low-level mutation between those two phases; any later export from the changed packet still fails closed against the original issuance seal.

## Buyer outcome

A recruiter can no longer treat an approved offer as implicitly accepted, and an employer-side caller has no legitimate contract path to manufacture a decline through the candidate response: the packet carries opaque candidate identity evidence but never authenticates the candidate itself, so every consequential use must first re-resolve the authoritative identity boundary. The next actionable state is explicit: re-resolve candidate identity and exact offer scope, then use the owning employment boundary if and only if the response is verified as authoritative and eligible.
6 changes: 3 additions & 3 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": "f68fecb02c7ebbd6fb4b9d4befa852645e89d32cee8ff7f767dbb97c70f9a4ea",
"bytes": 9936,
"lines": 164
},
{
"path": ".gitignore",
Expand Down
14 changes: 14 additions & 0 deletions packages/candidate-offer-response/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog

## 0.1.0 - Unreleased

- Add candidate-originated `offer_accepted` / `offer_declined` evidence bound to exact offer approval and offer-terms digests.
- Require candidate actor and identity-resolution provenance while keeping Keyverse read-only.
- Preserve the published identity-owner contract by accepting a bounded namespaced opaque `candidate_actor_reference` instead of imposing an Orgmetra-invented UUIDv4 requirement on the external actor identity.
- Keep every response explicitly non-authorizing for hire, employment, compensation execution, or candidate-to-worker conversion.
- Exclude candidate PII, compensation values, free-form decline reasons, credentials, and model output from the evidence packet.
- Normalize recorded/responded instants to detached built-in UTC values, reject trust-bearing runtime subclasses, redact `repr`, and detect post-construction evidence rewriting.
- Bind canonical export to the exact snapshot that passed issuance-seal validation so an interleaving valid-value rewrite cannot become emitted audit evidence after the integrity check.
- Add exact 100% statement/branch coverage and exact-head CI for the owned package.
- Build a wheel and execute the quality suite against the SHA-256-bound installed artifact in a fully isolated virtual environment; install the reviewed hash-pinned pytest/coverage toolchain inside that environment and fail closed if package or test-tool imports resolve outside it.
- Retire the package-specific quality workflow after protected repository-workflow consolidation; preserve the same SHA-256-bound installed-wheel and isolated-toolchain contract inside the canonical one-job Foundation CI lane.
Loading
Loading