Skip to content

feat: add governed candidate withdrawal evidence - #67

Draft
seonghobae wants to merge 20 commits into
feat/normalized-candidate-applicationfrom
feat/governed-candidate-withdrawal
Draft

feat: add governed candidate withdrawal evidence#67
seonghobae wants to merge 20 commits into
feat/normalized-candidate-applicationfrom
feat/governed-candidate-withdrawal

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible gap

PR #66 deliberately removes bare withdrawn from raw candidate-application stage persistence because that shape cannot prove candidate initiation. This stacked lane adds the missing governed candidate-withdrawal boundary without reintroducing a staff-controlled shadow rejection.

Implemented withdrawal contract

The branch adds separate tenant-qualified, append-only candidate_withdrawal_record evidence rather than a raw pipeline stage. It binds candidate actor/identity-resolution provenance, withdrawal evidence version/digest, chronology, immutable audit/outbox correlation, one-withdrawal cardinality, and rejects staff-actor shadow rejection, evidence mismatch, duplicate withdrawal, destructive rewrite, and foreign-tenant visibility. candidate: syntax is correlation, not authentication; Keyverse remains read-only through the published identity contract.

Migration repair

The original withdrawal envelope extension edited already-deployed migration 0008, which would leave databases that had already applied 0008 with the legacy validator. That defect was repaired forward-only: current exact head ee5a56db3f64d972a08fab367fbed3f5005fa8f7 retains 0016_candidate_withdrawal_audit_envelope.sql, whose source explicitly extends the already-deployed validator without editing 0008.

test_candidate_withdrawal_migration_upgrade_postgres.sh proves the upgrade path: the legacy 0008 validator rejects a withdrawal envelope, then 0016 accepts it. The persistence and anti-forgery/tenant-isolation PostgreSQL contracts remain part of the current lane.

No dedicated-writer dependency repository is modified.

Exact-current-head state

  • Current exact head: ee5a56db3f64d972a08fab367fbed3f5005fa8f7.
  • Current stacked base / parent feat: normalize candidate application lifecycle #66: feat/normalized-candidate-application@04c60a6d485c1af32973959c37c9133ae928f59b.
  • GitHub reports the PR open, Draft, and mergeable. It remains dependency-blocked until feat: normalize candidate application lifecycle #66 integrates and this child is retargeted/revalidated against protected develop. The older non-Draft wording is superseded by the live lifecycle state; mechanical mergeability is not integration evidence.
  • Exact-head Candidate withdrawal PostgreSQL contract: run 33251808179, job 99098654692, terminal SUCCESS.
  • Exact-head Candidate withdrawal migration upgrade contract: run 33251808179, job 99098654852, terminal SUCCESS.
  • Current review-thread state: all withdrawal-lane findings are resolved except the ADR 0017/0025 manifest-provenance observation. That thread remains intentionally unresolved because the owning same-repository protected-truth repair is PR docs: reconcile canonical protected product truth #51, current head aa33f8f9f2a7c0a72c91947e3edac90334bcaabf, and docs: reconcile canonical protected product truth #51 has not integrated into protected develop.
  • No qualifying independent non-author approval is present. No predecessor check or review evidence transfers.

Stack and merge governance

Process PR #66 dependency-first. Independently, PR #51 must integrate before the inherited ADR 0017/0025 manifest-provenance thread can be revalidated and resolved here. After #66 integrates, retarget #67 to fresh protected develop, reconcile the then-current #51/protected truth and migration ordering with other active migration lanes, refetch exact head/base/rules/reviews/threads, and rerun every applicable Foundation, Recovery, Security/SAST, product-quality, OpenCode, Noema, Strix, provenance and approval gate on the resulting exact head. Parent, predecessor, status-only, or model-only evidence never transfers.

Do not self-approve, use routine administrator bypass, weaken a gate, race another writer, transfer predecessor evidence, or mutate a dedicated-writer dependency.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9de12e03-0949-4460-af0f-e83f648e1f25

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger 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.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 4 new potential issues.

Devin Review

Comment thread .github/workflows/candidate-withdrawal-quality.yml
Comment thread database/migrations/0015_candidate_withdrawal_governance.sql
Comment thread docs/adr/README.md Outdated
Comment thread docs/adr/README.md
Comment on lines +19 to +20
| [0017](0017-governed-offer-approval.md) | Governed offer approval evidence | Proposed |
| [0025](0025-governed-candidate-evidence-intake.md) | Governed candidate evidence intake | Proposed |

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: Indexed ADRs 0017/0025 are not manifest-tracked

The new index rows point at 0017 and 0025, which exist and carry 'Status: Proposed', so link and index checks pass. Neither appears in REQUIRED_FILES or manifest.json, so their contents are not integrity-tracked and can drift undetected. CI stays green because the drift check only compares those two sets.

Devin Review

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Verified against current #67 head 65d86274d3c244344feab6811f236ffdc6ffcb18: ADR 0017/0025 are inherited protected-develop documents, not withdrawal-lane files. The owning protected-truth repair is PR #51, current head e8d94fd039377af0dcf2c9e75094c977f2854aae, which now adds both ADRs to the Python/Node required inventories and regenerated manifest; its hosted suite is re-running. Leaving this thread unresolved until that owner lane is merged and #67 is retargeted/revalidated; no current #67 manifest coverage is claimed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Update against current protected-truth owner state: PR #51 is now at aa33f8f9f2a7c0a72c91947e3edac90334bcaabf; its required inventories and regenerated manifest include ADR 0017/0025, and its exact-head hosted suite is still running. This remains intentionally unresolved until #51 integrates and #67 is retargeted/revalidated against protected develop; no manifest coverage is claimed by #67 while it is based on the feature parent.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Lifecycle authority correction: #67 is now Draft. Parent #66 is still unintegrated and #67 also depends on #51’s protected-truth/ADR provenance repair before its inherited manifest-provenance observation can be revalidated. The body’s earlier non-draft lifecycle line is historical. Keep the valid forward-only withdrawal migration/evidence delta, process #66 and #51 dependency-first, then non-force reconcile this child to fresh protected develop and rerun all exact-head gates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant