AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MPL-2.0 Self-run

Infrastructure Boundaries

skill-garrettw-php-arch-skills-infrastructure-boundaries · by garrettw

Use this skill when integrating third-party APIs, SDKs, or infrastructure services (like search engines or email). Provides rules for designing provider adapters/gateways, handling webhooks, and preventing vendor lock-in.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-garrettw-php-arch-skills-infrastructure-boundaries

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-garrettw-php-arch-skills-infrastructure-boundaries)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
23d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Infrastructure Boundaries? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Infrastructure & Integration Boundaries in PHP

When to Use Hexagonal Architecture (and When NOT to)

Hexagonal architecture isolates the core via ports and adapters, but it is not universal. Use it for long-lived applications that need to swap infrastructure or require high test coverage. Skip it for libraries, simple CRUD APIs, or throwaway utilities.

| Use Hexagonal For | Use Simpler Patterns For | |-----------------------------------------------------|-----------------------------------------------------------| | Long-lived application with evolving infrastructure | Libraries, packages, SDKs (PSR standards usually suffice) | | Need to swap DB, broker, or external API | Fixed infrastructure, unlikely to change | | Multiple entry points (API, CLI, events) | Single delivery channel | | High test coverage required | Quick scripts, internal tools |

For libraries, package your code with PSR-4 autoloading and clear namespacing. Let the consumer inject dependencies. Do not add a hexagonal adapter layer for a library.

System Overview

The Infrastructure layer contains everything that speaks to the outside world: databases, search engines, APIs, message queues, and the filesystem. It implements adapters (driven and driver) that fulfill ports defined by inner layers. This skill provides the rules for keeping infrastructure concerns separated from domain logic through adapters, ports, and proper placement.

A [Gateway](references/gateway.md) is the classic name for exactly this seam: an object that encapsulates communication with one external system so the application knows that the call happened, not how. In modern terms a Gateway is a Port + Adapter. Name it after the business capability (PaymentGateway), never the transport or vendor (StripeHttpWrapper).

A [Mapper](references/mapper.md) is the companion translation object at the same seam: it converts between two representations of the same fact (domain object ↔ DTO, domain ↔ external API model) while preserving meaning. It is not a Transformer — never put business rules in a mapper. The persistence-specific instance is the Data Mapper in [persistence-patterns](../persistence-patterns/references/data-mapper.md).

These two are boundary-protection patterns: a Gateway protects the infrastructure boundary and a Mapper protects the model boundary. They sit alongside Remote Facade / DTO (process & representation), Plugin (framework/extension), and Special Case (behavioral) in a shared family — see [boundary-protection-patterns.md](../distribution-patterns/references/boundary-protection-patterns.md) for how they map onto Hexagonal architecture.

Numbered Workflows

1. Placing Code in the Right Layer

If adding a new integration or third-party service:

  1. Define the Port. Create an interface in the Domain or Application layer that describes what the application needs in business terms.
  2. Implement the Adapter. Create the implementation class in the Infrastructure layer, using the specific vendor SDK.
  3. Verify Imports. Ensure the Domain/Application code only imports the interface, never the vendor SDK or HTTP client.

1.5. Classifying the Adapter

If determining where a new adapter belongs:

  1. Driver Adapters. Does the adapter receive external input and trigger application logic (e.g., HTTP controllers, CLI commands, message queue consumers)? Place it in Infrastructure/Http or the equivalent driver layer.
  2. Driven Adapters. Does the adapter implement an external concern called by the application (e.g., database repository, email sender, search engine client)? Place it in Infrastructure/Persistence, Infrastructure/Messaging, or the equivalent driven layer.
  3. Composition Root. Wire all adapter implementations to their ports in a single location (e.g., the DI configuration or the framework bootstrap) to keep the dependency rule intact.

2. Designing a Provider Adapter

If building a new infrastructure adapter:

  1. Define Inputs. The adapter must take primitive values or domain value objects, not framework request objects.
  2. Translate Exceptions. Catch vendor-specific exceptions (e.g., GuzzleHttp\Exception\ClientException) and wrap them in domain-meaningful exceptions defined by the port (e.g., PaymentFailedException).
  3. Format Outputs. Return primitive values, generic DTOs, or domain objects—never the raw vendor response object (e.g., Stripe\Charge).
  4. Reference Examples. Check the [Adapter Design Examples](references/adapter-design-examples.md) for structural patterns.

3. Handling Webhooks and Callbacks

If building an endpoint to receive a vendor webhook:

  1. Authenticate. Verify the webhook signature in an HTTP middleware or controller.
  2. Parse. Extract the relevant data from the vendor-specific payload into a generic DTO or array.
  3. Hand Off. Pass the domain-neutral facts to an application handler to execute the business use case.

Boundaries

Always Do

  • Always treat third-party integrations (like a CRM) and infrastructure systems (like a search engine) as infrastructure adapters (Gateways), not bounded contexts.
  • Always name a Gateway after the business capability it provides (PaymentGateway, SearchIndex, Mailer), never the vendor or transport (StripeHttpWrapper, ElasticsearchHttpClient).
  • Always limit a Mapper to representation conversion only — preserve meaning, never embed business rules or derivation (that belongs in the domain or an application-layer operation).
  • Always inject configuration values (like feature flags) into domain objects as simple scalar values (e.g., bool $isNewFeatureEnabled) via constructors.

Ask First

  • Ask before passing a ConfigResolver or FeatureFlagClient directly into a domain object or application handler.

Never Do

  • Never let vendor-specific exceptions bubble up to the application layer.
  • Never pass the entire configuration object or framework container into an adapter. Inject only the specific credentials or clients the adapter needs.
  • Never mix Domain code with infrastructure SDKs.
  • Never violate the dependency rule: Domain must not import database, HTTP, or messaging libraries. If it does, the boundary is broken.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.