← Security and risk guides

How to prevent agents from adding forbidden dependencies

How-To Security and risk Intermediate 1161002HOWTO-1161002

HOWTO-1161002Security and riskIntermediate

This guide shows you how to prevent agents from adding forbidden dependencies with SpecDD in a spec-driven development workflow.

Agents often solve the local problem they see. If the fastest path is importing a convenient module, calling a provider SDK directly, or reading a sensitive file, they may choose it unless the boundary is explicit. Forbids turns that boundary into a durable spec rule.

Short answer

Use Forbids to block dependencies, paths, modules, libraries, tools, or access patterns. Write allowed dependencies in Depends on, but remember that Depends on does not override inherited Forbids or Must not. Add static checks or review evidence in Done when for important dependency boundaries.

When to use this guide

Use this guide when:

Steps

1. Identify the dependency risk

Name the shortcut you want to prevent.

Examples:

Be specific. A precise Forbids entry is easier to enforce than a broad warning.

2. Write explicit Forbids entries

Use Forbids for blocked dependencies, paths, modules, libraries, tools, or access.

Spec: Billing API

Owns:
  ./billing-api.ts
  ./billing-api.test.ts

Forbids:
  Direct use of the payment provider SDK outside ../payment-provider/*
  Direct database writes outside ../billing-repository/*
  Reading secrets from checked-in files.

Use explicit paths when a path boundary matters:

Forbids:
  ../payment-provider/private/*
  ../../secrets/*

Forbids may contain prose as well as paths, but paths make review and automation easier.

3. Pair forbidden dependencies with allowed dependencies

Blocking a shortcut is clearer when the approved path is also visible.

Depends on:
  ../payment-provider/payment-provider-port.sdd
  BillingRepository

Forbids:
  Direct use of the payment provider SDK outside ../payment-provider/*
  Direct writes to billing tables outside BillingRepository.

This tells humans and agents both what not to do and what to use instead.

4. Put broad rules at the right level

If a dependency rule applies to every file in an area, put it in the parent spec for that area.

Spec: Domain Layer

Purpose:
  Keep business rules independent from infrastructure and UI frameworks.

Forbids:
  ../adapters/*
  ../ui/*
  Framework-specific request or response objects.

Child specs inherit the parent constraint. A child task cannot bypass it by adding a conflicting Depends on entry.

5. Add static or review evidence

Dependency boundaries are usually better checked statically than with unit tests.

Done when:
  Import-boundary check passes for domain-to-adapter rules.
  No billing API file imports the payment provider SDK directly.
  Dependency changes are reviewed against the Billing API spec.

Possible evidence:

Use whatever fits the project’s normal tooling. The spec should name the evidence, not invent a separate test framework.

6. Review dependency changes before approving

When a pull request changes imports, packages, or Forbids, ask:

Removing a Forbids entry because the current implementation wants it is usually a design review, not a small cleanup.

Example

Spec: Account Export API

Purpose:
  Serve authenticated account export requests through the approved export service.

Owns:
  ./account-export-api.ts
  ./account-export-api.test.ts

Can modify:
  ./account-export-api.ts
  ./account-export-api.test.ts

Depends on:
  ../account-export/account-export-service.sdd
  ../auth/session-validation.sdd

Must:
  Require authenticated account context before starting an export.
  Return the approved export job identifier when the request is accepted.

Must not:
  Read account data directly from persistence.
  Expose export data in the immediate API response.

Forbids:
  ../repositories/*
  Direct object storage access from the API route.
  New export-specific package dependencies without review.

Done when:
  Account export API imports only approved service and auth contracts.
  Direct repository and object storage imports are absent.
  Existing API authorization checks pass.

Prompt for review:

Check whether the account export API change introduces forbidden dependencies.

Common mistakes

How to verify the result

Forbidden dependencies are controlled when:

← Security and risk guides