Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3392fd1
refactor: rename Headers::fromHeaderables to Headers::from
gustavofreze May 15, 2026
57aff70
refactor: add named arguments at every own-code call site
gustavofreze May 15, 2026
63ea250
feat: encapsulate header operations in Headers VO with fromMessage an…
gustavofreze May 15, 2026
f4e9d9d
fix: remove JSON_INVALID_UTF8_SUBSTITUTE so invalid UTF-8 surfaces as…
gustavofreze May 15, 2026
9243245
refactor: reorder body before code in Server\Response::from and Respo…
gustavofreze May 15, 2026
5c326e1
refactor: make Http constructor private and introduce Http::with stat…
gustavofreze May 15, 2026
604517b
fix: restore JSON_INVALID_UTF8_SUBSTITUTE, remove json_encode try/cat…
gustavofreze May 15, 2026
e8f6294
docs(rules): expand PHPDoc rule to cover concrete entry-point classes
gustavofreze May 15, 2026
b805bf8
docs: add PHPDoc to Http and HttpBuilder public entry-point methods
gustavofreze May 15, 2026
68a8c94
docs: rewrite README for v2 public API
gustavofreze May 15, 2026
968aa1c
refactor: collapse NetworkTransport::with to single intersection-type…
gustavofreze May 15, 2026
4d57819
feat: add UserAgent value object with empty-version normalization
gustavofreze May 15, 2026
03404e2
docs: update NetworkTransport examples to new factory signature, add …
gustavofreze May 15, 2026
40339ad
chore: tighten validation gates and fix README PHP syntax
gustavofreze May 15, 2026
8ea0d84
refactor(exceptions): flatten hierarchy and unify HttpException contract
gustavofreze May 15, 2026
6047912
refactor: align public surface with v2 contract
gustavofreze May 15, 2026
ff54d54
chore(code-style): close remaining audit findings in src/
gustavofreze May 15, 2026
e9947bf
test: align tests with the v2 contract
gustavofreze May 15, 2026
38af453
docs: polish README for the flattened exception hierarchy
gustavofreze May 15, 2026
8a4fd18
chore(quality): clean every gate at level 9 with 100% MSI
gustavofreze May 15, 2026
45d5de1
chore: Update Claude rule files and Copilot instructions.
gustavofreze May 16, 2026
3dee2bc
docs: Expand README and add SECURITY policy.
gustavofreze May 16, 2026
017caab
build: Adjust composer, static analysis, test and editor configs.
gustavofreze May 16, 2026
60c9764
ci: Update GitHub workflow and add issue and pull request templates.
gustavofreze May 16, 2026
f524628
refactor: Reorganize namespaces and expose decoded server primitives.
gustavofreze May 16, 2026
b0133db
test: Restructure unit tests around public entry points.
gustavofreze May 16, 2026
f6d07a1
ci: Enhance GitHub workflows with concurrency settings and timeout ad…
gustavofreze May 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 16 additions & 32 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,16 @@
# Project

PHP library (tiny-blocks ecosystem). Self-contained package: immutable models, zero infrastructure
dependencies in core, small public surface area. Public API at `src/` root; implementation details
under `src/Internal/`.

## Rules

All coding standards, architecture, naming, testing, and documentation conventions
are defined in `rules/`. Read the applicable rule files before generating any code or documentation.

## Commands

- `make test` — run tests with coverage.
- `make mutation-test` — run mutation testing (Infection).
- `make review` — run lint.
- `make help` — list all available commands.

## Post-change validation

After any code change, run `make review`, `make test`, and `make mutation-test`.
If any fails, iterate on the fix while respecting all project rules until all pass.
Never deliver code that breaks lint, tests, or leaves surviving mutants.

## File formatting

Every file produced or modified must:

- Use **LF** line endings. Never CRLF.
- Have no trailing whitespace on any line.
- End with a single trailing newline.
- Have no consecutive blank lines (max one blank line between blocks).
# CLAUDE.md

This is a PHP library in the tiny-blocks ecosystem. Detailed rules live in `.claude/rules/`.
Each file is scoped via its `paths` frontmatter. Read the relevant file before producing or
editing content under its scope.

## Rule files

- `php-library-architecture.md` — folder structure, public API boundary, `Internal/` semantics.
- `php-library-code-style.md` — semantic code rules for `.php` files in `src/` and `tests/`.
- `php-library-commits.md` — Conventional Commits format. Applied only when generating commit messages.
- `php-library-documentation.md` — README and Markdown documentation standards.
- `php-library-github-workflows.md` — CI workflow structure and action pinning.
- `php-library-modeling.md` — nomenclature, value objects, exceptions, enums, complexity.
- `php-library-testing.md` — BDD Given/When/Then, PHPUnit conventions, coverage discipline.
- `php-library-tooling.md` — canonical config files (`composer.json`, `phpcs.xml`, etc).
78 changes: 0 additions & 78 deletions .claude/rules/github-workflows.md

This file was deleted.

145 changes: 145 additions & 0 deletions .claude/rules/php-library-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
description: Folder structure, public API boundary, and Internal/ semantics for PHP libraries.
paths:
- "src/**/*.php"
---

# Architecture

Covers the physical layout of the library. Folder structure, the boundary between public API and
implementation detail, and where each type of class lives. Semantic rules (value objects,
exceptions, enums, complexity, nomenclature) live in `php-library-modeling.md`. Code style lives
in `php-library-code-style.md`.

