FDEInterviews logo

Specify the ownership, trust, network and meaning at each boundary

Turn a system trace into boundary contracts with responsible owners, permission checks, approved routes and explicit domain meanings. Work through a misleading customer-ID join and a dependency schedule instead of treating arrows as guarantees.

28 MIN

TL;DR: For each connection, state who owns changes, which identity and permissions apply, what network route is approved and what the data means. Boundaries deserve explicit checks, while failures inside components remain part of the investigation too.

Where you are. The previous lesson traced a record and marked evidence limits. Now turn the important crossings into contracts that can guide implementation, review and recovery.

An arrow needs a contract

Architecture diagrams can show ownership, trust and network boundaries well when their authors include them. A diagram containing only boxes may leave these questions open. The remedy is to annotate or supplement it, not to assume all diagrams conceal the truth.

Components can fail internally through incorrect logic, resource exhaustion or storage errors. Boundaries add risks of mismatched assumptions between otherwise working parts. Investigate both. The three boundary types below are useful views, not an exhaustive list of all failure modes.

Your service within your authority Their system coordinate changes OWNERSHIP TRUST NETWORK who fixes bad data whose credentials who allows the route

Ownership defines coordination and correction rights

A source owned by another team may still support an approved correction API, a mapping layer or a joint repair. Ownership does not mean you can only wait. It means you need to know who can authorize each change and how the source and derived copies remain consistent.

For a malformed identifier, possible responses include a contract-approved normalization, explicit mapping, quarantine, rejection of the whole batch or source correction. Choose based on the meaning and consequence. If malformed rows make the batch unsafe, continuing the rest may be wrong; if they are isolated and the contract permits partial processing, blocking all work may be unnecessary.

Record original values, transformation rule/version and reconciliation evidence where appropriate. Do not silently “repair” an identifier merely because a transformation lets the join succeed. Nor should you reject a valid canonicalization rule simply because it changes the source's formatting.

A shared word may hide different models

Martin Fowler's bounded-context explanation describes explicit boundaries within which a domain model is coherent, with mappings between models. A bounded context is not simply a synonym for a team ownership boundary or network segment.

In this synthetic freight example, billing's customer is the legal party paying an invoice. Dispatch's customer field identifies the delivery site. Both use small integers, but equal integers do not establish equal entities.

Run the SQLite fixture to see a query that is syntactically valid and semantically wrong:

import sqlite3

conn = sqlite3.connect(':memory:')
conn.executescript('''
CREATE TABLE billing_customer (payer_id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE delivery_site (site_id INTEGER PRIMARY KEY, payer_id INTEGER, name TEXT);
CREATE TABLE shipment (shipment_id TEXT PRIMARY KEY, site_id INTEGER);
INSERT INTO billing_customer VALUES (1, 'North Retail'), (2, 'South Wholesale');
INSERT INTO delivery_site VALUES (1, 2, 'Harbor depot'), (2, 1, 'Hill depot');
INSERT INTO shipment VALUES ('S1', 1), ('S2', 2);
''')
wrong = conn.execute('''
SELECT s.shipment_id, b.name
FROM shipment s JOIN billing_customer b ON b.payer_id = s.site_id
ORDER BY s.shipment_id
''').fetchall()
correct = conn.execute('''
SELECT s.shipment_id, b.name
FROM shipment s
JOIN delivery_site d ON d.site_id = s.site_id
JOIN billing_customer b ON b.payer_id = d.payer_id
ORDER BY s.shipment_id
''').fetchall()
print('same-shaped IDs:', wrong)
print('explicit mapping:', correct)
assert correct == [('S1', 'South Wholesale'), ('S2', 'North Retail')]
# same-shaped IDs: [('S1', 'North Retail'), ('S2', 'South Wholesale')]
# explicit mapping: [('S1', 'South Wholesale'), ('S2', 'North Retail')]

Both queries return two rows, so a row-count check alone misses the error. The mapping in this fixture is supplied domain evidence. In a real system, verify its owner, current validity, tenant scope and change history. The example does not establish that every site has exactly one payer forever.

Trust concerns permissions as well as identity

Authentication identifies the caller or service. Authorization decides which objects and actions that identity may access. A broad service credential must not erase the end user's restrictions when returning results.

For retrieval, enforce the applicable permissions before unauthorized content reaches model context or the response. Ingestion filters, tenant-specific indexes and current query-time checks may work together; the right design depends on access changes and the serving paths. “Query time instead of ingestion” is an incomplete rule when caches, embeddings, direct fetches and revoked grants also need controls.

