Five questions, cheapest first. The order is the technique: three of the five can kill a request outright, and asking them out of order is how a sprint gets spent building something the data-protection officer was always going to veto.
Each question has an owner, a cost, and a meaning when the answer is no. None of them is 'is it hard?' — difficulty is an estimate, not a feasibility gate.
Asked in this order, every time
#
Question
Answered by
Cost
What 'no' means
1
Does the data exist in any source system at all?
the source owner, in a message
minutes
this is a source project, not a warehouse project — it leaves your backlog today
2
Does it reach us at the grain and latency the request needs?
the bronze table and the job schedule
an hour
a new feed or a cadence change: costed, scheduled, and dependent on someone else
3
Does the source carry the history the question needs?
the extract's specification — not its contents
a morning
frequently fatal, always a surprise; see bronze.sap_kna1 below
4
Do the keys survive conformance across sources?
profiling the join
a day
the answer stays per-source until someone makes an identity decision
5
Is anyone allowed to see it?
the classification and the access policy
a week — it involves people outside the team
a masked or aggregated version of the request, or nothing
Cheapest disqualifier first, with one exception: if the request names a column classified as personal data — dim_customer.email, .phone, .street — ask question five first. It is the only one of the five whose answer is not yours to give, and the only one that can be reversed by someone who was not in the room.
Why
The expensive mistake is symmetrical. Refusing something feasible sends the work to a spreadsheet you will never see again; accepting something infeasible spends a sprint and then costs the credibility you needed for the next three.
A fixed order makes 'no' a position in a sequence rather than an opinion. Question three failed, here is the probe I ran, here is what the source does not record. That is a sentence a junior engineer can say to a stakeholder; 'I don't think we can' is not.
Doing it
Run the five in order, out loud, with the requester presentThe sequence is the argument.
Timebox each: question one is a message, question five is a meetingTwo days into question three IS the answer — the history is not there.
Record which question failed on the requirement itselfIn six months nobody remembers whether it was a source problem or a governance one, and the request comes back.
Jump straight to question five whenever email, phone or street appears in the request
Embedding it
The team runs the five; you hold the clockAny question that overruns its box is itself a finding worth discussing.
Make them ask question one of the source owner directly rather than routing it through youThat relationship is part of the handover, and it does not transfer at the end.
Walk one feasible request through all five so the team sees the sequence when the answer is yesA team that only ever sees it applied to refusals learns it as a rejection ritual and quietly drops it.
When they reach question five, hand the conversation to the data-protection owner in front of themThe lesson is that this answer has an owner, and it is not an engineer.
Defaults
Fixed order, cheapest first; anything naming personal data jumps to question five
Every failed question is recorded with its evidence, not summarised as 'not feasible'
Feasibility ends in three options, never in a verdict
Question three is asked about semantics, question four about data — do not swap them
Gotchas
Answering question one by looking in the warehouseThe warehouse shows only what was already ingested, so you get a 'no' that actually means 'not yet' and a viable request dies of a lookup.
Profiling data to answer question threeA snapshot source looks history-rich — many rows per customer — while the thing being asked for, when and why it changed, is not in there at any row count.
Question five answered by an engineer'We can mask it' is true and is not the same statement as 'you may have it'. The engineer's yes gets quoted back six weeks later by someone who never spoke to the data-protection owner.
Treating question four as a modelling task instead of a feasibility oneIf SAP customers and webshop customers share no resolvable key, no amount of dimension design produces conformed revenue — and that is a finding for the intake, not a ticket for the sprint.
REQ-118's field four already asked for segment as of the order date, and the owner's follow-up makes the dependency explicit: show me when customers moved between segments, and how many moved last year. Both readings need the same thing — a history of segment changes — and both are bounded by the same source. That source is bronze.sap_kna1, the SAP customer master as a daily full extract with no change timestamp. Nothing in the file says a change happened; the change is the difference between two files.
Answerable
That a customer's segment differs between two extracts we hold — to a resolution of one day, forward from the first snapshot retained.
Not answerable — anything before the first retained snapshot
No engineering recovers it, at any budget. The information was never sent.
Not answerable — a change that reversed between two extracts
A → B → A over a weekend is, to this source, no change at all. A reversal spanning several extracts is visible; one that opens and closes inside a single gap is not.
Silently misdated
A change on a day whose extract never arrived is dated to the next extract we hold, and nothing marks it as approximate.
Before promising anything, run the probe. It reads _tech_extract_date — the fourth technical column this source carries beyond the standard three, the extract's business date parsed from the filename by the Ingestion job. It takes a minute and it converts the estimate from a hope into a date:
Why
This question gets skipped because the table looks rich: a year of rows, one per customer per day. Grain is not history. A year of states and a year of changes are different things, and the request lives exactly in the gap between them.
Skipping it does not cost a sprint — it costs the engagement's credibility. You promise a churn number, build the pipeline correctly, and deliver a chart that starts in March to a business that asked about last year. Everything you did was right and the deliverable is still wrong.
How
sqlThe feasibility probe — run during intake, not during build
-- How far back can this source answer 'when did it change'?
-- _tech_extract_date is the extract's BUSINESS date, taken from the filename.
-- _tech_loaded_at would answer a different question -- when we loaded it --
-- and would move every answer on the day the extracts are re-run.
SELECT
MIN(_tech_extract_date) AS earliest_snapshot,
MAX(_tech_extract_date) AS latest_snapshot,
COUNT(DISTINCT _tech_extract_date) AS snapshots_held,
DATEDIFF(MAX(_tech_extract_date), MIN(_tech_extract_date)) + 1
- COUNT(DISTINCT _tech_extract_date) AS missing_days
FROM bronze.sap_kna1;
earliest_snapshot is the honest start of the answer. missing_days is the honest caveat: each missing day is a day on which a real change gets stamped with the wrong date, invisibly. If the probe returns 2026-03-14 and four missing days, the sentence you owe the requester is 'from 14.03.2026, to the day, except across four days where the date may be late' — not 'partially'.
Building it, once an option is chosen, is the snapshot-comparison pattern in the Ingestion route. This route only decides what may be promised.
Doing it
Ask the source team for the extract's specification, not a sampleA sample cannot tell you whether a change timestamp exists.
Run the probe before the estimateQuoting a history start date you have not queried is how the March boundary becomes a surprise in the demo.
State the limitation as a date and a count, in the requirement, in the requester's language
Record intra-extract reversal as a known limitationIt is invisible by construction, so it will never be found later by testing.
Embedding it
Hand the team the probe and the request and let them find the March date themselvesBeing told the source has no history is forgettable; watching MIN() return a date three months ago is not.
Have the team member who found the limitation write the sentence to the requesterDelivering a limitation is the skill being transferred, and you cannot transfer it by doing it for them.
Ask 'what does this source not know?' at every new-feed refinementKeep asking until somebody answers before you finish the question.
Ask the same question of bronze.sap_vbak and let them find that there is nothing to probeCDC carries a change timestamp per record, so question three is settled from the extract's specification in a minute. Contrast is what makes the distinction stick — one source needs a query to find its limit, the other has none to find.
Defaults
Interrogate the source's semantics before its contents
Every promise about history cites a queried date, never an adjective
Limitations that follow from the source live on the requirement and later in the table COMMENT
Snapshot sources make bronze retention a correctness requirement, not a storage preferenceSay so at intake, because it is a cost.
Gotchas
'We have a year of data' offered as the feasibility answerIt is a year of states. The request wanted changes, and the two coincide only where the source records a change event — which this one does not.
Deriving the change date from _tech_loaded_at instead of the extract's business dateRe-running last month's extracts on a Friday stamps every change that Friday, the report shows one enormous migration day, and every job was green.
Promising a backfill from the source archive before anyone has opened itArchives are routinely incomplete, differently formatted, or kept for thirty days — all of which you discover after the commitment, not before.
Treating missing_days as an operations problem to fix laterFor this request it is a correctness caveat owed to the business now, because the misdating is silent and no downstream test can detect it.
'Not possible' ends the conversation and moves the decision to whoever says yes next — usually a spreadsheet. Replace it with three options: what we can do now, what we could do with someone else's help, and what it would take to answer the question properly. Each carries a cost, a dependency, and the part people omit: what it still does not answer.
REQ-118's history problem, as three options
What you get
Cost
Depends on
Still not answered
A · compare snapshots forward
segment changes to the day, from the first retained extract
~2 days, this sprint
nothing outside the team
anything before that date; reversals inside one extract interval
B · request change documents from SAP
true change dates including history, back to SAP's own retention
1 day our side, 4–8 weeks lead time
the SAP team's backlog
nothing — if it arrives, and it arrives later than anyone plans for
C · reconstruct from the extract archive
possibly several extra months of history
1 sprint, quality unknown until it is opened
the archive existing and being complete
whatever the archive lacks — and you find that out at the end
Present all three, name your recommendation, let the owner choose, and write the choice into the requirement including the two that were rejected. In month nine somebody asks why the history starts in March, and the answer has to be a decision with a name and a date on it.
Why
A flat refusal is heard as the platform cannot do this. It does not stop the report from being built — it stops the report being built where you can govern it, test it, or find it during the next audit.
Three options also move the trade-off to the person who owns it. Whether four weeks of waiting is worth a year of history is a business decision, and every time an engineer makes it silently the business later discovers it was made and resents both the choice and the process.
Doing it
Never present fewer than three, and never pad to three with an option you would not takeA straw option is spotted instantly and it costs you the credibility of the other two.
Cost in days and dependencies, not in t-shirt sizes'Large' is not a number anyone can plan against.
State what each option still does not answerThat is the sentence people quote back to you, correctly, in six months.
Recommend oneThree options with no recommendation is abdication wearing the costume of neutrality.
Write the decision, the date, the decider and the rejected options into the requirement before the meeting ends
Embedding it
The engineer who found the limitation presents the three options, with you in the room and quietWhoever finds the problem should carry the conversation.
Rehearse five minutes before: ask what option C costsIf they cannot say, the option is not real yet and the meeting will expose that.
Ban 'not possible' from stand-upThe replacement phrase is 'not from this source — three options', and the team will start using it on each other first.
When the business picks the cheap option against your recommendation, write it down and move on visiblyThe team is watching to learn whether disagreeing with a stakeholder is survivable here.
Defaults
Three real options, honest costs, one stated recommendation, one written decision
Every option names what it still leaves unanswered
Rejected options stay on the requirementThey are the answer when the same question returns next year.
Anything depending on a third party is quoted as a lead time, never as an estimate
Gotchas
The straw optionPadding to three with something obviously unserious teaches the room that the exercise is theatre, and the next set of options gets read as sales material.
Costing option B at one day because your part is one dayThe SAP team's queue is the schedule; a plan that quietly assumes otherwise slips in public, and it slips at the demo.
Options with no recommendationThe business picks the cheapest, hits its limitation, and feels misled — correctly, because you already knew which limitation they were choosing.
Letting the chosen option live only in a slideThe chart's history starts in March forever, and whoever inherits it treats March as a bug and re-investigates the whole thing from scratch.