php artisan boost:add-skill contentful/core
Save this content to: AGENTS.md
---
package: contentful/core
source_path: AGENTS.md
repo: https://github.com/contentful/contentful-core.php
---
# Agent Guide
<!-- Generated by seed-golden-context | Last updated: 2026-05-11 -->
Read this file first. It tells you where to find context in this repo.
## Quick Reference
| What you need | Where to look |
|---|---|
| How this repo is structured | [ARCHITECTURE.md](./ARCHITECTURE.md) |
| How to build/test/run | [CONTRIBUTING.md](./CONTRIBUTING.md) |
| Why decisions were made | [docs/ADRs/](./docs/ADRs/) |
| What this repo does | [README.md](./README.md) |
| PR review rules | [.bito/guidelines/](./.bito/guidelines/) |
| Active specs/work | [docs/specs/](./docs/specs/) |
## Sharp Edges & Invariants
- **This is a shared foundation library — never add Delivery- or Management-specific logic here.** Both `contentful.php` and `contentful-management.php` depend on this package. Coupling it to either SDK's domain leaks the abstraction and breaks the other.
- **Backward compatibility is a hard constraint.** Any public type, interface, or constructor signature change requires a major version bump under Semver. The CI backwards-compatibility check (`composer run test-for-bc-breaks`) is authoritative — do not merge if it fails without an explicit justification and major version bump.
- **Dropping a PHP version is a breaking change.** Removing support for a PHP version must be accompanied by a major version bump, regardless of whether any source-level changes are required.
- **Never invent or hard-code API error IDs.** The exception-dispatch mechanism in `Requester` maps `sys.id` values from the Contentful API response to typed exception classes dynamically. Adding a new exception class is correct; hard-coding error string literals elsewhere is not.
- **PSR interfaces at the boundary.** `BaseClient` accepts `LoggerInterface` and `HttpClient` via constructor. Do not introduce concrete logger or HTTP client dependencies into library source — keep injection as the pattern.
- **`X-Contentful-User-Agent` header format is load-bearing.** Contentful's API uses this header for analytics and support. The `UserAgentGenerator` format (`app name/ver; integration name/ver; sdk name/ver; platform PHP/X.Y.Z; os Linux;`) must not be changed without coordinating with the API team.
- **`composer run test-for-bc-breaks` requires `fetch-depth: 0` in CI.** It diffs against git history — shallow clones will produce false positives.
- **All dev tooling runs inside the devcontainer.** Do not attempt to run `composer install`, PHPStan, or php-cs-fixer directly on the host; use `devcontainer exec` or open the repo in VS Code Dev Containers. See CONTRIBUTING.md.
## Key Conventions
- **Commit format:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, etc.)
- **Branch strategy:** `master` is the stable/release branch. Feature work on `feat/` or `chore/` branches, merged via PR.
- **Test location:** `tests/Unit/` mirroring `src/` namespace structure. Fixture JSON in `tests/Fixtures/`.
- **Concrete implementations for testing:** `tests/Implementation/` — test-only concrete subclasses of abstract classes
- **PHP version:** 8.0 minimum. Do not use syntax or functions unavailable in PHP 8.0 without bumping the constraint in `composer.json`.
## Integration Points
**Upstream (this repo consumes):**
- Contentful REST APIs (CDA + CMA) via Guzzle
**Downstream (consumes this repo):**
- `contentful.php` — Delivery SDK
- `contentful-management.php` — Management SDK
- `ContentfulBundle` — Symfony integration (transitive)
- `contentful-laravel` — Laravel integration (transitive)
## Build & Quality
```bash
# Full verification loop (run inside devcontainer)
composer install -n --prefer-dist
composer run lint-static-analysis
composer run test-for-bc-breaks
composer run test-quick-fail
```
Read this file first. It tells you where to find context in this repo.
| What you need | Where to look |
|---|---|
| How this repo is structured | ARCHITECTURE.md |
| How to build/test/run | CONTRIBUTING.md |
| Why decisions were made | docs/ADRs/ |
| What this repo does | README.md |
| PR review rules | .bito/guidelines/ |
| Active specs/work | docs/specs/ |
contentful.php and contentful-management.php depend on this package. Coupling it to either SDK's domain leaks the abstraction and breaks the other.composer run test-for-bc-breaks) is authoritative — do not merge if it fails without an explicit justification and major version bump.Requester maps sys.id values from the Contentful API response to typed exception classes dynamically. Adding a new exception class is correct; hard-coding error string literals elsewhere is not.BaseClient accepts LoggerInterface and HttpClient via constructor. Do not introduce concrete logger or HTTP client dependencies into library source — keep injection as the pattern.X-Contentful-User-Agent header format is load-bearing. Contentful's API uses this header for analytics and support. The UserAgentGenerator format (app name/ver; integration name/ver; sdk name/ver; platform PHP/X.Y.Z; os Linux;) must not be changed without coordinating with the API team.composer run test-for-bc-breaks requires fetch-depth: 0 in CI. It diffs against git history — shallow clones will produce false positives.composer install, PHPStan, or php-cs-fixer directly on the host; use devcontainer exec or open the repo in VS Code Dev Containers. See CONTRIBUTING.md.feat:, fix:, chore:, docs:, etc.)master is the stable/release branch. Feature work on feat/ or chore/ branches, merged via PR.tests/Unit/ mirroring src/ namespace structure. Fixture JSON in tests/Fixtures/.tests/Implementation/ — test-only concrete subclasses of abstract classescomposer.json.Upstream (this repo consumes):
Downstream (consumes this repo):
contentful.php — Delivery SDKcontentful-management.php — Management SDKContentfulBundle — Symfony integration (transitive)contentful-laravel — Laravel integration (transitive)# Full verification loop (run inside devcontainer)
composer install -n --prefer-dist
composer run lint-static-analysis
composer run test-for-bc-breaks
composer run test-quick-fail
How can I help you explore Laravel packages today?