Skip to content

feat(bap): bind lifecycle receipts to idempotency keys - #211

Open
seonghobae wants to merge 52 commits into
mainfrom
feat/bap-idempotency-receipt-contract
Open

feat(bap): bind lifecycle receipts to idempotency keys#211
seonghobae wants to merge 52 commits into
mainfrom
feat/bap-idempotency-receipt-contract

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible boundary

Bounded implementation of #200. Prerequisite #208 is merged, and this canonical branch has been non-destructively reconstructed directly onto current protected main while preserving the idempotency/recovery production boundary.

  • protected main: 542ca1e9c0a863595b8b6697790005d2471f5413;
  • exact current branch head: 52a918577958a5701e1146c7eb8b62fe8f8ccd44;
  • live compare against protected main: 52 ahead / 0 behind, merge base exactly protected main;
  • diff remains limited to the intended BAP receipt/recovery source, regression-test, architecture, API/TRD, traceability, and changelog boundary.

The BAP lifecycle owns an immutable in-memory command receipt binding a bounded caller-supplied tenant namespace, idempotency key, task identifier, lifecycle event, and accepted transition. Exact replay requires exact retry metadata and exact equality with the lifecycle's most recently accepted transition. Ambiguous, stale, foreign, divergent-history, or state-only restored snapshots fail closed without a second lifecycle mutation.

This branch exposes storage-neutral typed seams needed to reconstruct both sides of that replay identity from persisted primitive fields: BapTaskTransition::restore(...) revalidates an accepted transition against the lifecycle state machine; BapTaskLifecycle::restore_with_transition(...) requires exact validated last-transition evidence for every non-created snapshot; and BapCommandReceipt::restore(...) revalidates bounded retry identifiers before reconstructing the immutable receipt. The persistence boundary remains responsible for integrity/authenticity of supplied evidence and for atomicity with any external side effect.

Test-first repair lineage

The receipt/recovery contract covers exact retry, metadata conflicts, foreign lifecycle reuse, stale reuse after lifecycle advancement, same-state/different-sequence reuse, divergent histories, identifier validation, Debug redaction, state-only recovery refusing replay, transition reconstruction, transition-backed lifecycle restoration, and persisted receipt reconstruction.

A commercial recovery defect was reproduced test-first on this canonical branch: persisted transition/lifecycle state could be reconstructed through the public typed API, but a persisted BapCommandReceipt could not, so true cross-process replay was impossible. Test-only RED head 794e532dd70c1f03416b87016ec8f10d565ee6cc failed with the expected missing-API error; production repair df89f56a7976447da76214c7d8300633d600639d added the restore boundary while reusing fail-closed retry-identity validation. Historical RED/predecessor evidence remains lineage only.

Subsequent current-head review findings corrected the API-contract scope and changelog classification. Two later Devin observations were verified against exact current head as informational rather than defects: transition evidence is internally validated at the private type-construction boundary before restore_with_transition, and the explicit replay state/sequence checks are harmless fail-closed invariant checks. All current inline review threads are resolved; only addressed or verified-non-actionable threads were resolved.

Exact-current verification

On unchanged exact head 52a918577958a5701e1146c7eb8b62fe8f8ccd44 against protected main 542ca1e9c0a863595b8b6697790005d2471f5413:

  • CI run 33105052208: success;
  • Rust contracts and production coverage checks: success;
  • SAST Semgrep run 33105052160: success;
  • Security Scan run 33105052231: success;
  • exact-head code-scanning checks including Semgrep OSS, OSV-Scanner, and Trivy: success;
  • the one-shot Rust-nightly materializer is skipped and is not counted as passing evidence;
  • current formal review inventory contains COMMENTED reviews only and no counted independent approval;
  • current inline review inventory contains no unresolved threads.

No predecessor-head check, scanner result, review, status, comment, synthetic merge, or model output transfers to this head or counts as independent approval. Same-head gates not actually present are not claimed.

Safety and truth boundary

This remains an in-memory lifecycle/idempotency primitive plus typed recovery-validation/reconstruction seams. It does not authenticate the caller or tenant, authorize an operation, persist receipts or transition evidence, authenticate persisted evidence, provide durable concurrent deduplication or locking, atomically couple receipt storage to browser/network side effects, or reconcile ambiguous external outcomes. A durable owner must persist receipt + exact transition evidence atomically at the appropriate production boundary, authenticate that evidence on restore, preserve policy/tenant/session authority, and reconcile uncertain side effects before commercial crash recovery can be claimed.

