Surface Spectral's features so AI agents use them - #21
Conversation
AI agents building APIs with PhoenixSpectral underuse Spectral's capabilities because the library's docs never enumerate them, link only to GitHub rather than hexdocs, and the example demonstrates only a subset. Agents act on what's in front of them, so the fix is discoverability, not code. - README: add a "Going further with Spectral" feature-reference table (string constraints, field aliases, only, struct defaults, enums, codecs, type docs) with hexdocs links and a worked type_parameters example; re-point all Spectral links from GitHub to hexdocs. - Add AGENTS.md: an agent-facing "I'm tempted to... -> use this instead" map, wired into ExDoc extras and the hex :files so it ships; tells downstream maintainers to copy it into their own AGENTS.md. - Example: demonstrate declarative validation via type_parameters string constraints on a named type, with a test proving a too-short name returns 400. - Moduledocs: add "Powered by Spectral" callouts with auto-linked Spectral.* refs on the pages agents land on first.
| Phoenix `(conn, params)`. Request data is decoded and validated against your typespecs, | ||
| and responses are encoded automatically. | ||
|
|
||
| > #### Powered by Spectral {: .info} |
There was a problem hiding this comment.
I don't understand this.
There was a problem hiding this comment.
Replaced the verbose admonition with one plain sentence pointing at the Spectral docs. Fixed in fa381a5.
| # A named type with `type_parameters` string constraints. No custom codec is | ||
| # needed: Spectral enforces min/max length (and `pattern`, `format`) on both | ||
| # decode and encode, and emits minLength/maxLength into the OpenAPI schema. | ||
| # A name shorter than 2 or longer than 50 characters fails with a 400. |
There was a problem hiding this comment.
This comment is too long.
| @@ -0,0 +1,38 @@ | |||
| # AGENTS.md | |||
There was a problem hiding this comment.
Hmm, maybe a little bit to much focus on delegating to spectral.
There was a problem hiding this comment.
Agreed — removed AGENTS.md entirely (and its mix.exs wiring). The README/example/moduledoc changes carry the feature pointers without the heavy delegation framing. Fixed in fa381a5.
| | Accept an enum from a path/query param (e.g. `?role=admin`) | an atom-union type `:: :admin \| :user`, decoded via the `binary_string` format | [Data Serialization API](https://hexdocs.pm/spectral/readme.html#data-serialization-api) | | ||
| | Serialize `DateTime`, `Date`, or `MapSet` | the built-in codecs (registered automatically) | [Built-in Codecs](https://hexdocs.pm/spectral/readme.html#built-in-codecs) | | ||
| | Encode/decode a domain type with custom rules (prefixed IDs, money, etc.) | `use Spectral.Codec` | [Custom Codecs](https://hexdocs.pm/spectral/readme.html#custom-codecs) | | ||
| | Reuse one codec across types with different config | `spectral type_parameters: …` read as the codec's `params` argument | [Codec-specific configuration](https://hexdocs.pm/spectral/readme.html#codec-specific-configuration) | |
There was a problem hiding this comment.
I don't want to highlight this specific feature as I think it was a misstake.
There was a problem hiding this comment.
Removed the codec-specific-configuration row from the table. The string-constraints use of type_parameters stays, since that wasn't flagged — let me know if you'd rather drop that too. Fixed in fa381a5.
- Remove AGENTS.md and its mix.exs wiring — too much focus on delegating to Spectral (reviewer feedback). - Simplify the Controller moduledoc note from a verbose admonition to one clear sentence. - Trim the overlong type_parameters comment in the example to one line. - Drop the "codec-specific configuration" row from the README feature table — maintainer considers type_parameters-as-codec-params a mistake and doesn't want it highlighted.
There was a problem hiding this comment.
Pull request overview
This PR improves discoverability of Spectral features within PhoenixSpectral by expanding documentation, updating links to Spectral’s HexDocs, and updating the example app to demonstrate type_parameters string constraints (with a test).
Changes:
- Expanded README with a “Going further with Spectral” capability→link reference table and updated Spectral/spectra links to HexDocs.
- Added “powered by Spectral” pointers in key moduledocs to steer readers toward Spectral’s type-level features.
- Updated the example app to use a named
name()type withtype_parametersmin/max length constraints, plus a test asserting a too-short name returns 400.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds Spectral feature reference section + HexDocs links and example constraint snippet. |
| mix.exs | Bumps version to 0.6.1 and adds a Hex package link to Spectral docs. |
| lib/phoenix_spectral/controller.ex | Moduledoc callout pointing readers to Spectral docs for type shaping features. |
| lib/phoenix_spectral.ex | Moduledoc callout emphasizing schemas are derived from Spectral types. |
| example/lib/example/types.ex | Introduces name() type with type_parameters constraints and uses it in UserInput. |
| example/test/example_test.exs | Adds regression test asserting min-length constraint yields HTTP 400. |
| CHANGELOG.md | Documents the 0.6.1 documentation + example updates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Why
AI agents building APIs with PhoenixSpectral consistently underuse Spectral's features — string/length/pattern constraints, field aliases, custom codecs, the built-in date/time codecs. The cause is discoverability, not capability: an agent acts on what's in front of it, and PhoenixSpectral's docs mention Spectral only vaguely, link to its GitHub repo (not hexdocs), never enumerate what's available, and the example demonstrates only a subset. So agents hand-roll validation that Spectral does declaratively.
What changed
1. README — feature reference + hexdocs links
type_parametersconstraint example. Puts the menu directly in the agent's context.github.com/...tohexdocs.pm/...(with section anchors). Agents browsing hexdocs follow same-host links far more readily than jumping to GitHub.2. Example app — demonstrates declarative validation via
type_parameters: %{min_length: 2, max_length: 50}on a namednametype (the single most underused feature), with a test proving a too-short name returns 400. The example is the most-copied artifact, so agents imitate it.3. Moduledocs — pointers on
PhoenixSpectralandPhoenixSpectral.Controller(the hexdocs pages agents land on first) noting that schemas are derived from Spectral types, using backtickedSpectral.*refs that ExDoc auto-links into Spectral's docs.4. Packaging — a
Spectralcross-link added to the Hex packagelinks. Version bumped to 0.6.1 (docs-only patch release; see CHANGELOG).Review history
An earlier revision added an
AGENTS.mdagent entry point and a "Powered by Spectral" admonition in the controller moduledoc. Both were removed during review — the maintainer found the framing leaned too hard on "this is a thin shell, the real power is elsewhere." The remaining changes carry the feature pointers without that delegation framing.Design note
I deliberately enumerate-and-link rather than duplicate Spectral's docs into PhoenixSpectral — duplication drifts out of sync as Spectral evolves.
Verification
make ci(compile, test, credo, dialyzer, format) — passes, 0 dialyzer errors.cd example && mix test— 14 pass, including the newmin_lengthconstraint test.Note: no behavior change to the library itself — this is docs, one example type/test, and packaging metadata.