diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 90bff64..94cd7e1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ // Webware alignment Dev Container. // -// This is a thin wrapper around compose.yml — it reuses the `tooling` service +// This is a thin wrapper around compose.yml - it reuses the `tooling` service // rather than defining a parallel environment, so VS Code and plain // `docker compose` users share the exact same container. Non-VS Code // developers are not orphaned: they use `docker compose up -d` + diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 44c4048..1564245 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,12 +1,12 @@ -# Webware Message — Copilot Agent Instructions +# Webware Message: Copilot Agent Instructions -## Read this before acting — fleet working agreements +## Read this before acting: fleet working agreements `vendor/webware/webware-tools/agent-working-agreements.md` is authoritative for how work is done in this fleet, and it overrides anything else in this file or in any local note. Read it before acting, and again before reporting. The non-negotiables: -- Do exactly the scope asked — only the files, branches and repositories named. No adjacent edits, +- Do exactly the scope asked - only the files, branches and repositories named. No adjacent edits, no cleanup, no onboarding, no surveys. - Anything else you notice gets one line at most, with no proposed fix. - Never close a reply with a condensed restatement of it, and never present an inference as a @@ -21,22 +21,22 @@ PHPUnit 13 enforces a strict separation between mocks and stubs. Violating these - **Use `createStub()`** when the test double only needs to return values (`method()->willReturn()`, `method()->willReturnCallback()`). No expectations are configured. - **Use `createMock()`** only when the test verifies behavior with `expects()` (e.g. `expects($this->once())`, `expects($this->never())`). -- **Never** call `createMock()` without also calling `expects()` on at least one method — PHPUnit 13 will issue a notice. +- **Never** call `createMock()` without also calling `expects()` on at least one method - PHPUnit 13 will issue a notice. - **Remove** `/** @var ClassName&MockObject */` annotations and `MockObject` intersection types on variables created with `createStub()`. - **Remove** the `use PHPUnit\Framework\MockObject\MockObject;` import from any file where no `createMock()` + `expects()` usage remains. ### Examples ```php -// CORRECT — stub returns value, no expectations +// CORRECT - stub returns value, no expectations $container = $this->createStub(ContainerInterface::class); $container->method('get')->willReturnCallback(static fn(string $id): mixed => ...); -// CORRECT — mock verifies behavior with expects() +// CORRECT - mock verifies behavior with expects() $handler = $this->createMock(ErrorHandler::class); $handler->expects($this->once())->method('attachListener'); -// WRONG — createMock() with no expects() triggers PHPUnit notice +// WRONG - createMock() with no expects() triggers PHPUnit notice $logger = $this->createMock(Logger::class); $logger->method('withName')->willReturn($logger); // should be createStub() ``` @@ -45,6 +45,6 @@ $logger->method('withName')->willReturn($logger); // should be createStub() `phpunit.xml.dist` has `requireCoverageMetadata="true"`. Every test class **must** have: -1. `#[CoversClass(ClassName::class)]` — one per source class under test. -2. `#[CoversMethod(ClassName::class, 'methodName')]` — one per public/protected method exercised. +1. `#[CoversClass(ClassName::class)]` - one per source class under test. +2. `#[CoversMethod(ClassName::class, 'methodName')]` - one per public/protected method exercised. 3. `use PHPUnit\Framework\Attributes\CoversClass;` and `use PHPUnit\Framework\Attributes\CoversMethod;` imports. diff --git a/Dockerfile b/Dockerfile index 7e9cea2..4ff0c47 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # # Builds a self-contained, interactive PHP development environment carrying # the Webware toolchain: PHP CLI, Composer, Mago, and Xdebug. Developers work -# inside this container — either through the VS Code Dev Container (backed by +# inside this container: either through the VS Code Dev Container (backed by # compose.yml) or by `docker compose up -d` + `docker compose exec tooling`. # The host machine (Windows, WSL, Linux, or macOS) never needs a native PHP # toolchain. diff --git a/compose.yml b/compose.yml index 7f4bd9e..25fc10f 100644 --- a/compose.yml +++ b/compose.yml @@ -9,7 +9,7 @@ # This compose file is the single source of truth for the environment. Two # ways to use it: # -# 1. VS Code Dev Container — "Reopen in Container" uses +# 1. VS Code Dev Container: "Reopen in Container" uses # .devcontainer/devcontainer.json, which is *backed by* this file (it # references the `tooling` service rather than defining its own). # @@ -24,7 +24,7 @@ # Packages whose tests need MySQL uncomment the `mysql` service below (and the # `phpmyadmin` web UI if wanted), plus the `depends_on` block on `tooling`. The # `mysql` service mirrors the `db-image` package parameter used by CI, and is -# reachable from `tooling` as host `mysql` on port 3306 — matching the PhpDb +# reachable from `tooling` as host `mysql` on port 3306: matching the PhpDb # `mysql.local.php` connection convention. Packages that need a different # engine add an equivalent service here (postgres, mariadb, ...) mirroring # their own `db-image` parameter. @@ -57,7 +57,7 @@ services: volumes: # Bind-mount the source so edits are visible on both the host and the # container. vendor/ is deliberately overridden below with a named - # volume — do not bind-mount it from the host. + # volume - do not bind-mount it from the host. - .:/app # Named volumes keep vendor/ and the Composer cache on the Linux # filesystem. Bind-mounting vendor/ from a Windows host is extremely @@ -73,7 +73,7 @@ services: working_dir: /app # ------------------------------------------------------------------------- - # MySQL (optional) — uncomment this whole block for packages whose tests + # MySQL (optional) - uncomment this whole block for packages whose tests # need a MySQL database (e.g. webware-acl via php-db/phpdb-mysql). # # Mirror the spec's `db-image` / `db-env-json` / `db-port` Package Parameters @@ -99,7 +99,7 @@ services: # # survives `docker compose down` (use `down -v` to wipe it). # - mysql-data:/var/lib/mysql # - # # phpMyAdmin — optional web UI for the `mysql` service above. Reachable at + # # phpMyAdmin - optional web UI for the `mysql` service above. Reachable at # # http://localhost:8080 (log in with the MYSQL_* credentials). Uncomment # # alongside `mysql`. # phpmyadmin: diff --git a/docs/v1/configuration.md b/docs/v1/configuration.md index 337c80b..ee222dd 100644 --- a/docs/v1/configuration.md +++ b/docs/v1/configuration.md @@ -19,7 +19,7 @@ ] ``` -`SystemMessenger` is not a singleton — it is constructed per request from the +`SystemMessenger` is not a singleton - it is constructed per request from the session by `MessageMiddleware`. ## View Helpers diff --git a/docs/v1/installation.md b/docs/v1/installation.md index 635760e..d901d14 100644 --- a/docs/v1/installation.md +++ b/docs/v1/installation.md @@ -4,7 +4,7 @@ - PHP 8.4.1 or later - A Mezzio application (PSR-11 container, PSR-15 middleware) -- Session middleware in the pipeline — the message middleware reads the +- Session middleware in the pipeline - the message middleware reads the session from `SessionMiddleware::SESSION_ATTRIBUTE` ## Composer diff --git a/docs/v1/messenger.md b/docs/v1/messenger.md index 3cce3d4..442ea1f 100644 --- a/docs/v1/messenger.md +++ b/docs/v1/messenger.md @@ -20,8 +20,8 @@ $messenger->sendNow('Visible this request too', MessageLevel::Info); ### Hops -- `send()` defaults to one hop — visible on the next request, then expires. -- `sendNow()` defaults to zero hops — visible in the current request only. +- `send()` defaults to one hop - visible on the next request, then expires. +- `sendNow()` defaults to zero hops - visible in the current request only. - Passing `$hops` persists the message across that many additional hops. ```php