---
title: "Development and tests"
manual: "HTTP Guard"
version: "main"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-http-guard:development@main"
source: "Development/Index.rst"
rendered: "2026-10-18T14:31:38+00:00"
---

# Development and tests {#development}

## One extension, two internal namespaces {#development-layout}

| Path | Purpose |
| --- | --- |
| `Classes/` | TYPO3 adapter under `\Netresearch\NrHttpGuard`. |
| `Classes/HttpGuard/` | Embedded security core under `\Netresearch\HttpGuard`. |
| `Configuration/` | TYPO3 services, aliases and RequestFactory registration. |
| `Resources/Private/HttpGuard/data/` | Runtime address rules, shared corpus and source metadata. |
| `Documentation/` | Complete manual and reusable examples. |
| `Tests/Unit/` | Unit tests for the TYPO3 adapter. |
| `Tests/Functional/` | Genuine Core decoration, classic activation and mode bootstraps. |
| `Tests/HttpGuard/` | Policy, transport and real wire tests for the embedded core. |

The adapter supplies immutable configuration, registry, resolver, clock and
reporter. The independent embedded core allows isolated tests within this
one installable extension; see [ADR-0015: One installable extension](https://docs.typo3.org/permalink/netresearch/nr-http-guard:decision-single-extension@main).

## Local checks {#development-unit}

Development dependencies come from `composer.json` and install under
`.Build/vendor/`. PHPUnit `^11.5`, PHPStan `^2.3`
and `netresearch/typo3-ci-workflows:^1.12` provide the shared tools.
The development directory and tool configurations are excluded from the
classic extension package.

**Install tools and run deterministic local checks**

```bash
composer install
composer check:harness
composer check:secrets
composer check:local
```

CaptainHook installs commit-message and pre-commit checks. Staged secrets
are checked before quality; missing tools and failed checks must fail.
Installation alone proves no passing run. CI remains the merge authority;
see `CONTRIBUTING.md` for hook scope and isolated checkouts.

| Composer command | Scope |
| --- | --- |
| `ci:test:php:cgl` | Shared PHP style, dry run. |
| `ci:test:php:rector` | PHP 8.2-compatible modernization, dry run. |
| `ci:test:php:phpstan` | Curated kernel and actual Core profiles; configured level 10. |
| `ci:test:php:unit` | Offline adapter and kernel Unit tests. |
| `ci:test:php:functional` | Controlled native transport tests. |
| `ci:test:php:architecture` | Documented architecture boundaries. |
| `ci:test:php:mutation` | All-source Infection analysis, including uncovered mutants. |
| `ci:test:php:fuzz` | Deterministic input/property checks. |
| `ci:test:php:performance` | Normalization/classification/policy benchmark. |

Commands, configuration and execution are separate evidence. Curated static
rules use no baseline or broad suppression. Analysis-only HandlerStack/Client
stubs retain actual SDK methods/storage and document Guzzle 7's missing
template plus both majors' open constructor/`getConfig` contracts.
Native controls preserve caller defaults; neither stub runs in production.

The integrated offline suite passes **1,535 Unit tests and 7,199 assertions**
on each genuine Core 13/Guzzle 7 and Core 14/Guzzle 8 graph on PHP 8.5.11.
Kernel/Core 13/14 level 10, architecture and Rector are clean. Recorded style
has zero changes in 196 files across the GPL extension/test/tool and MIT
kernel scopes. The final 263-input full-source run passes 90.43%/91.54%
with no skipped/ignored mutants; focused results retain separate bindings.
See [Integrated local checks](https://docs.typo3.org/permalink/netresearch/nr-http-guard:verification-integrated-local@main) for complete 850 quality evidence
and the unchanged 90%/90% targets.

Wire tests require dedicated targets and counters; serialize runs that
share them. Ordinary Unit tests remain offline. A minimal SDK installation
can run policy tests with the separate bootstrap:

**Isolated policy tests with an explicitly selected SDK loader**

```bash
HTTP_GUARD_TEST_AUTOLOAD=/absolute/sdk/vendor/autoload.php \
    /absolute/sdk/vendor/bin/phpunit \
    --configuration Build/phpunit-http-guard.xml \
    Tests/HttpGuard/Unit/Policy
```

Fixed fixtures preserve exact Core and SDK snapshots. Four floating native
Core 13/14 and Guzzle 7/8 rows resolve compatible updates on pull requests
and weekly schedules; eight native rows and 14 fixed PHP CI cells remain
separate matrices. See [Semantic support and recorded proof](https://docs.typo3.org/permalink/netresearch/nr-http-guard:verification-semantic-support@main) for recorded
versions and [Assessment reconciliation](https://docs.typo3.org/permalink/netresearch/nr-http-guard:assessment-reconciliation@main) for current remediation.

## Functional fixture routes {#development-functional-routes}

The three executed Core entrypoints live in `Tests/Functional/`.
Select an already prepared genuine fixture and controlled wire targets:

**Host and selected-container Core routes**

```bash
bash Build/Scripts/runTests.sh -s integration -f .Build/fixtures/core14g8
bash Build/Scripts/runTests.sh -s classic -f .Build/classic-sites/classic14 -- active
bash Build/Scripts/runTests.sh -s mode -f .Build/fixtures/core14g8 -- observe
bash Build/Scripts/runTests.sh -s integration -f .Build/fixtures/core14g8 -p 8.5 -t 14
```

Without runtime flags the wrapper uses host PHP. Selected-container routes
use the official `suite_http_guard_functional` hook and the selected
digest-pinned image. Ephemeral host-network containers reach the
separately prepared witness destinations used by these entries. They mount
the physically validated project, preserve literal fixture arguments, and
probe the actual fixture PHP/Core graph before running the entrypoint.
External fixtures and escaping loader symlinks fail before delegation.
The fixture graph is unchanged; generic suites retain their shared routes.

Containers run as the caller without capabilities and with a read-only
root filesystem. Cleanup removes captured owned IDs; failures propagate.
Core 13 fixtures may omit `composer/semver`: the probe loads only
that namespace from development tools, retaining the fixture's Core/SDK.

The 27 offline routing controls establish argument, path, ownership and
failure behavior. Separate real qualification passed 20 host and 20
selected-container routes on PHP 8.5.11 and 8.5.10 respectively. Those records
are bound to their tested sources and graphs. See `Build/Fixtures/README.md`
for fixture preparation and routing details.

## Mutation scope in CI {#development-mutation-scope}

Pull-request verification selects production PHP files added, modified or
renamed relative to the validated base commit. A NUL-separated Git file list
is validated and passed as positional paths to Infection, which mutates
the complete selected files, including unchanged functions. Direct and
nested `Classes/` files are included. MSI and Covered MSI both retain
90% thresholds, default mutators, uncovered mutants and measured failures.

When no production PHP was added, modified or renamed, the workflow records
an explicit skipped mutation measurement. Unit and native behavior still
run; that skip establishes no mutation score. Scheduled runs, pushes to
`main` and manual dispatch retain the complete `Classes/`
scope without changed-file selection. Full alpha qualification is recorded
separately with its actual measured score and source binding; configuring
the threshold does not establish that it passed.

## Evidence and reproduction {#development-evidence}

The technical verification distinguishes policy results, native transfer
construction and actual new TCP and HTTP contacts. A mock handler alone
does not prove pinning. The wire fixtures use their own synthetic addresses
and DNS responses; third-party production destinations are not required
for the tests.

Maintained runners and fixtures live under `Tests/` and `Build/`;
source-bound summaries live under `Build/Reports/Assessment/`.
[Requirements and security invariants](https://docs.typo3.org/permalink/netresearch/nr-http-guard:development-requirements@main) maps the original 45 requirements, 84
scenarios and eight invariants to current tests and immutable history.
[Verification report](https://docs.typo3.org/permalink/netresearch/nr-http-guard:verification-report@main) distinguishes completed runs from archived
measurements; these development records are not TER runtime dependencies.

The checks cover in particular:

-   IPv4 and IPv6 CIDR boundaries, mapped IPv6, metadata and narrow endpoint
    permissions.
-   Complete DNS chains, TC retry over TCP, limits, NSS exclusion and
    memoization and expiry checks.
-   Actual cURL pinning, missing capabilities, options, proxy SAPI behaviour,
    redirects, retries, streaming and cancellation lifetimes.
-   Real TYPO3 DI and RequestFactory bootstraps, context restrictions, CLI
    commands and classic archives without a separately installed library.
-   Optional Vault migration with independent resource and OAuth bindings.
-   Isolated mutants that remove denials or violate pinning or fallback
    restrictions; witnesses check actual contacts before the assertions.

The PHP and SDK core matrix is separate from the framework matrix. A core
test run on PHP 8.2 does not automatically qualify every TYPO3 version for
that PHP version. Compatible dependency patches and minors remain
installable within the supported ranges. Changes to supported majors,
minima, handlers, protocols or permitted options require source comparison
and the relevant policy, wire, integration and mutation tests.

The named policy benchmark and historical measurements retain their own
source/runtime boundaries under [Assessment reconciliation](https://docs.typo3.org/permalink/netresearch/nr-http-guard:assessment-reconciliation@main).

## Render the manual {#development-docs}

The sources under `Documentation/` use the current phpDocumentor
Guides configuration. `Settings.cfg` is not required. The official
TYPO3 documentation describes the
[rendering container](https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/Howto/RenderingDocs/Index.html).

**Official renderer in the extension directory**

```bash
docker run --rm -v "$PWD":/project \
    ghcr.io/typo3-documentation/render-guides@sha256:fcf1ea87377ac401ce595b8c320c03b2b1bf2505ec0109561ca2fe56d7d71fc1 \
    --config=Documentation --no-progress --fail-on-log
```

HTML is written to `Documentation-GENERATED-temp/`. A custom output
must stay inside the mounted directory. Use `--fail-on-log` so that
warnings fail the build; a default exit code alone proves no valid references.
This digest identifies the recorded renderer. Updating it requires fresh
English and German rendering before claiming another successful build.

-   [Licenses and data](https://docs.typo3.org/permalink/netresearch/nr-http-guard:licenses-and-data@main)
-   [Requirements and security invariants](https://docs.typo3.org/permalink/netresearch/nr-http-guard:requirements-and-security-invariants@main)
-   [Verification report](https://docs.typo3.org/permalink/netresearch/nr-http-guard:verification-report-1@main)
-   [Dependencies and security status](https://docs.typo3.org/permalink/netresearch/nr-http-guard:dependencies-and-security-status@main)
-   [Repository assessment](https://docs.typo3.org/permalink/netresearch/nr-http-guard:repository-assessment@main)
-   [Assessment reconciliation](https://docs.typo3.org/permalink/netresearch/nr-http-guard:assessment-reconciliation-1@main)
-   [Release provenance and integrity](https://docs.typo3.org/permalink/netresearch/nr-http-guard:release-provenance-and-integrity@main)
