Start here
Quick Start Architecture Components Frameworks Contributing Coding StandardContributing¶
Use this guide when changing Fight Common itself. Consumer installation, component adoption, and framework composition belong in their respective guides; this route covers repository workflow, verification, and release evidence for maintainers.
Read the repository-local AGENTS.md, planning/agents/project-profile.md, and the applicable documents in
docs/engineering/standards/. These committed instructions are self-contained; they require no private skills
or external checkout. docs/engineering/STANDARDS.md records the adopted baseline and update policy.
Choose the change boundary¶
Start with the smallest owned boundary that can deliver the requested behavior:
- Domain contains framework-free business rules and value objects.
- Application coordinates use cases and may depend on Domain, PHP internals, PSR contracts, and the allowlisted scheduler expression contract.
- Adapter integrates frameworks and infrastructure through Application or Domain contracts.
- Standards publishes the orthogonal coding standard and has no runtime dependants.
The enforced dependency direction is Adapter -> Application -> Domain. Keep public behavior backwards
compatible: a deprecated public API remains supported for at least one released minor and is removed only in the
next major.
Before editing, read the relevant task, its parent TICKET, and any accepted ADR named by the task. The live
Board is the execution
frontier; planning/CONVENTIONS.md defines status, ordering, and completion updates. The Roadmap has a separate
planning frontier for undecomposed parents. Close eligible parents in the same child-completion operation under
Automatic parent completion, counting live and archived children.
Common owns reusable package promises; consumer applications own policy, permissions, routes and composition
unless an explicit package contract says otherwise. Use public package contracts directly without behaviorless
wrappers; preserve required compatibility aliases and framework integrations.
Create an isolated branch¶
Choose the main checkout or an isolated worktree with the maintainer. New TASK branches use
feature/task-NNNNN-<slug> from develop, never from main; do not commit directly to either protected branch.
Preserve established branch/PR identities and existing release/patch conventions.
For coordinated or concurrent work, use a linked checkout under the repository's ignored run area:
git worktree add -b feature/task-NNNNN-short-description \
.runs/worktrees/short-description develop
Run every command from the selected checkout. Keep investigation notes in .runs/notes/, reusable local handoffs
in .runs/handoffs/, canonical independent reports in the base worktree's .runs/reviews/<TASK-ID>/review.md,
and retired scratch in .runs/archive/. Those paths are local evidence and must not be
staged. Removing a worktree or other run material is a separate cleanup action.
Implement and verify¶
Production tests cover owned production code and meaningful behavior. Every PHPUnit class extends
Fight\Test\Common\TestCase\UnitTestCase and carries explicit coverage metadata. Direct unit tests use
#[CoversClass]; #[CoversNothing] is reserved for qualifying integration or product-journey tests and cannot
hide missing direct coverage.
Documentation, generated files, wrappers, build orchestration, configuration text, and tooling are checked with their owning commands and human inspection. Do not add tests that merely inspect those surfaces. Preserve existing release tests and probes without adding packaging or release-process tests in any suite or renamed harness. The project profile inventories retained checks; do not recreate a removed suite. Meaningful runtime, shipped coding standard and framework integration tests remain product contracts.
Use a non-interactive container command for focused feedback:
docker container run --rm -v "$PWD:/app:delegated" -w /app fight-common \
php vendor/bin/phpunit tests/Domain/Specification/AndSpecificationTest.php
Useful interactive wrappers include:
./bin/phpunit --filter test_method_name
./bin/phpstan
./bin/deptrac
./bin/rector process src/ --dry-run
./bin/docs validate
The canonical pre-submit gate is:
It resolves and installs dependencies with composer update, validates the documentation artifact, provisions
disposable MySQL and PostgreSQL services, and runs Composer validation, syntax checks, PHPCS, PHPStan, Deptrac,
Rector's dry run, direct unit tests with exact statement coverage, integration tests, functional tests, and planning
integrity. This library ignores composer.lock; every full build resolves its supported dependency constraints
instead of reusing a stale local lock. A focused run provides iteration feedback; implementation completion requires
the full gate. Documentation-only follow-ups may retain a verified earlier full pass with input-equivalence evidence
and current targeted checks under docs/engineering/standards/Testing.md.
Hosted CI runs the same ./bin/build command in the runner's Docker environment. Its result is separate hosted
delivery evidence for the checked-out SHA, not a second dependency or quality lane. The workflow is work → local
verification → independent review → land: local evidence permits technical acceptance without a PR or hosted run,
including in this public repository. Authorized land owns the later push and PR creation.
To enable the tracked pre-commit gate:
The hook runs ./bin/build. If it fails or is interrupted, diagnose the cause and run it again to completion.
Never use git commit --no-verify, disable, or otherwise bypass the hook merely because the gate is slow,
interrupted, or inconvenient. An exception requires explicit authorization for that exact commit and leaves
delivery unverified.
Prepare the pull request¶
Before the final commit or pull request:
- Verify every acceptance criterion with current evidence.
- Mark TASK implementation
doneonce all implementation acceptance and required local verification are complete, before publication. A green build alone is insufficient. Keep pending independent review explicit and record review, publication, merge, release and deployment separately. - Update the TASK metadata and PR link, preserving dependency edges as history.
- Run
./bin/planning-check --writeto refresh Board, parent, index, and Roadmap tables. - Run the read-only
./bin/planning-check, inspect the complete diff, and satisfy./bin/buildor Testing's documented input-equivalence rule for documentation-only follow-ups.
Independent review follows the Spec/Standards accept/revise contract in docs/engineering/standards/Review.md:
one independent reviewer may do both passes, material contributors cannot accept, and any failed or unverified
criterion requires revise. Review does not repair, change status, publish or merge. Moving revisions retain
acceptance only through the proven mechanical-reconciliation bridge in Delivery; semantic or uncertain changes
need renewed independent review.
After independent acceptance, authorized land opens the feature pull request against develop with title
TASK-NNNNN — <TASK title>; preserve an established PR identity. The hosted Tests workflow runs the complete
pre-submit gate; the documentation workflow builds and validates the generated site. Both are required delivery
checks on the final published head, not pre-publication review prerequisites. A queued, skipped, cancelled,
warning-bearing, or no-step job is not passing evidence. Pending delivery does not invalidate local acceptance;
record it honestly and retain required resources. The repository's planning/agents/project-profile.md owns
these delivery requirements.
Commit, push, pull-request creation, merge, deployment, and cleanup are distinct effects. Perform only the effects that have been explicitly authorized.
Certify a release candidate¶
A successful ./bin/build proves the checkout's submit gate; it does not certify or publish a release.
Certification requires a clean, committed candidate and resolves its own baseline, latest-compatible, and
lowest-compatible dependency lanes in exported workspaces:
It binds evidence to the exact HEAD, runs the complete product gate for those three lanes, builds the Composer
archive, probes an installed consumer, and writes the result under .runs/handoffs/. A pre-existing root lockfile
is not a certification prerequisite. See the
release module guide for the full contract.
Certification does not merge, tag, push, create a GitHub release, publish to Packagist, or deploy documentation.
Promotion from develop to main, tagging, publication, rollback, and maintenance-branch work each require their
own accepted plan and authorization. Do not infer a hotfix or backport route from urgency alone.
Documentation workflow¶
Use the pinned documentation runtime:
preview serves the local site at 127.0.0.1:8000. build creates the disposable, ignored site/ artifact.
validate performs the strict render and current artifact checks. Review changed routes in the supported viewport
and color-scheme combinations before treating the documentation as accepted.
Pull requests validate documentation but do not deploy it. The hosted workflow deploys only after a push to
main; a local artifact, successful build, or uploaded workflow artifact is not production publication evidence.
Related maintenance routes¶
- Adopt or configure the package's optional Coding Standard.
- Review the consumer-facing Architecture before changing layer ownership.
- Check Framework Support before changing adapter or provider claims.
- Use the Quick Start as the representative portable consumer journey.