-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add governed structured interview plan #40
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
229
commits into
develop
Choose a base branch
from
feat/structured-interview-plan
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
229 commits
Select commit
Hold shift + click to select a range
095b899
test: define structured interview plan quality contract
seonghobae f4da61d
test: add RED structured interview plan regressions
seonghobae 19a4a5f
feat: add governed structured interview plan
seonghobae 12566d6
feat: export structured interview plan contract
seonghobae 89cd211
docs: explain structured interview plan boundary
seonghobae fd89a19
docs: record structured interview plan slice
seonghobae 043e5b4
docs: doctor structured interview plan evidence
seonghobae 0dbba0f
docs: record structured interview plan decision
seonghobae 735c27d
docs: trace structured interview plan contract
seonghobae dac45f0
ci: add structured interview plan quality gate
seonghobae ee043e8
refactor: keep interview plan builder explicitly typed
seonghobae 91d9860
test: require question-to-competency mapping evidence
seonghobae e7a2a73
fix: bind questions to governed competency mapping evidence
seonghobae dd9f3aa
docs: bind interview questions to competency map evidence
seonghobae 66ddaac
docs: record competency mapping hardening
seonghobae eca3fa7
docs: require question competency map evidence
seonghobae 8c54d1f
docs: trace question competency mapping evidence
seonghobae 092dd77
test: require cardinality-only interview error
seonghobae 1e4ea43
fix: describe interview count constraint precisely
seonghobae ae03344
Merge branch 'develop' into feat/structured-interview-plan
opencode-agent[bot] 40c3cbf
merge: reconcile structured interview plan with current protected dev…
seonghobae de15f6d
merge: reconcile structured interview plan with latest protected develop
seonghobae 4b9633f
chore: reconcile structured interview plan with protected develop
seonghobae b8fd5be
test: reject value-bearing structured interview metadata
seonghobae 870908d
fix: close structured interview metadata privacy boundary
seonghobae d0de9ad
test: use opaque UUID interview plan fixtures
seonghobae 6eedc7b
docs: harden structured interview privacy guidance
seonghobae 5fa63bb
docs: record structured interview privacy boundary
seonghobae 62baef9
docs: trace structured interview privacy regressions
seonghobae fb42902
docs: record structured interview privacy hardening
seonghobae 8154e96
Merge branch 'develop' into feat/structured-interview-plan
github-actions[bot] 8093e76
test: require structured interview docstrings
seonghobae c60f900
docs: make structured interview regressions readable
seonghobae d9ffd07
chore: reconcile structured interview plan onto develop
seonghobae 7d67ed6
test: require structured interview evidence version
seonghobae f139416
fix: bind structured interview evidence version
seonghobae 9d76aa6
docs: trace structured interview evidence versions
seonghobae fd96303
merge develop into structured interview plan after #49
seonghobae 2fbb6bd
test: reject UUIDv1 interview trust references
seonghobae cd58ec6
fix: require UUIDv4 interview trust references
seonghobae ac8a37c
docs: record UUIDv4 trust-reference boundary
seonghobae 5cb75af
test: require tenant-scoped interview resolution
seonghobae 39a5744
fix: require authoritative interview plan resolution
seonghobae 1dc200b
docs: explain authoritative interview activation checks
seonghobae cfbf1d6
docs: record authoritative interview resolution boundary
seonghobae c1320d5
docs: trace authoritative interview activation evidence
seonghobae 2955b57
docs: record authoritative interview activation hardening
seonghobae 1ceca52
chore: reconcile interview plan onto restored develop
seonghobae 09a3b8e
test: require honest interview activation traceability
seonghobae 277bf47
docs: correct structured interview activation evidence boundary
seonghobae ff49751
test: reject correlating tenant UUIDv1 in interview plans
seonghobae 2b320b2
fix: require opaque UUIDv4 tenant identity in interview plans
seonghobae 01a7c3a
docs: bind interview-plan tenant identity to UUIDv4 opacity
seonghobae e4f388a
docs: require UUIDv4 tenant opacity in interview-plan ADR
seonghobae 6261180
docs: trace UUIDv4 tenant opacity in interview plans
seonghobae 9751d45
docs: record interview-plan tenant UUIDv4 hardening
seonghobae b4a0a56
Merge remote-tracking branch 'refs/remotes/origin/develop' into HEAD
seonghobae b0f1e18
test: require interview plans to accept canonical tenant UUIDv7
seonghobae 456e548
fix: honor authoritative tenant UUID contract in interview plans
seonghobae b9cf166
docs: align interview tenant identity with Orgmetra core
seonghobae 887c7c9
docs: separate tenant and packet UUID ownership
seonghobae ed90333
docs: trace authoritative tenant UUID interoperability
seonghobae e199842
docs: record tenant identity interoperability repair
seonghobae aee7389
chore: integrate protected develop into interview-plan lane
seonghobae 211ce77
chore: reconcile structured interview plan with current develop
seonghobae 4a274fe
test(interview-plan): expose duplicate ADR numbering
seonghobae b2da11c
fix(interview-plan): renumber ADR after job-analysis integration
seonghobae 50540d5
test(interview-plan): require executable governed activation
seonghobae f69553f
feat(interview-plan): execute fail-closed human activation
seonghobae 460c4e4
feat(interview-plan): export governed activation contracts
seonghobae 69aa96b
test(interview-plan): satisfy executable docstring contract
seonghobae 6e2fc73
docs(interview-plan): document executable activation boundary
seonghobae 47197a0
docs(traceability): bind structured interview activation evidence
seonghobae 953aa86
docs(adr): record executable activation decision
seonghobae 48bc773
docs(changelog): record governed activation receipt
seonghobae 2931805
test(interview-plan): align traceability regression with activation b…
seonghobae 4e6d294
fix(interview-plan): remove unused receipt import
seonghobae 09f88be
fix(interview-plan): remove protocol no-op expression
seonghobae ed3e99f
chore(interview-plan): integrate protected develop after #41
seonghobae 867cb11
test(interview-plan): reject pre-generation approval evidence
seonghobae b3b5542
fix(interview-plan): enforce activation time ordering
seonghobae af5d7b2
docs(interview-plan): document activation chronology guard
seonghobae eddc92b
docs(interview-plan): record temporal integrity repair
seonghobae d4afadf
docs(interview-plan): trace activation chronology invariant
seonghobae 6e6cc4f
test(interview-plan): prove temporal guard precedes authority
seonghobae d641400
test(interview): reject unvalidated activation plan objects
seonghobae 0292790
fix(interview): require validated activation plan type
seonghobae 049205d
docs(interview): document activation plan type boundary
seonghobae a2135d6
docs(interview): record activation plan type repair
seonghobae c8cfe76
docs(interview): trace validated activation plan boundary
seonghobae 1f30abb
docs(interview): record exact activation plan type decision
seonghobae 58f84fd
fix(interview-plan): remove unreachable protocol statement
seonghobae 0476132
chore(interview-plan): integrate protected develop after #43
seonghobae 656a374
test(interview-plan): bind approval time to authority
seonghobae e516cb5
fix(interview-plan): verify approval time at authority boundary
seonghobae 33ecde8
test(interview-plan): adapt authority fixtures to approval time
seonghobae 260ace0
test(interview-plan): align authority fixture contract
seonghobae 42a6a28
docs(interview-plan): bind approval instant to authority
seonghobae 680f977
docs(interview-plan): trace authoritative approval-time binding
seonghobae 4ab7b82
docs(interview-plan): record authority-bound approval time
seonghobae 11838bc
docs(interview-plan): record approval-time verification repair
seonghobae a4f5c55
test(interview-plan): reject recorded-time subclasses
seonghobae 6afb318
fix(interview-plan): require exact recorded-time type
seonghobae 138073d
test(interview-plan): align traceability activation regression
seonghobae 1cb7dc5
test(interview-plan): reject forged string evidence types
seonghobae 9cadc9f
fix(interview-plan): require exact string evidence types
seonghobae c944722
test(interview-plan): reject forged governance codes
seonghobae 58eba76
fix(interview-plan): require exact governance-code text
seonghobae e1a2035
test(interview-plan): document runtime integrity regressions
seonghobae 09a8fd4
test(interview-plan): name invalid approval timestamp
seonghobae d4a6ed6
refactor(interview-plan): make timestamp diagnostics field-aware
seonghobae f770a5f
fix(interview-plan): report approval timestamp failures precisely
seonghobae d26e5a7
test(interview-plan): require authoritative receipt issuance
seonghobae 68a977f
fix(interview-plan): require authoritative receipt issuance
seonghobae 70c9cce
test(interview-plan): reject receipt scope replacement
seonghobae a0d52aa
fix(interview-plan): consume receipt issuance capability
seonghobae febd6fe
test(interview-plan): require redacted verification repr
seonghobae 2a83d9a
fix(interview-plan): redact activation verification repr
seonghobae 2a662c0
test(interview-plan): reject mutable verification subclasses
seonghobae d8002d8
fix(interview-plan): require exact verification evidence type
seonghobae 8a88fd4
test(interview-plan): reject forged verification scope strings
seonghobae e32ba5e
fix(interview-plan): require exact digest runtime type
seonghobae 2d4945f
fix(interview-plan): validate exact authority scope evidence
seonghobae 428b439
test(interview-plan): expose runtime evidence subclass forgery
seonghobae d6f32a6
fix(interview-plan): require exact canonical evidence containers
seonghobae 050522a
docs(interview-plan): record canonical runtime-type hardening
seonghobae 8aaf0b7
docs(traceability): bind exact runtime evidence types
seonghobae 3c388a4
test(interview-plan): reject authority-time plan mutation
seonghobae d57cb69
fix(interview-plan): freeze plan evidence across authority call
seonghobae ae43337
docs(interview-plan): record authority-call snapshot integrity
seonghobae 1e70ba4
docs(traceability): bind pre-authority plan snapshot
seonghobae ef8c4f7
docs(adr): close activation plan-mutation TOCTOU
seonghobae 8d8896b
test(traceability): require activation snapshot evidence
seonghobae 06637b8
test(interview-plan): reject rewritten activation receipts
seonghobae ab299c3
fix(interview-plan): bind receipts to issuance evidence
seonghobae 8eb3a26
docs(interview-plan): trace receipt issuance integrity
seonghobae c907958
docs(interview-plan): record receipt integrity repair
seonghobae c678ad4
docs(interview-plan): define creation-bound receipt integrity
seonghobae 072596e
test(interview-plan): expose post-issuance plan mutation
seonghobae ae291c6
fix(interview-plan): bind plan canonical evidence to issuance
seonghobae 7a131cb
test(interview-plan): cover missing plan issuance evidence
seonghobae ee0791a
test(interview-plan): align authority mutation with plan seal
seonghobae b3ad9ce
test(interview-plan): cover plan seal cleanup fail-closure
seonghobae 01c26f4
docs(interview-plan): record creation-bound plan integrity
seonghobae 46a4bf3
docs(adr): bind structured interview plan issuance integrity
seonghobae 33d700d
docs(traceability): cover creation-bound interview plans
seonghobae ae6a511
docs(interview-plan): explain creation-bound plan evidence
seonghobae d3cfc89
fix(interview-plan): remove obsolete mutation branch
seonghobae a750b11
test(interview-plan): make traceability assertion semantic
seonghobae 2ac8894
test(interview-plan): expose activation integrity review findings
seonghobae cb38632
fix(interview-plan): make plan issuance seal single-registration
seonghobae b4b0150
fix(interview-plan): snapshot activation authority evidence
seonghobae 0fef690
test(interview-plan): bind verification to approval instant
seonghobae 927f2a2
test(interview-plan): attest reviewed approval time
seonghobae 21fe4d9
test(interview-plan): keep mutation fixture contract-current
seonghobae 76e9bac
test(interview-plan): keep type fixture contract-current
seonghobae b043b14
test(interview-plan): cover detached time and authority snapshots
seonghobae c3e3b65
docs(interview-plan): document detached activation evidence
seonghobae ba026ad
docs(interview-plan): record activation snapshot hardening
seonghobae db1ab58
docs(adr): define detached activation evidence boundary
seonghobae aae5006
docs(traceability): bind exact approval-time evidence
seonghobae 52ae7df
test(interview-plan): bind traceability assertions to contract
seonghobae f3e8f23
test(interview-plan): prove immutable activation evidence boundaries
seonghobae ad83893
fix(interview-plan): detach activation evidence from runtime aliases
seonghobae 1d90738
docs(interview-plan): align immutable activation evidence contract
seonghobae fc846e5
test(interview-plan): track detached activation traceability
seonghobae 79b890b
test(interview-plan): reproduce mutable generated-time drift
seonghobae c476e91
fix(interview-plan): detach generated time before sealing
seonghobae 6e923b3
docs(interview-plan): document generated-time detachment
seonghobae afc323a
docs(interview-plan): record generated-time integrity repair
seonghobae 296b0fb
docs(adr): bind plan generation time to UTC snapshot
seonghobae 2afcb01
docs(traceability): bind generated time to mutable-timezone regression
seonghobae 460ed3c
test(interview-plan): reproduce UTC boundary overflow
seonghobae 8878353
fix(interview-plan): fail closed on UTC range overflow
seonghobae 054c3a7
fix(interview-plan): normalize approval range overflow
seonghobae 3651948
docs(interview-plan): document UTC range fail-closure
seonghobae 07b3bca
docs(adr): fail closed on unrepresentable UTC instants
seonghobae 40a391a
docs(traceability): bind UTC boundary overflow regressions
seonghobae b7535b3
docs(interview-plan): record UTC boundary validation repair
seonghobae 32f5211
test(interview-plan): reproduce receipt seal renewal
seonghobae 7911661
fix(interview-plan): preserve receipt issuance seal
seonghobae 3fd52e3
docs(interview-plan): record receipt single-registration seal
seonghobae a9ccc1e
docs(interview-plan): document receipt seal single registration
seonghobae 885d787
docs(adr): prevent activation receipt seal renewal
seonghobae c67c869
docs(traceability): bind receipt seal renewal regression
seonghobae 1a8a3cf
test(interview-plan): fail closed on hostile tzinfo evaluation
seonghobae 7a02138
fix(interview-plan): normalize hostile plan timezone failures
seonghobae b023bc4
fix(interview-plan): normalize hostile activation timezone failures
seonghobae 602f33e
test(interview-plan): normalize receipt timezone failures
seonghobae f54bfd7
fix(interview-plan): normalize canonical timestamp failures
seonghobae a4342c0
docs(interview-plan): record timezone trust-boundary repair
seonghobae 49b05e0
docs(interview-plan): explain untrusted timezone handling
seonghobae 5678d8b
docs(traceability): bind hostile timezone regressions
seonghobae 34b20d8
docs(adr): treat timezone implementations as untrusted
seonghobae b84b57e
test(interview-plan): reject direct receipt minting with private sent…
seonghobae 5ab76c1
fix(interview-plan): bind receipt issuance to verified factory
seonghobae 4346c2c
test(interview-plan): require factory issuance for receipt export
seonghobae 61ca1fe
docs(interview-plan): document factory-bound receipt issuance
seonghobae 53b4010
docs(interview-plan): record verified-factory issuance repair
seonghobae f28556a
docs(traceability): bind receipt issuance to verified factory
seonghobae e115b86
docs(adr): make receipt issuance factory-bound
seonghobae 4c25757
test(interview-plan): require supported Python compatibility lanes
seonghobae 199be0c
build(interview-plan): pin coverage wheels for supported Python minors
seonghobae b428ed7
ci(interview-plan): test every supported Python minor
seonghobae fdf36e9
test(interview-plan): preserve factory receipt seal across revalidation
seonghobae 1628b5d
test(interview-plan): hide receipt issuance capabilities from module …
seonghobae ebadac3
fix(interview-plan): encapsulate receipt issuance authority
seonghobae 10fecfc
test(interview-plan): verify receipt reseal fail-closed through publi…
seonghobae c858c3e
fix(interview-plan): remove unreachable receipt reseal branch
seonghobae bd4d0cf
fix(interview-plan): preserve approval evidence field contract
seonghobae bf8897a
fix(ci): validate logical hashed requirements
seonghobae cb3b2a0
test(foundation): reproduce pipefail package lookup failure
seonghobae 540b585
fix(foundation): make package lookup pipefail-safe
seonghobae 242b088
test(interview-plan): reject constructor-bypassing issuance clone
seonghobae 768b628
fix(interview-plan): bind issuance to constructor provenance
seonghobae c58fea3
docs(interview-plan): record constructor provenance boundary
seonghobae eea011a
docs(interview-plan): trace issuance provenance repair
seonghobae fe8a588
test(interview-plan): cover duplicate seal fail-closure
seonghobae c971494
test(interview-plan): reject direct class allocator issuance
seonghobae 82b73d0
fix(interview-plan): gate issuance on full class construction
seonghobae a451072
docs(interview-plan): trace allocator provenance repair
seonghobae e367580
docs(interview-plan): define full-constructor provenance
seonghobae 032de12
docs(interview-plan): trace full-constructor issuance proof
seonghobae ab035c4
test(interview-plan): reproduce timezone provenance reentrancy
seonghobae f7ca68b
fix(interview-plan): consume constructor provenance before callbacks
seonghobae 78e7542
docs(interview-plan): document one-shot constructor provenance
seonghobae 22551cc
docs(interview-plan): record reentrant constructor boundary
seonghobae da4162c
docs(interview-plan): changelog timezone reentrancy repair
seonghobae 6917e41
docs(interview-plan): trace timezone provenance reentrancy
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
|
devin-ai-integration[bot] marked this conversation as resolved.
|
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,104 @@ | ||
| name: Structured Interview Plan Quality | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: | ||
| - develop | ||
| paths: | ||
| - "packages/interview-plan/**" | ||
| - ".github/requirements/foundation-test.txt" | ||
| - ".github/workflows/interview-plan-quality.yml" | ||
| - ".gitignore" | ||
| - ".python-version" | ||
| - "conftest.py" | ||
| - "packages/conftest.py" | ||
| - "pyproject.toml" | ||
| - "pytest.ini" | ||
| - "setup.cfg" | ||
| - "tox.ini" | ||
| - "docs/adr/0015-governed-structured-interview-plan.md" | ||
| - "docs/doctoring/structured-interview-plan-references.md" | ||
| - "docs/traceability/structured-interview-plan.md" | ||
| workflow_dispatch: | ||
|
seonghobae marked this conversation as resolved.
|
||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: structured-interview-plan-quality-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| unit: | ||
| name: Structured interview plan 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" | ||
|
devin-ai-integration[bot] marked this conversation as resolved.
|
||
| 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 structured interview plan package | ||
| run: python -m compileall -q packages/interview-plan/src packages/interview-plan/tests | ||
| - name: Test structured interview plan with exact statement and branch coverage | ||
| env: | ||
| PYTHONPATH: packages/interview-plan/src | ||
| COVERAGE_FILE: /tmp/orgmetra-structured-interview-plan.coverage | ||
| run: python -m pytest -c packages/interview-plan/pyproject.toml packages/interview-plan/tests | ||
| - name: Require clean checkout | ||
| run: | | ||
| git diff --exit-code | ||
| test -z "$(git status --porcelain)" | ||
|
seonghobae marked this conversation as resolved.
|
||
|
|
||
| compatibility: | ||
| name: Python ${{ matrix.python-version }} compatibility and 100% coverage | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.12", "3.13"] | ||
| 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: ${{ matrix.python-version }} | ||
| 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 structured interview plan package | ||
| run: python -m compileall -q packages/interview-plan/src packages/interview-plan/tests | ||
| - name: Test supported Python with exact statement and branch coverage | ||
| env: | ||
| PYTHONPATH: packages/interview-plan/src | ||
| COVERAGE_FILE: /tmp/orgmetra-structured-interview-plan-${{ matrix.python-version }}.coverage | ||
| run: python -m pytest -c packages/interview-plan/pyproject.toml packages/interview-plan/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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| # ADR 0015: Govern structured-interview plans as candidate-neutral evidence | ||
|
|
||
| - **Status:** Proposed — active PR only | ||
| - **Date:** 2026-08-18 | ||
|
|
||
| ## Context | ||
|
|
||
| Orgmetra already separates authoritative Job/Position/Assignment truth, governed requisition review, selection evidence, and accountable human employment decisions. A buyer still needs a defensible boundary between an approved opening and the interview that will be used as a selection procedure. | ||
|
|
||
| A structured interview is stronger when assessed competencies come from current job analysis, candidates receive the same predetermined questions, and responses are evaluated against common rating standards. A question count cannot prove that each governed competency is represented, so the approved question-to-competency mapping needs its own immutable evidence identity. Candidate identity, assessment values, and semantic/value-bearing labels are unnecessary at this pre-use boundary and would increase privacy risk. Packet-owned trust references therefore use UUIDv4; the authoritative tenant identifier instead follows Orgmetra core's canonical non-sentinel operational UUID contract. | ||
|
|
||
| Opaque identities and artifact digests identify evidence but do not prove tenant ownership, requisition-to-Job-to-job-analysis relationships, or distinct human identities. Those relationships must be re-resolved at authoritative owner boundaries immediately before activation. A prose-only `next_action` is insufficient: the package needs an executable host boundary that cannot issue activation evidence when authoritative checks reject or when returned verification evidence belongs to another plan, actor, or approval instant. | ||
|
|
||
| Plan-generation time and approval time are trust-bearing evidence. Caller-controlled mutable timezone state must not make one governed instant later represent a different UTC instant. Caller-owned `tzinfo` implementations are executable code and may raise arbitrary exceptions while `utcoffset()` is evaluated; such failures and unrepresentable UTC normalization must become field-specific governed validation before plan issuance, authority side effects, verification acceptance, or canonical export. Constructor provenance must also not remain ambient while such caller code runs: otherwise a reentrant timezone callback can invoke the plan allocator, retain a second object that inherits constructor eligibility, populate it later with otherwise valid fields, and mint issuance evidence without a normal class construction. | ||
|
|
||
| Python `frozen=True` is not an adversarial immutability or authorization boundary. `object.__setattr__` can rewrite dataclass fields, and low-level allocation can create a dataclass-shaped instance without completing its governed constructor. Merely executing a class `__new__` method is also not proof of construction because callers can invoke that allocator directly. A module-private constructor token is still reachable by Python callers. Therefore receipt shape construction must not itself confer human-approval authority, and plan issuance must prove that the exact live object entered through the normal full `StructuredInterviewPlan(...)` construction path before `__post_init__` may register creation evidence. Plan construction may register process-local integrity evidence because construction is the governed plan-issuance boundary, but activation-receipt issuance evidence must be registered only by the verified activation factory after authoritative host checks and exact-scope matching have completed. | ||
|
|
||
| ## Decision | ||
|
|
||
| Add a transport-neutral `StructuredInterviewPlan` value object that binds: | ||
|
|
||
| - canonical non-sentinel Orgmetra tenant identity and one UUIDv4-backed opaque interview-plan reference; | ||
| - UUIDv4-backed requisition and authoritative Job references; | ||
| - exact job-analysis, question-set, question-to-competency mapping, and rating-anchor references plus independent SHA-256 digests; | ||
| - sorted, unique job-related competency references and a bounded 2–8 actor interviewer panel; | ||
| - a bounded question count at least as large as the governed competency count, while the separately bound mapping artifact supplies actual coverage evidence; and | ||
| - fixed purpose `structured_interview_plan`, closed reason `approved_requisition_interview`, bounded positive `evidence_version`, precision-preserving UTC time, mandatory human confirmation, and `requires_human_approval` state. | ||
|
|
||
| `tenant_record_id` follows the authoritative operational UUID contract. Packet-owned trust-bearing references require canonical non-sentinel UUIDv4 plus their expected namespace. Names, labels, compensation/protected-attribute values, and other semantic suffixes fail closed. Direct construction, builder construction, and `dataclasses.replace(...)` share the same plan validation. `evidence_version` is serialized canonically and changes immutable SHA-256 correlation when revised. Routine plan representation is fully redacted. | ||
|
|
||
| Before plan issuance evidence is registered, detach caller-owned `generated_at` into one built-in UTC `datetime` using one concrete offset read from the original aware value. Treat offset evaluation as an untrusted-code boundary: exceptions and offset arithmetic beyond Python's representable `datetime` range become the same field-specific `ValueError`. Store the built-in UTC snapshot rather than caller-owned `tzinfo` state. Canonical timestamp rendering reuses this fail-closed detachment. | ||
|
|
||
| A private metaclass arms a context-local **one-shot allocator ticket** immediately before the normal `StructuredInterviewPlan(...)` class construction. The exact `StructuredInterviewPlan.__new__()` invocation consumes that ticket before any field validation, `tzinfo.utcoffset()` call, or other caller-controlled callback can execute, then records construction eligibility only for that exact live object. Successful `__post_init__()` requires and consumes that provenance, computes a process-local HMAC over the canonical plan payload, registers the seal outside plan-writable slots, and records the exact identity as issued. Registration remains single-use for one live plan identity. `canonical_json()` requires exact issued-identity membership plus creation-bound HMAC evidence and uses constant-time comparison before returning bytes; `sha256_digest()` is downstream. An `object.__new__` clone, direct `StructuredInterviewPlan.__new__(StructuredInterviewPlan)` allocation, or allocator call reached reentrantly from caller-owned timezone code cannot call `__post_init__()` to mint fresh issuance evidence because none receives or retains the already-consumed constructor ticket. Low-level mutation, copied/reconstructed identities, missing issuance evidence, and attempted plan resealing fail closed. These context/identity/HMAC controls are same-process integrity evidence only, not a hostile-interpreter capability boundary, persisted signing scheme, portable signature, or replacement for immutable audit/outbox evidence. | ||
|
|
||
| Make authoritative activation executable through `StructuredInterviewActivationAuthority` and `activate_structured_interview_plan(...)`. Before authority work, activation requires the exact governed `StructuredInterviewPlan` runtime type, obtains creation-bound canonical plan JSON, derives tenant/interview-plan scope and SHA-256 from those bytes, detaches caller-owned `approved_at` into built-in UTC, validates the approving actor, and rejects chronology before plan generation. The authority receives only detached canonical plan JSON, its exact digest, approving actor, and normalized approval instant—never the live plan object. A retained alias therefore cannot change what the authority reviews through a temporary change-and-restore cycle; non-restored mutation is still rejected by the post-authority plan integrity check. | ||
|
|
||
| Implement `StructuredInterviewActivationVerification` as an exact `NamedTuple` carrying tenant, interview-plan reference, plan digest, approving actor, authority-evidence reference/digest, and reviewed `approved_at`. Activation rejects subclasses, unpacks the exact tuple once, normalizes returned approval time through the same fail-closed UTC helper, validates returned values, and compares the complete tenant/plan/digest/actor/time scope against the pre-call request. | ||
|
|
||
| `StructuredInterviewActivationReceipt` is a value-minimized receipt shape, not an authorization primitive. Its dataclass constructor validates tenant/reference/digest/time/fixed-governance values but **does not register issuance evidence**. Direct construction and `dataclasses.replace(...)` therefore produce unissued values whose `canonical_json()` and `sha256_digest()` fail closed. The constructor has no issuance-token parameter; a module-private legacy sentinel confers no authority and is retained only as a regression target proving that callers cannot mint issued receipts by importing a private module attribute. | ||
|
|
||
| Only after `activate_structured_interview_plan(...)` has accepted exact verification evidence, normalized the returned approval instant, validated all returned fields, and matched tenant, interview-plan reference, plan digest, approving actor, and approval time does it construct the receipt and register a process-local HMAC seal over that exact canonical payload. Issued receipt canonical export recomputes and constant-time compares the seal. Any low-level post-issuance rewrite or missing issuance evidence fails closed. The seal is same-process integrity evidence only; it is not a durable signing key, portable attestation, cross-process rehydration credential, or substitute for the host's immutable audit/outbox record. | ||
|
|
||
| The issued receipt records the exact plan digest, accountable UUIDv4 approving actor, authority-verification reference/digest, fixed purpose `structured_interview_activation`, fixed reason `human_approved_plan_activation`, bounded positive evidence version, detached precision-preserving UTC approval time, `human_confirmation=True`, and fixed `approved_for_use` state. Routine receipt and verification representations are fully redacted. The plan and receipt remain candidate-neutral: they contain no candidate identity, response, score, demographic attribute, compensation value, free-form model output, provider credential, or final selection recommendation. | ||
|
|
||
| ## Consequences | ||
|
|
||
| ### Positive | ||
|
|
||
| - Buyers can prove which Job Analysis, competencies, questions, mapping, rating anchors, panel, and evidence revision were reviewed before candidate use. | ||
| - Caller-controlled timezone failures and mutable timezone state cannot silently redefine governed plan or approval instants. | ||
| - Constructor-bypassing `object.__new__` clones, direct class-allocator calls, and reentrant allocator calls from caller-owned timezone callbacks cannot mint creation-bound plan issuance evidence merely by copying valid fields and invoking `__post_init__()`. | ||
| - The authoritative adapter reviews detached creation-bound plan evidence rather than a caller-owned live plan object. | ||
| - Authority verification fields are tuple-immutable at runtime and exact-type checked before one-time unpacking. | ||
| - A caller cannot mint an `approved_for_use` evidence artifact by importing a private constructor sentinel: direct and replaced receipt values remain unissued and cannot export canonical evidence. | ||
| - Receipt issuance is causally ordered after authoritative host verification and exact tenant/plan/digest/actor/time matching. | ||
| - Post-issuance receipt mutation and missing process-local issuance evidence fail closed before canonical export. | ||
| - Candidate PII and assessment values remain outside planning and activation artifacts. | ||
| - The authority protocol preserves standalone operation and later MSA extraction without cross-service application-table SQL or duplicated foreign-service state. | ||
|
|
||
| ### Costs and constraints | ||
|
|
||
| - The package does not persist requisitions, Job Analysis, interview questions/mappings, responses, scores, or authoritative relationship-resolution results. | ||
| - The authority protocol is not proof that a concrete production adapter performs tenant/database/API checks correctly; production adapters still need executable integration evidence and immutable authority/audit records. | ||
| - Plan and activation-receipt HMAC seals and live-identity provenance exist only for the lifetime of their in-process objects. They are not portable signatures, durable verification credentials, or key-management facilities. | ||
| - Directly constructed receipt values are intentionally unusable as authoritative evidence until a supported future rehydration/issuance contract exists. | ||
| - Human approval remains mandatory; model output cannot activate or approve the plan. | ||
| - UUID/digest metadata and reference inequality do not establish tenant ownership, identity separation, scientific validity, fairness, or legal compliance. | ||
| - This ADR remains proposed until its exact PR head merges into protected `develop`. | ||
|
|
||
| ## References | ||
|
|
||
| See `docs/doctoring/structured-interview-plan-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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Structured interview plan references | ||
|
|
||
| These sources inform the active-PR structured-interview planning contract. They do not establish certification or replace organization-specific legal review, job analysis, validation, or adverse-impact monitoring. | ||
|
|
||
| ## APA 7 references | ||
|
|
||
| International Organization for Standardization. (2023). *ISO 30405:2023 human resource management — Guidelines on recruitment* (2nd ed.). https://www.iso.org/standard/79488.html | ||
|
|
||
| U.S. Equal Employment Opportunity Commission. (1979, March 1). *Questions and answers to clarify and provide a common interpretation of the Uniform Guidelines on Employee Selection Procedures*. https://www.eeoc.gov/laws/guidance/questions-and-answers-clarify-and-provide-common-interpretation-uniform-guidelines | ||
|
|
||
| U.S. Office of Personnel Management. (n.d.). *Structured interviews*. Retrieved August 18, 2026, from https://www.opm.gov/policy-data-oversight/assessment-and-selection/structured-interviews/ | ||
|
|
||
| U.S. Office of Personnel Management. (n.d.). *How do I select the competencies, or content areas, I want to assess with the structured interview?* Retrieved August 18, 2026, from https://www.opm.gov/frequently-asked-questions/assessment-policy-faq/structured-interviews/how-do-i-select-the-competencies-or-content-areas-i-want-to-assess-with-the-structured-interview/ | ||
|
|
||
| ## Applied boundary | ||
|
|
||
| OPM describes structured interviews as standardized, job-related assessment methods using predetermined questions and common rating standards, with competencies selected from job analysis and confirmed by subject-matter experts. The UGESP guidance emphasizes documenting job relatedness and the basis for selection procedures. ISO 30405:2023 provides current recruitment-process guidance covering assessment and stakeholder management. Orgmetra therefore binds the interview plan to exact job-analysis evidence, predetermined question/rating artifacts, and accountable human review before candidate use. |
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.