In this article

For an AI-assisted interview, start with one request and trace its inputs, dependencies, and failure paths before asking for edits. This illustrative Python exercise follows an order through a handler, service, and repository. It shows how three contract tests expose a missing ownership check and protect a narrow repair. Python provides traceback inspection and assertion tools for checking your understanding. Python traceback documentation Python unittest documentation

Python request map connects handle_order, load_order, and Orders.get, then checks owner, different-user, and missing-order outcomes.
View full-size diagram

Start with one request and a written contract

An unfamiliar repository becomes easier to explore when you can name a single behavior. In this practice exercise, a user requests an order by its identifier. The contract says the owner receives the order, a different user receives a forbidden response, and an unknown identifier receives a missing response. Write those three outcomes down before opening an assistant. They give your exploration a purpose and let you distinguish a plausible explanation from a verified one.

Use AI during a real assessment only when its instructions explicitly permit it. The workflow here is a practice technique, not a claim about any employer's hiring rules. For a timed rehearsal, try spending five minutes locating the request entry point and ten minutes tracing its dependencies, then reserve time for a patch, tests, and explanation. Adjust that budget to the exercise rather than treating it as a universal interview format.

    Map the handler, service, and repository

    Read from the public entry point inward. In this example, handle_order chooses the response shape, load_order makes the ownership decision, and Orders.get retrieves stored data. The dependency map is handle_order → load_order → Orders.get. Record which inputs each function receives and what it returns or raises. This is more useful than summarizing every file: it tells you where a changed behavior belongs and which callers might observe it.

    Imagine the service initially omitted the ownership comparison and immediately returned the order. A request by bob for alice's order would then receive status 200 and its total. Nothing crashes, so a happy-path run cannot reveal the contract violation. The repaired service below adds the ownership decision before constructing the successful response. The handler already knows how to map PermissionError to the illustrative 403 response; the repository does not need a new responsibility.

    Illustrative service after the ownership repair
    Codepython
    class Orders:
        def __init__(self, rows):
            self.rows = rows
    
        def get(self, order_id):
            return self.rows[order_id]
    
    
    def load_order(user_id, order_id, repo):
        order = repo.get(order_id)
        if order["owner"] != user_id:
            raise PermissionError("Order belongs to another user")
        return {"id": order_id, "total": order["total"]}
    
    
    def handle_order(user_id, order_id, repo):
        try:
            return 200, load_order(user_id, order_id, repo)
        except KeyError:
            return 404, {"error": "missing"}
        except PermissionError:
            return 403, {"error": "forbidden"}
    

      Use execution evidence to check the call map

      A call map is a hypothesis until you inspect or execute the relevant paths. For the missing-order case, call load_order directly with an unknown identifier and examine the resulting exception. Python's traceback.extract_tb reads the traceback into frame summaries, which can show the functions traversed by that failing call. That evidence helps confirm the repository lookup path; it does not prove that the ownership rule exists or that every possible request follows the same route. Python traceback documentation

      In the complete handler, KeyError is converted to a response, so the exception no longer escapes that boundary. Inspect the service directly when exploring the example instead of changing the handler just to obtain a stack trace. For the unauthorized path, compare the returned response with the written contract. A successful HTTP-like status can still be incorrect. Keep observed results separate from your interpretation so an assistant cannot turn an assumed behavior into a supposed fact.

      Inspect the missing-order service path
      Codepython
      import traceback
      
      repo = Orders({"o1": {"owner": "alice", "total": 25}})
      try:
          load_order("alice", "absent", repo)
      except KeyError as error:
          print([frame.name for frame in traceback.extract_tb(error.__traceback__)])
      # The final two frame names are load_order and get.
      

        Ask the assistant for an evidence-backed explanation

        Give the assistant the three functions, the three expected outcomes, and the observed unauthorized response. Ask it to identify the function that owns each decision before proposing a change. A useful prompt is: Explain this request path using function names from the supplied code. Separate confirmed behavior from assumptions. Identify the smallest change that prevents a different user from receiving the order, while preserving the existing missing-order response.

        Check every named symbol against the source. If the explanation invents a middleware layer or assumes that authentication already validates ownership, correct the context before accepting a patch. User identity and ownership are separate inputs to this toy contract. You can also ask for an alternative placement of the check and compare the affected callers. The assistant helps you enumerate options; reading and testing the actual repository determines whether those options fit.

          Verify allowed, forbidden, and missing requests

          Place the tests below after the repaired service in one file, such as order_example.py, and run python order_example.py. The expected response tuples are written from the contract, without calling another production function to calculate them. Python's unittest assertion methods compare the result with those explicit expectations. The setup supplies fresh example data for each test, keeping these cases independent of earlier requests. Python unittest documentation

          All three tests were executed successfully for this article. Removing only the ownership guard makes the forbidden-request assertion fail: the service returns 200 instead of 403. That deliberate check demonstrates that the suite can detect the original omission. It also explains why the owner and missing-order tests matter: a repair that denies every request or maps every failure to forbidden would break behavior outside the motivating case. These results apply to this small example, not a production authorization audit.

          Independent response-contract tests
          Codepython
          import unittest
          
          
          class OrderContractTests(unittest.TestCase):
              def setUp(self):
                  self.repo = Orders({"o1": {"owner": "alice", "total": 25}})
          
              def test_owner_receives_order(self):
                  self.assertEqual(handle_order("alice", "o1", self.repo),
                                   (200, {"id": "o1", "total": 25}))
          
              def test_other_user_is_denied(self):
                  self.assertEqual(handle_order("bob", "o1", self.repo),
                                   (403, {"error": "forbidden"}))
          
              def test_missing_order(self):
                  self.assertEqual(handle_order("alice", "absent", self.repo),
                                   (404, {"error": "missing"}))
          
          
          if __name__ == "__main__":
              unittest.main()
          

            Explain the repair and its remaining assumptions

            A concise interview explanation can follow the same evidence: I traced the request into load_order, found that it returned stored data without comparing owners, added the comparison before building the response, and ran allowed, forbidden, and missing cases. Name the actual failure and the actual tests. Saying that the assistant fixed security is too broad; saying that a different-user request now produces the agreed response describes an observable result.

            The example assumes trusted user identity, valid stored rows, and an intentionally distinct response for missing and forbidden orders. A real service may deliberately use the same response to avoid revealing whether an identifier exists. It may also require tenant boundaries, database-level checks, logging rules, and protection against concurrent changes. Ask how the repository defines those contracts before extending the patch. Reading one request deeply gives you a foundation for those questions without claiming complete understanding of the application.

            For practice explaining the next decision while you work, the booking-repair dialogue shows how to clarify a boundary rule, reject a generated suggestion, and report the evidence from a focused test.

            To practice the whole repair under a clock, the 45-minute rehearsal assigns checkpoints to reproduction, implementation, verification, and explanation using a small inventory bug. Treat its timing as a practice plan you can adjust.

              Frequently asked questions

              How much of the repository should I read first? Read the entry point, the decision-making service, its direct data dependency, and relevant tests for one concrete behavior. Expand outward when a dependency or caller changes the contract. A directory-wide summary is useful only if you can connect it to the request you are trying to understand.

              Can an AI explanation replace a test run? No. It can suggest a call map and candidate checks, but execution can contradict that explanation. In this exercise, a normal response from the original code is precisely the failure. Compare the observable result with an independently written expectation.

              What should I do if AI is not allowed in the interview? Practice this tracing process beforehand and perform it without the assistant during the assessment. The request map, explicit outcomes, narrow change, and evidence-based explanation are useful with or without AI.

                Sources & editorial notes

                This article was authored with AI using primary-source research and an automated technical review. It has not been reviewed by a human. Code examples are illustrative; run and verify them in your own environment.

                1. Python traceback documentation

                  Documents traceback extraction and frame summaries used to inspect the illustrative failing service path; it does not establish an authorization policy.

                2. Python unittest documentation

                  Documents TestCase assertions and test execution used to compare the example responses with independent contract expectations.

                Put the reading into practice

                Work through an existing repository, review AI suggestions, and test the decisions behind your changes.

                Explore practice problems