## Pre-output checklist

Verify every item before producing or relocating any file. If any item fails, revise before
outputting.

1. None of the following folder names exist in `src/`: `Models/`, `Entities/`, `ValueObjects/`,
`Enums/`, `Domain/`. They carry no semantic content and conflate technical role with domain
meaning.
2. The `src/` root contains only interfaces, extension points, public enums, thin orchestration
classes, and primary implementations or façades. Substantial logic (algorithms, state machines,
I/O) lives in `src/Internal/`, never at the root.
3. `src/Internal/` is implementation detail and not part of the public API. Breaking changes
inside `src/Internal/` are not semver-breaking.
4. Consumers must not reference, extend, or depend on any type inside `src/Internal/`. The
namespace itself is the boundary.
5. Public exception classes live in `src/Exceptions/`.
6. Internal exception classes live in `src/Internal/Exceptions/`.
7. Public enums live at the `src/` root or inside a public `<ConceptGroup>/` folder. Enums used
only by internals live in `src/Internal/`.
8. Public interfaces live at the `src/` root or inside a public `<ConceptGroup>/` folder.
9. A `<ConceptGroup>/` folder at the `src/` root groups related public types under a shared
concept. Each group has its own namespace and is part of the public API.
10. `<ConceptGroup>/` is optional. Use it only when the library exposes several coherent groups of
types (for example, aggregates and events) rather than a flat set of types around a single
concept.
11. Test fixtures representing domain concepts live in `tests/Models/`. Test doubles for system
boundaries live at the root of `tests/Unit/` or `tests/Integration/`. No dedicated `Mocks/`
or `Doubles/` subdirectory exists. `tests/Drivers/<Vendor>/` is permitted when the library
exposes a port exercised against multiple third-party implementations (PSR adapters,
framework integrations). Each `<Vendor>/` subdir holds tests against one specific
implementation.
12. The `tests/Integration/` folder exists only when the library interacts with external
infrastructure (filesystem, database, network). Otherwise, the folder is absent.

## Folder structure

Canonical layout for a PHP library in the tiny-blocks ecosystem.

```
src/
├── <PublicInterface>.php # public contract at root
├── <Implementation>.php # main implementation or extension point at root
├── <PublicEnum>.php # public enum at root
├── <ConceptGroup>/ # public folder grouping related public types under a shared concept
│ ├── <PublicType>.php
│ └── ...
├── Internal/ # implementation details, not part of the public API
│ ├── <Collaborator>.php
│ └── Exceptions/ # internal exception classes
└── Exceptions/ # public exception classes

tests/
├── Models/ # domain fixtures reused across tests
├── Unit/ # unit tests targeting the public API
│ ├── <SomeMock>.php # test doubles at root of Unit/
│ └── <SomeSpy>.php
└── Integration/ # only present when the library interacts with infrastructure
└── <SomeMock>.php # test doubles at root of Integration/ when needed
```

Never use `Models/`, `Entities/`, `ValueObjects/`, `Enums/`, or `Domain/` as folder names. They
carry no semantic content and describe technical role instead of domain meaning.

## Public API boundary

The `src/` root is the contract. Everything at the root, plus everything inside public
`<ConceptGroup>/` folders and the public `Exceptions/` folder, is what consumers depend on. Changes
to these types follow semver rules.

`src/Internal/` is implementation detail. The namespace itself signals the boundary. Consumers
must not depend on any type inside `src/Internal/`. Breaking changes inside `src/Internal/` are
not semver-breaking for the library.

### What lives at the public boundary

- Interfaces that define contracts for consumers.
- Extension points designed to be subclassed or composed by consumers.
- Public enums and value objects consumers manipulate directly.
- Thin orchestration classes that wire collaborators together without containing substantial logic.
- Public exception classes consumers may catch.

### What lives in `src/Internal/`

- Algorithms, state machines, and complex transformations.
- Adapters for I/O (filesystem, network, database).
- Collaborators that exist purely to break a public class into testable units.
- Implementation details that may change between minor or patch releases.
- Internal exception classes raised by collaborators.

## Reference examples

### Small library with flat root

```
src/
├── Timezone.php # public value object
├── Timezones.php # public collection
├── Clock.php # public interface
└── Internal/
├── SystemClock.php # default Clock implementation
└── Exceptions/
└── InvalidTimezone.php
```

Everything lives at the root or inside `Internal/`. No `<ConceptGroup>/` folders. Suitable when
the library exposes a small, cohesive set of types around a single concept.

### Library with public concept groups

```
src/
├── ValueObject.php # public extension point at root
├── Aggregate/ # public namespace grouping aggregate types
│ ├── AggregateRoot.php
│ ├── EventualAggregateRoot.php
│ └── ModelVersion.php
├── Event/ # public namespace grouping event types
│ ├── EventRecord.php
│ ├── EventRecords.php
│ └── SequenceNumber.php
├── Internal/
│ ├── DefaultModelVersionResolver.php
│ └── Exceptions/
│ └── InvalidSequenceNumber.php
└── Exceptions/
└── EventRecordingFailure.php
```

`Aggregate/` and `Event/` are public folders at the root, each grouping a coherent set of public
types under one shared concept. Consumers import directly, for example
`TinyBlocks\<LibName>\Aggregate\AggregateRoot`. Suitable when the library exposes several distinct
concept areas, each with its own set of related types.
Loading