Skip to content

feat(bap): classify crash-recovery side-effect outcomes - #214

Draft
seonghobae wants to merge 51 commits into
feat/bap-idempotency-receipt-contractfrom
feat/bap-recovery-outcome-classification
Draft

feat(bap): classify crash-recovery side-effect outcomes#214
seonghobae wants to merge 51 commits into
feat/bap-idempotency-receipt-contractfrom
feat/bap-recovery-outcome-classification

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Scope

Bounded partial implementation of #200, stacked on canonical BAP idempotency owner PR #211. This Draft makes crash-recovery side-effect ambiguity explicit, binds each classification to the exact accepted command receipt and a canonical SHA-256 recovery-evidence identity, exposes lifecycle-aware fail-closed recovery handling, and gives both external outcome classes and derived recovery actions exact storage-neutral canonical text values. It does not authenticate recovery evidence, prove that an external side effect occurred, provide durable deduplication/persistence, or grant tenant, policy, destination, secret, browser, approval, dispatch, or release authority.

Recovery contract

BapExternalSideEffectOutcome has exact canonical values confirmed_no_side_effect, confirmed_side_effect, unknown_outcome, and reconciliation_required. BapRecoveryAction now likewise has exact canonical values revalidate_before_redispatch, verify_confirmed_side_effect, and reconcile_before_further_action. Both APIs emit only those values and parse only exact canonical text; aliases, case changes, surrounding whitespace, and unknown values fail closed with typed parse errors.

BapCommandRecovery retains the exact immutable BapCommandReceipt, external side-effect classification, and validated BapRecoveryEvidenceDigest. Digest mismatch fails closed before lifecycle inspection, then exact receipt replay validation preserves typed errors. Terminal/suspended/reconciliation-held states block redispatch even for confirmed-no-side-effect; confirmed side effects require post-condition verification; unknown/unreconciled outcomes require reconciliation. A recovery action or Ok(true) from permits_redispatch() remains protocol metadata/eligibility only and never becomes execution authority.

Test-first lineage

The current action-encoding slice was added test-first at b4a6c7a3392819d68994146e067d103e8eacb3e0: the integration contract required BapRecoveryAction::as_str, strict parse, and BapRecoveryActionParseError before those production APIs existed. Production repair 150184280bcfc9c30b8569322fd49bef369d8f07 implements that exact bounded contract. Existing regressions continue to cover all four outcome classes, recovery-action derivation, exact outcome/action encoding and strict parsing, approval/input/checkpoint/reconciliation holds, terminal events, stale receipts, canonical digest parsing, evidence-digest binding, and Debug redaction.

Exact current evidence

For unchanged exact head 150184280bcfc9c30b8569322fd49bef369d8f07:

  • CI run 33306089600: success;
  • Rust contracts job 99242810201: repository contracts, canonical formatting, locked workspace/all-target check, full tests, strict Clippy, and rustdoc success;
  • Production coverage job 99242810079: exact production function/line/region/branch measurement and exact coverage enforcement success;
  • current formal review inventory: empty;
  • current inline review-thread inventory: empty.

No predecessor check, review, approval, queued/skipped/cancelled status, synthetic merge, or model output transfers to this head.

Fresh stack truth / authority

  • protected main: 542ca1e9c0a863595b8b6697790005d2471f5413 at the latest run read;
  • parent PR feat(bap): bind lifecycle receipts to idempotency keys #211/live base: feat/bap-idempotency-receipt-contract@52a918577958a5701e1146c7eb8b62fe8f8ccd44;
  • this Draft exact contributor head: 150184280bcfc9c30b8569322fd49bef369d8f07;
  • GitHub reports this Draft mergeable against that base.

This PR remains Draft while parent #211 is open and independent qualifying review is absent. Protected-main AGENTS.md and live organization rules remain authoritative. No workflow, secret, governance, release, tag, publish, approval, Ready-state, merge, force-push, destructive-rebase, or gate-weakening mutation is included.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

Copy link
Copy Markdown
Contributor Author

Current-head audit for 30fb52f (base 52a9185): CodeGraph trace covered BapCommandRecovery, BapExternalSideEffectOutcome, exact receipt replay validation, lifecycle suspension/terminal states, and recovery tests. Local Rust 1.97.1 verification passed: cargo test -p originweave-bap --all-targets (45 integration tests), cargo clippy -p originweave-bap --all-targets -- -D warnings, cargo fmt --all -- --check, and git diff --check. Hosted Rust contracts, Production coverage, and CodeRabbit are SUCCESS; unresolved non-outdated review threads: 0. No production defect or justified mutation found. PR remains draft; reviewDecision is empty, so no merge or readiness claim is 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