Trace the grant source and its freshness. Test at least an allowed user, a denied user, a revoked grant and a cache hit. A document omitted from the UI can still leak if its text reaches the model or a downloadable endpoint. Keep authorization outside model-generated claims.

Network connectivity is necessary but not permission

Describe the source, destination, port/protocol, DNS, proxy, TLS requirements, credentials and approval owner. A successful call from a laptop does not establish the deployed workload can make it. A route being technically reachable does not authorize sending customer data through it.

If an external service is unavailable or disallowed, a queue can decouple timing but cannot make the route permitted. A cache can reduce calls but introduces storage, staleness and access questions. An approved local alternative or a different workflow may be needed. Do not propose queueing forever as a solution to a permanently prohibited destination.

Use bounded checks from the intended environment under the actual network process. Record whether a failure was DNS, connection, TLS, authentication, authorization or application behavior. These layers can produce similar symptoms but need different owners and repairs.

Calculate the dependency path

The slowest request is not automatically the whole project timeline. Some prerequisites run in parallel, while integration verification may start only after several finish.

In this synthetic plan, a route review takes five working days, an identity review takes three and implementation takes four. Assume all three can start together with separate assigned capacity. The end-to-end check needs both approvals and the implementation, then takes two days. Earliest completion is max(5, 3, 4) + 2 = 7 working days under those assumptions.

If identity review cannot start until the route review finishes, the path becomes 5 + 3 + 2 = 10 days, assuming implementation still finishes in parallel. If the same engineer must implement and perform another task, capacity may change the schedule again. Record dependency and staffing assumptions rather than reporting the largest single number as the answer.

Write the boundary register

For the freight path, use one row per important crossing: producer and consumer, data meaning, current owner, permitted identity/action, route, contract/version, failure behavior and evidence status. Link the source of each decision.

A useful unresolved row says “payer mapping history not supplied; billing data owner to confirm changes before historical reporting.” It does not say “billing is the blocker.” The former identifies a testable dependency; the latter turns uncertainty into blame.

What an arrow has to say before you trust it 1 Producer and consumer one row per crossing 2 Who owns changes and who can authorize a fix 3 Identity and permission enforced before the model sees it 4 The approved route reachable is not permitted 5 What the word means on each side of the arrow 6 Failure behavior and who is told 7 Evidence status per row, with its source Authentication identifies the caller; authorization decides what that identity may reach. Test an allowed user, a denied user, a revoked grant and a cache hit. A document hidden from the interface can still leak if its text reaches the model or a downloadable endpoint. A successful call from a laptop does not establish that the deployed workload can make it. A queue decouples timing but cannot make a prohibited destination permitted, and a cache adds storage, staleness and access questions of its own. Billing's customer is the legal party paying the invoice. Dispatch's customer is the delivery site. Both are small integers, and equal integers do not establish equal entities, so a row-count check misses the error entirely. "Payer mapping history not supplied, billing data owner to confirm before historical reporting" names a testable dependency. "Billing is the blocker" turns uncertainty into blame and closes nothing.

The spine below is one row of the boundary register, drawn as the order you fill it in, from the two ends of the arrow to the evidence behind every claim on it.

Do this before moving on

Run the join fixture. Change the site-to-payer mappings and verify the explicit join follows them while the same-shaped-ID join remains wrong. Add a missing site mapping and decide how the real workflow should expose that unresolved shipment; an inner join silently omits it, so a reconciliation count or left join may be required.

Write three negative checks for the trust boundary, including revoked access and a cached response. For a proposed external route, state both connectivity and data-use prerequisites. Explain why adding a queue does not waive either.

Finally, calculate the seven-day and ten-day dependency plans and identify the assumptions that distinguish them. Your boundary register passes when it names decisions, contracts and evidence instead of relying on a box label or a handshake in the architecture diagram.

Go deeper

Key takeaways

  • Boundaries require contracts for responsibility, meaning, permissions and connectivity.
  • An ownership boundary permits coordinated repair; it does not justify silent transformation or automatic partial processing.
  • Equal field types and row counts do not establish equivalent domain meaning.
  • Apply permission controls across all serving paths, including caches and current grants.
  • Plan from dependencies and capacity, not only the longest individual request.

Check yourself

Answer before you look. Recalling it is what makes it stick; recognising it does not.

  1. 1Both joins return two rows. Does that establish the payer attribution is correct?

  2. 2An external endpoint is prohibited. Does putting requests in a queue make the integration acceptable?

  3. 3Parallel tasks take five, three and four days, followed by two days of checking. What is the earliest completion under the supplied independent-capacity assumption?

Sign in to track which lessons you have finished.