The right picture, delivered into the wrong rectangle
Resolution, crop and reserved space solve different image problems. Design all three around what the reader needs to see.
A constructed write-permission failure shows how controlled comparisons change the next decision without proving more than their evidence supports.
The weekly report stops updating after R2, so the release is an obvious place to look. It is not yet an explanation. A changed parser, another selected credential, an account change or an unrelated fault could all fit the timing. Reverting may be a sensible way to reduce the disruption. Finding the cause asks for something more discriminating: a check whose alternative outcomes would send the investigation in different directions.
The investigation plan follows an invented service where a source read works and the destination write returns permission_denied. It is a fully specified case to reason through, not a real incident or an executed provider test. The notebook keeps observations separate from their interpretation. Running a function that prints the predetermined answers would not test the diagnostic method; the useful work is deciding what each possible result would make us check next.
Google's Effective Troubleshooting chapter describes testing explanations, considering confounding conditions and recording results, while distinguishing mitigation from investigation.[1] In this constructed case, the report should be marked stale and repeated unexamined writes avoided while the cause is checked. Those measures address the operational consequence without claiming that R2 caused the permission denial. The comparison can then examine the write boundary while users have an accurate account of the report's freshness.
Start with three plausible explanations: the transformation produces an unacceptable payload, the credential expired, or the job lacks write capability. More than one can be true. A release could alter both the parser and the selected connection. Finding a promising fault should therefore focus the next check rather than clear every other component by association. That keeps the investigation useful without requiring a complete account of the service before making any progress.
The first proposed test bypasses the new transformation with a previously accepted payload, using the same current principal, resource and relevant request conditions. If that succeeds, the changed transformation deserves closer inspection. In the constructed observation, it receives the same denial. The new payload is therefore not required to reproduce this denial. That weakens the case for fixing the parser first, but it does not prove the parser has no defect: a permission check might reject both payloads before either reaches the changed mapping.
A fresh uncached read succeeds under the verified same token identity while the write fails. That weakens simple expiry of the whole credential and turns attention towards the capabilities needed for writing. It does not make read permission stand in for write permission. A cached response, another token or a public endpoint would change even that narrower interpretation. Keep those comparison conditions in the notebook through safe references, so the next engineer can see why the read result is relevant without exposing the token itself.
Compare the job’s selected connection with its expected operations and resource access. In this case the write stage chose a read-only connection instead of the configured write-capable one. That mismatch explains a concrete obstacle at the current write boundary. Who selected it and whether R2 introduced the choice are historical questions for authorised configuration or change-history evidence. Separating them lets the owner correct a present fault while still investigating how it arrived. Editing the payload cannot grant a read-only connection write authority, so another round of parser changes would leave this obstacle in place. The configuration comparison earns priority for that concrete reason.
A known-good payload is only a useful comparison when its important conditions are known too. An older payload submitted to a different account can succeed for a reason unrelated to its contents. An engineer's personal token may have broader rights than the scheduled job. A test from a laptop can take another network route. Record the account, resource, client configuration and relevant request metadata, using safe references rather than secret values. The aim is to change the explanation under test while holding enough else steady that the result is interpretable.
Useful incident work rarely comes with laboratory conditions. If the only available comparison uses another account, retain that detail rather than translate its success into the API works. The result may still justify the next low-risk check. It just answers a narrower question than a same-account test would. Naming the difference now is easier than making the next investigator unlearn a confident explanation that no longer fits the conditions they encounter.
An active test write can send a notification, duplicate a report or alter a later comparison. Observation is preferable when it can adequately distinguish the explanations; otherwise a designated resource and authorised procedure are needed. This constructed plan calls no live API and expands no scopes. The read-only connection finding identifies a mismatch to review with the owner, rather than evidence that the application should request every available permission.
Record the alternative outcome before running the test. For the old-payload comparison, success would direct attention to the transformation; denial would direct attention to the common write boundary. If both results would merely lead to rerunning the same command, the test may not be answering the question claimed for it. This small habit makes a diagnostic action accountable for the information it is expected to produce. It also helps a colleague continue the investigation without repeating a check whose negative result was never written down.
Fully specified constructed investigation, not actual incident observations or executed provider tests.
Follow the labelled arrows. On a narrow screen, scroll sideways if needed.
After an approved correction selects the intended connection, a bounded write may succeed. Check the actual report update before telling its readers that it is current. Success against another resource cannot supply that evidence, and restoring today’s update does not reconstruct every missed reporting period. Those are separate pieces of work. The recovery message can be clear about which is finished without waiting for the complete historical explanation. Readers may need the latest report while its owner still checks the missing periods. Keeping both states visible prevents a successful current update from quietly closing the older work the interruption left behind.
The timeline may still need investigation. A rollback could appear to fix the report because it restores the old configuration selection, even if the released parser was never involved. Conversely, a rollback might leave the current credential selection unchanged and fail to help. Preserve which component, configuration and data state each action affected. Without that record, the eventual story can become the deployment broke it and rollback fixed it, while omitting the mechanism that would prevent recurrence.
There are times when mitigation should come before a discriminating experiment. If continued processing risks corrupting data or creating external commitments, stop that damage using an understood control rather than leave the system running to obtain a cleaner diagnosis. Explain what evidence was lost or altered by the mitigation and continue afterwards. A method that insists on perfect proof while customers bear increasing impact has confused the investigation's elegance with the purpose of operating the service.
The final notebook should say what was observed, which explanations remain possible, which action restored the intended behaviour and what evidence links the original change to the failure. In this constructed case, the useful finding is a wrong connection selection at the write stage. The cause of that selection is a further historical question. Keeping those sentences separate makes the account more accurate and gives the follow-up work a specific target.
The old payload still received the denial; the same-token read worked; the job selected a read-only connection. Together those results make the next action more precise than the report failed after R2. Correct and verify the intended write path, then use change history to investigate whether the release introduced the selection. Another engineer should be able to challenge that account by following the comparisons. They should not have to accept the release timing as the missing mechanism.
Working on a workflow like this? Hamsa helps finance and operations teams connect their tools and handle the exceptions, starting with one workflow.
See the Payment Operations PilotPrimary sources behind this article. Living documentation may change.

Practical engineering. A human perspective.
More about Hamsa Software and the person behind it. Editorial notes.