Prerequisite #208 is merged and the current branch is reconstructed and exact-head green. This PR is review-ready, but independent approval remains required before integration. Passing checks, comments, model output, and author activity are not approval. No workflow, secret, governance, release, tag, publish, approval, or merge mutation is included.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

BAP 수명주기가 마지막 전환 증거를 보존하고 검증된 상태 복구를 지원합니다. 명령 영수증은 식별자와 단일 전환을 묶습니다. 재생은 최신 전환의 상태, 순서, 이벤트가 모두 일치할 때만 성공합니다.

Changes

BAP 영수증 수명주기

Layer / File(s) Summary
전환 증거와 수명주기 복구
crates/originweave-bap/src/lib.rs, crates/originweave-bap/tests/task_recovery_transition_evidence.rs, crates/originweave-bap/tests/reconciliation_receipt_recovery.rs
BapTaskTransition이 이벤트를 보존합니다. restorerestore_with_transition이 상태, 순서, 마지막 전환 증거를 검증합니다. 복구된 reconciliation 및 terminal 상태의 동작을 테스트합니다.
명령 영수증 생성과 재생
crates/originweave-bap/src/lib.rs, crates/originweave-bap/tests/idempotency_receipt.rs, crates/originweave-bap/tests/idempotency_replay_validation.rs, crates/originweave-bap/tests/receipt_debug_redaction.rs
식별자 형식과 128바이트 제한을 검증합니다. apply_with_receipt, validate_replay, apply_or_replay가 신규 적용과 정확한 재생을 구분합니다. 영수증 디버그 출력에서 식별자 값을 숨깁니다.
계약 문서와 변경 추적
ARCHITECTURE.md, CHANGELOG.md, docs/API_CONTRACT.md, docs/TRD.md, docs/traceability/README.md
인메모리 영수증 계약과 재시도 네임스페이스를 기록합니다. 인증, 영속적 중복 제거, 부작용 억제가 계약 범위에 없음을 명시합니다.

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

Merge Risk: ⚪ Minimal · up to 34c5e

This PR adds exact idempotent replay and lifecycle-recovery validation. The remaining issues are limited to documentation wording and changelog classification, which could briefly mislead maintainers or integrators but do not change runtime behavior; no actionable merge-blocking risk remains after normal review.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant BapTaskLifecycle
  participant BapCommandReceipt
  Caller->>BapTaskLifecycle: apply_or_replay 요청
  BapTaskLifecycle->>BapCommandReceipt: 식별자와 전환 영수증 비교
  alt 일치하는 영수증
    BapCommandReceipt-->>Caller: 기존 영수증 반환
  else 영수증 없음
    BapTaskLifecycle->>BapTaskLifecycle: 전환 적용 및 마지막 전환 저장
    BapTaskLifecycle-->>Caller: 새 명령 영수증 반환
  end
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.39% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 7 files. (5 skipped: 5 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 BAP 수명주기 영수증을 멱등성 키에 연결하는 핵심 변경을 정확하고 간결하게 설명합니다.
Full details: Docstring Coverage

Explanation

Docstring coverage is 80.39% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 51 functions across 7 files. (5 skipped: 5 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bap-idempotency-receipt-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae changed the base branch from feat/bap-task-lifecycle to main August 27, 2026 02:26
Reconstruct the canonical idempotency branch on protected main 542ca1e while preserving the branch-owned BAP source, tests, API/TRD, architecture, and traceability changes. CHANGELOG overlap is reconciled in a following bounded commit.
@seonghobae
seonghobae marked this pull request as ready for review August 27, 2026 18:20
devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[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.

Devin Review found 2 new potential issues.

Devin Review

Comment thread crates/originweave-bap/src/lib.rs
Comment thread crates/originweave-bap/src/lib.rs
@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head governance audit:

  • Base main = 542ca1e9c0a863595b8b6697790005d2471f5413; head feat/bap-idempotency-receipt-contract = 52a918577958a5701e1146c7eb8b62fe8f8ccd44.
  • Live review-thread query found no unresolved, non-outdated threads.
  • Rust contracts, Production coverage, coverage-evidence, OpenCode, Noema, Semgrep, OSV, Trivy, Scorecard, and Python analysis checks are successful for this head.
  • reviewDecision=REVIEW_REQUIRED, and no qualifying independent non-author approval is present.
  • This PR is not merged; no source mutation, self-approval, or protected-branch bypass was made.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant