Skip to content

fix(ers): continue failure_strategy bug - first-match-wins per ADR - #3964

Open
elizabethhealy wants to merge 2 commits into
feat/dspx-4581-ers-bdd-gapsfrom
dspx-4595-ers-continue-failure-strat-bug
Open

fix(ers): continue failure_strategy bug - first-match-wins per ADR#3964
elizabethhealy wants to merge 2 commits into
feat/dspx-4581-ers-bdd-gapsfrom
dspx-4595-ers-continue-failure-strat-bug

Conversation

@elizabethhealy

@elizabethhealy elizabethhealy commented Sep 2, 2026

Copy link
Copy Markdown
Member

Proposed Changes

  • First-match-wins is now enforced for both failure strategies — previously, continue
    kept running all matching strategies after a success and accumulated one entity per
    strategy into the chain. The ADR is explicit
    that on success, execution stops regardless of failure strategy; a token's entity chain
    always holds exactly one entity
  • continue still does what it's supposed to — the ADR defines continue
    as error handling only: if a strategy fails, fall through to the next matching one.
    The fix only changes what happens on success
  • Strategy order, not failure strategy, determines the winner — whichever strategy is
    listed first in config and matches the token is the one that resolves it
  • BDD Scenario 3 was an intentionally-failing test asserting PERMIT against the buggy
    behavior; it now correctly asserts DENY and acts as a regression guard

Note for reviewers

The customer pattern of "Claims for routing, LDAP for department" across two separate
strategies is not supported — multi-entity chain composition is explicitly deferred in
the ADR as future work
.
The workaround is to put the richer strategy first, or merge both sources in a single
strategy's output_mapping.

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

Summary by CodeRabbit

  • Behavior Changes

    • Multi-strategy entity resolution now stops after the first successful strategy.
    • Each resolved token chain contains exactly one entity from the first matching strategy.
    • Strategy order determines the selected entity; failure handling only controls fallback after errors.
  • Bug Fixes

    • Corrected multi-strategy resolution to prevent later successful strategies from adding entities to an existing chain.
  • Documentation

    • Updated guides and acceptance scenarios to describe first-match-wins behavior and current strategy limitations.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 031e7e5d-a871-42f5-ad1f-7a185b21c0ea

📥 Commits

Reviewing files that changed from the base of the PR and between 8688ec2 and db3203a.

📒 Files selected for processing (11)
  • service/entityresolution/integration/README.md
  • service/entityresolution/integration/entity_chain_comparison_test.go
  • service/entityresolution/integration/internal/chain_contract_tests.go
  • service/entityresolution/integration/internal/resolved_token_chain_contract.go
  • service/entityresolution/integration/multistrategy_contract_test.go
  • service/entityresolution/integration/multistrategy_test.go
  • service/entityresolution/integration/unified_contract_test.go
  • service/entityresolution/multi-strategy/README.md
  • service/entityresolution/multi-strategy/v2/registration.go
  • service/entityresolution/multi-strategy/v2/registration_test.go
  • tests-bdd/features/multi-strategy-ers-multi-success.feature

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Multi-Strategy entity resolution now stops after the first successful strategy. Contract tests support implementation-specific chain shapes. Unit, integration, and BDD tests validate single-entity chains, strategy ordering, and failure fall-through.

Changes

Multi-Strategy first-match resolution

Layer / File(s) Summary
Runtime first-match behavior
service/entityresolution/multi-strategy/v2/registration.go, service/entityresolution/multi-strategy/v2/registration_test.go, service/entityresolution/multi-strategy/README.md
Resolution stops after the first successful strategy. continue only advances after failure. Tests cover strategy order and failure fall-through.
Implementation-specific chain contracts
service/entityresolution/integration/internal/chain_contract_tests.go, service/entityresolution/integration/multistrategy_contract_test.go, service/entityresolution/integration/unified_contract_test.go, service/entityresolution/integration/README.md
Contract suites accept expected chain shapes. Multi-Strategy expects one CATEGORY_ENVIRONMENT entity, while Keycloak retains its two-entity shape.
First-match integration assertions
service/entityresolution/integration/internal/resolved_token_chain_contract.go, service/entityresolution/integration/multistrategy_test.go, service/entityresolution/integration/entity_chain_comparison_test.go
Integration expectations and comparison assertions validate one entity from the first matching strategy.
BDD first-match regression coverage
tests-bdd/features/multi-strategy-ers-multi-success.feature
The regression scenario expects DENY when a later strategy would provide an attribute but does not execute.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to db320

Multi-strategy entity resolution now returns only the first successful strategy result, with later strategies used only after a failure under continue mode. The behavior and associated chain-shape expectations are covered across runtime and regression tests, with no remaining merge-blocking risk identified.

Sequence Diagram(s)

sequenceDiagram
  participant Token
  participant MultiStrategy
  participant EntityChain
  Token->>MultiStrategy: Submit token
  MultiStrategy->>MultiStrategy: Try strategies in configured order
  MultiStrategy->>EntityChain: Store first successful entity
  MultiStrategy->>MultiStrategy: Continue only after failure
Loading

Suggested reviewers: jrschumacher

Poem

A rabbit checks the strategy line
First success makes the chain align
Failures hop to the next bright door
One small entity, never more
Tests guard the rule with carrot cheer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.42% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 8 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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 The title clearly identifies the ERS failure-strategy bug and the first-match-wins behavior required by the ADR.
Full details: Docstring Coverage

Explanation

Docstring coverage is 68.42% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 19 functions across 8 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dspx-4595-ers-continue-failure-strat-bug

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.

@github-actions github-actions Bot added the size/m label Sep 2, 2026
@elizabethhealy elizabethhealy changed the title fix(ers):ccontinue failure_strategy bug fix(ers): continue failure_strategy bug Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 249.223926ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 138.89646ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 432.418685ms
Throughput 231.26 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 59.336519082s
Average Latency 592.078324ms
Throughput 84.27 requests/second

@elizabethhealy elizabethhealy changed the title fix(ers): continue failure_strategy bug fix(ers): continue failure_strategy bug — first-match-wins per ADR Sep 4, 2026
@elizabethhealy elizabethhealy changed the title fix(ers): continue failure_strategy bug — first-match-wins per ADR fix(ers): continue failure_strategy bug - first-match-wins per ADR Sep 4, 2026
@elizabethhealy
elizabethhealy changed the base branch from main to feat/dspx-4581-ers-bdd-gaps September 4, 2026 14:16
@elizabethhealy
elizabethhealy marked this pull request as ready for review September 4, 2026 14:16
@elizabethhealy
elizabethhealy requested a review from a team as a code owner September 4, 2026 14:16
@elizabethhealy
elizabethhealy changed the base branch from feat/dspx-4581-ers-bdd-gaps to main September 4, 2026 14:29
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 220.367373ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 127.566444ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 415.24781ms
Throughput 240.82 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 55.912679618s
Average Latency 558.169261ms
Throughput 89.43 requests/second

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • otdfctl
  • service
  • tests-bdd

See the workflow run for details.

@elizabethhealy
elizabethhealy changed the base branch from main to feat/dspx-4581-ers-bdd-gaps September 4, 2026 14:46
// First match wins, per the ADR: failure_strategy only governs error handling
// ("continue" tries the next strategy on failure, "fail-fast" stops immediately).
// Neither mode keeps resolving after a success, so a chain holds exactly one entity.
break

@pflynn-virtru pflynn-virtru Sep 4, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can make every decision fail for environment-first configs.

I am verifying now...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

tests to confirm #3980

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants