Skip to content

fix: bind reconciliation approval to database snapshot - #31

Merged
seonghobae merged 5 commits into
fix/reconciliation-multi-match-conservationfrom
fix/reconciliation-approval-snapshot
Aug 28, 2026
Merged

fix: bind reconciliation approval to database snapshot#31
seonghobae merged 5 commits into
fix/reconciliation-multi-match-conservationfrom
fix/reconciliation-approval-snapshot

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add migration 0016 for database-owned SHA-256 reconciliation approval snapshots.
  • Preserve immutable object-storage source-payload hash/reference provenance separately from the database state snapshot.
  • Freeze late allocations and prevent reviewed matches from changing tenant, run, match, or candidate identity; supersession preserves terminal approval time.
  • Reject upgrades with pre-existing non-proposed reconciliation matches that lack durable approval evidence.
  • Expand real PostgreSQL forced-RLS regression coverage and correct standards traceability for multi-match conservation.

Authority boundary

This slice records reconciliation review evidence only. It does not select chart-account identifiers, post/reverse journals, close periods, or issue accounting receipts.

Dependency

Stacked on PR #29 and its current head fb8223bd82d51ed5337feae4c0dfa114ce964971 on fix/reconciliation-multi-match-conservation.

Verification

  • PostgreSQL 18.6 isolated test database: 490 tests passed.
  • Branch and statement coverage: 100% (4,992 statements; 1,800 branches).
  • Repository contract validator: valid.
  • git diff --check: clean.
  • CodeGraph index: up to date.
  • Local RED regressions reproduced before each corresponding hardening change.

Review response

The approval snapshot is computed and overwritten by PostgreSQL trigger logic under a shared transaction advisory lock. Candidate identity and terminal approval time are immutable after review evidence exists; allocation lock triggers run before migration 0015 conservation checks. Existing unbound terminal history fails the migration closed.

@coderabbitai

coderabbitai Bot commented Aug 28, 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: 70c5d379-3642-4df5-b9c4-fc3167bffa8a

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.

…onservation' into fix/reconciliation-approval-snapshot
devin-ai-integration[bot]

This comment was marked as resolved.

chatgpt-codex-connector[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.

Devin Review found 1 new potential issue.

Devin Review

Comment thread database/migrations/0016_reconciliation_approval_evidence.sql
@seonghobae
seonghobae merged commit de479ca into fix/reconciliation-multi-match-conservation Aug 28, 2026
7 checks passed

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac72e686f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +77 to +79
SELECT 1
FROM accounting_core.reconciliation_match AS reviewed_match
WHERE reviewed_match.match_status_code <> '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.

P1 Badge Run the upgrade guard with all-tenant visibility

When 0016 is applied by an unbound, non-BYPASSRLS migration owner, this query sees no rows because reconciliation_match already has forced RLS and current_tenant_account_id() only resolves runtime-role bindings. The migration therefore succeeds despite legacy terminal matches lacking approval evidence, leaving precisely the unbound history the guard claims to reject. Fresh evidence in this revision is that the new upgrade guard performs an ordinary RLS-filtered query rather than using controlled all-tenant migration visibility.

AGENTS.md reference: AGENTS.md:L21-L21

Useful? React with 👍 / 👎.

Comment on lines +389 to +390
IF TG_OP = 'UPDATE'
AND OLD.match_status_code IN ('approved', 'rejected') THEN

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep superseded matches terminal and immutable

After an approved or rejected match is changed to superseded, later updates bypass this branch because it only recognizes approved and rejected as old terminal states. A caller can consequently rewrite the preserved approved_at, move the match back to proposed, or reactivate an approved match using its old immutable approval row and snapshot, defeating supersession as the explicit historical-retirement path.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant