What problem does it solve? Integrating a language model into an application without leaking vendor SDK details everywhere is hard: timeouts hang, errors arrive unclassified, and structured outputs pass schema checks while being useless. This Skill defines how to build and maintain a vendor-neutral LlmPort layer under src/ai/ so providers can be swapped with a bounded edit. ## Core Features & Use Cases - Port vs. adapter boundaries: Defines what belongs on the vendor-neutral LlmPort interface versus construction-time adapter configuration, with ESLint and module-graph gates keeping SDK imports inside src/ai/adapters/. - Two-layer structured output validation: Sends a JSON Schema derived from the caller's Zod schema to the provider, then re-validates the answer with safeParseAsync so refinements the conversion dropped still fail as ERR_LLM_INVALID_OUTPUT. - Deadline and error mapping: Composes per-attempt timeouts, a total adapter deadline via AbortSignal.any, and caller signals, and maps every provider failure onto the ERR_LLM_* union by caller remedy. - Use Case: When adding a second provider adapter, follow references/adding-an-adapter.md to implement the port, wire the contract suite in tests/ai-port.test.ts, and update the gate files without touching application code. ## Quick Start Ask the AI to add a new LLM provider adapter under src/ai/adapters/ following the integrating-llm guidelines and its contract test harness.