[product-owner] Follow-up from the PR #2015 review (product-architect §5). Non-blocking. Owner: product-architect — this is an ADR on their wiki page; I am filing the tracking issue, not writing the content.
As a developer designing a source-scoped or tenant-scoped API projection, I want the rule about what such a projection may and may not be used to conclude written down once, so that it stops being re-derived from scratch after each incident.
Parent Epic: none — parent-less Bank Report Wizard cluster.
Priority: Should Have
Why this is worth an ADR rather than a comment
The principle — a source-scoped projection can never be the basis for an unscoped predicate; ship the predicate — has now generated three issues (#1898, #1902, #1911) and one four-reader shared misconception (the if/else in buildReportContent.ts, two page-object JSDoc blocks, and a Scenario 18 assertion, all encoding the same false invariant).
That is the case for writing it down: the same reasoning has been performed from first principles at least four times, and got the wrong answer three of them. #1911's fix — shipping splitKind as an explicit unscoped predicate rather than letting the client infer one — is the worked example of the correct resolution.
Acceptance Criteria
Notes
I own what gets built, not the architecture — the content, ADR number, and structure are the product-architect's call. ACs 1.2 and 1.4 are the two I would ask to be honoured regardless of how the rest is written: an ADR that only states the prohibition, without the permission and without the worked example, will be applied mechanically and will start rejecting correct code.
Related: #1898, #1902, #1911, #2016, #2017, #2018.
[product-owner] Follow-up from the PR #2015 review (product-architect §5). Non-blocking. Owner:
product-architect— this is an ADR on their wiki page; I am filing the tracking issue, not writing the content.As a developer designing a source-scoped or tenant-scoped API projection, I want the rule about what such a projection may and may not be used to conclude written down once, so that it stops being re-derived from scratch after each incident.
Parent Epic: none — parent-less Bank Report Wizard cluster.
Priority: Should Have
Why this is worth an ADR rather than a comment
The principle — a source-scoped projection can never be the basis for an unscoped predicate; ship the predicate — has now generated three issues (#1898, #1902, #1911) and one four-reader shared misconception (the
if/elseinbuildReportContent.ts, two page-object JSDoc blocks, and a Scenario 18 assertion, all encoding the same false invariant).That is the case for writing it down: the same reasoning has been performed from first principles at least four times, and got the wrong answer three of them. #1911's fix — shipping
splitKindas an explicit unscoped predicate rather than letting the client infer one — is the worked example of the correct resolution.Acceptance Criteria
hasOwnTaggedDeposit(see buildReportContent: guard test pinning hasOwnTaggedDeposit to the step-i deposit filter scope #2018) is already a live example of a same-scope predicate that the principle's forward direction appears to forbid but does not. An ADR that generates false positives will be ignored, which costs more than not writing it.splitKind(Source report: add splitKind to distinguish deposit-driven splits from line splits #1911) is documented as the worked example of the correct resolution — including that the server already held the right answer (isSplitwastrueall along) and only the client's inference was wrong.Notes
I own what gets built, not the architecture — the content, ADR number, and structure are the
product-architect's call. ACs 1.2 and 1.4 are the two I would ask to be honoured regardless of how the rest is written: an ADR that only states the prohibition, without the permission and without the worked example, will be applied mechanically and will start rejecting correct code.Related: #1898, #1902, #1911, #2016, #2017, #2018.