Skip to content

[architecture] Design a Box + PHP-Scoper dev-tools-shim for extracted Fast Forward components #197

@coisa

Description

@coisa

Summary

Create a dedicated fast-forward/dev-tools-shim distribution built with Box + PHP-Scoper so Fast Forward tooling can be split into smaller reusable packages while still sharing the existing DevTools runtime, container, and automation capabilities.

Problem

fast-forward/dev-tools currently acts as one large Composer plugin and tool bundle. That works well for repository bootstrap, workflow sync, and the unified composer dev-tools entrypoint, but it makes it hard to extract parts of the project into smaller standalone packages that can be consumed independently.

A concrete example is changelog automation. A dedicated fast-forward/changelog package could be useful on its own in consumer repositories, but today the implementation is tightly coupled to the main dev-tools dependency graph and command surface.

At the same time, those smaller Fast Forward components would still benefit from DevTools capabilities during development, such as:

  • the existing container and service-provider wiring
  • command orchestration and process helpers
  • changelog, docs, and workflow conventions
  • shared QA tooling and CI surfaces

Goal

Introduce a dev-tools-shim artifact that packages the DevTools runtime in an isolated PHAR-style distribution, so that:

  • fast-forward/dev-tools can evolve into an orchestrator and aggregator of smaller Fast Forward components
  • standalone Fast Forward component packages can depend on fast-forward/dev-tools-shim as a require-dev tool dependency
  • those component packages can reuse DevTools internals and tooling without exposing DevTools' third-party dependency graph directly to their own consumers

Proposed Direction

  1. Create a dedicated fast-forward/dev-tools-shim package built with Box + PHP-Scoper.
  2. Scope the bundled runtime so the shim can safely embed DevTools internals and its third-party implementation dependencies.
  3. Keep fast-forward/dev-tools as the repository-facing orchestrator responsible for:
    • the Composer plugin integration
    • workflow wrappers and local GitHub actions
    • consumer sync flows
    • packaged skills, packaged agents, and repository bootstrap defaults
  4. Allow extracted Fast Forward component packages to use fast-forward/dev-tools-shim during development and CI.
  5. Move toward a model where fast-forward/dev-tools aggregates smaller Fast Forward components instead of permanently owning all behavior directly.

Why This Matters

This would let Fast Forward packages reuse a common runtime and toolchain while reducing direct dependency pressure on downstream consumers.

In practice, it could help with cases where the current dev-tools dependency set is too broad or too invasive, especially because the repository currently requires runtime and QA packages such as:

  • php-di/php-di
  • phpunit/phpunit
  • phpunit/php-code-coverage
  • friendsofphp/php-cs-fixer
  • rector/rector
  • phpdocumentor/shim
  • symplify/easy-coding-standard
  • other tool-specific packages that are useful to DevTools itself but may be undesirable as direct dependency constraints for a smaller component package

A shim would also allow Fast Forward components to reuse the existing DI surface from DevToolsServiceProvider instead of duplicating container choices package by package.

Repository Constraints And Challenges To Capture

The issue SHOULD explicitly account for the current repository shape:

1. Composer-plugin and orchestrator split

fast-forward/dev-tools is currently a composer-plugin with:

  • plugin capability registration
  • bin/dev-tools
  • synchronized workflow wrappers in resources/github-actions/
  • local reusable GitHub actions in .github/actions/
  • sync orchestration for repository defaults, skills, agents, changelog automation, wiki, and other managed assets

The shim cannot simply replace the main package. We need a deliberate split between:

  • the repository orchestration package (fast-forward/dev-tools)
  • the isolated reusable runtime/tool distribution (fast-forward/dev-tools-shim)

2. Service container reuse

DevToolsServiceProvider currently wires a large shared runtime:

  • process builder / queue
  • filesystem and file locators
  • changelog services
  • git client
  • console loader and logger services
  • diffing, gitignore, gitattributes, license, Twig loader, clock, etc.

If extracted component packages are expected to reuse this runtime, we need a stable contract for what the shim exposes versus what remains private implementation detail.

3. Third-party dependency scoping strategy

A major motivation is avoiding consumer dependency conflicts, but some dependencies have public-facing development ergonomics.

Example challenge:

  • a package that installs only the shim would not automatically have the real phpunit/phpunit classes available to extend in its own test suite unless we make an explicit decision about what is bundled, what is scoped, and what remains a normal Composer dependency.

We need a clear strategy for cases like:

  • PHPUnit APIs used directly by package tests
  • Prophecy / coverage helpers used directly in package tests
  • tool configs or extension classes that are meant to be referenced by consumers

This may require selectively scoping only implementation dependencies, or splitting some concerns into separate packages instead of putting everything into one giant scoped PHAR.

4. Release and version propagation

If dev-tools-shim becomes a separate package or artifact, the release flow needs to keep it aligned with fast-forward/dev-tools.

One specific challenge is that fast-forward/dev-tools releases would need to trigger a shim release/update workflow so the shim can be rebuilt and published at the matching version.

The issue SHOULD cover:

  • how the shim version mirrors DevTools releases
  • whether the shim is released from the same repository or a dedicated repository
  • what workflow handoff or cross-repository dispatch is required

5. Sync and workflow compatibility

fast-forward/dev-tools currently synchronizes workflow wrappers, local action references, packaged skills, packaged agents, and repository bootstrap files into consumers.

The shim should not blur those responsibilities. The issue SHOULD keep clear that the shim is for isolated runtime/tool reuse, while the main dev-tools package remains the owner of:

  • consumer sync behavior
  • workflow wrappers and repository automation defaults
  • packaged agents / packaged skills surfaces
  • broader repository orchestration

6. Artifact duplication and content divergence

Using a shim means some files will effectively exist twice:

  • normal repository source in fast-forward/dev-tools
  • scoped / packaged equivalents inside the shim artifact

That duplication is acceptable only if we define what is intentionally replicated and how drift is prevented when the packaged content differs from repository source because of scoping, stubs, or build-time rewriting.

Non-Goals

  • This issue should not immediately extract all DevTools functionality into separate packages.
  • This issue should not decide every final package boundary up front.
  • This issue should not replace the existing fast-forward/dev-tools consumer sync and workflow orchestration role.

Acceptance Criteria

  • A design is documented for fast-forward/dev-tools-shim using Box + PHP-Scoper.
  • The design clearly distinguishes fast-forward/dev-tools orchestration responsibilities from shim responsibilities.
  • The plan covers how extracted component packages can depend on the shim in require-dev and reuse DevTools services safely.
  • The plan addresses public-vs-scoped dependency strategy, especially around PHPUnit and other developer-facing tool APIs.
  • The plan addresses version propagation and release workflow coordination between DevTools and the shim artifact.
  • The plan addresses how build-time replicated files are generated and kept in sync.
  • Follow-up implementation issues can be split cleanly from this design issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions