Repository navigation
[architecture] Plan domain-owned tooling extraction and DevTools orchestration #240
Description
Proposal / validation gate: this issue records an extraction design for maintainer validation. Repository/package names are candidates. Approve the boundary and migration plan before implementation; this task does not authorize creating repositories, implementing the extraction, releases or consumer rollout.
Current decision — responsibility-oriented extraction (2026-10-21)
This issue is intentionally reframed, not marked implemented. The former proposal to move every workflow into .github is superseded by domain ownership. Its original description is preserved below. Changelog already owns its library/CLI/workflows/Actions/skill; apply that pattern where useful, not a mandatory surface checklist.
DevTools remains the bootstrap, composition and upgrade orchestrator for fresh and existing projects, instead of a static template maintained separately. Domain packages own behavior and their delivery assets. LLM Skills already distributes skills; do not recreate its copying/symlink mechanism or a mandatory central agents bundle.
Evidence and candidate distinction
Inspected main 35d27ee; open PR #376 at cde0cc6 proposes external CPX and portable skills, not yet merged/released. Preserve that candidate and human review. #373 release PR is also not publication proof. The old #197 draft contains already changed Composer/changelog assumptions; its runtime-isolation concern remains separate.
Ownership map and linked work
| Domain / proposed owner | Current payload / boundary | Tracking |
|---|---|---|
| changelog (existing) | Fragments/history/version/release lifecycle and matching adapters/skill | Existing package; do not re-extract |
| code-standards | ECS, PHP-CS-Fixer source/PHPDoc policy, explicit Rector transformations; not rendered docs/tests | #379 |
| testing | PHPUnit execution/public extensions, coverage/JUnit, test-specific PR feedback | #380; preserve #8, #262, #246 |
| documentation | HTML API/guides, Wiki, site assembly/publishing; consumes external test/metrics artifacts | #367; retain phpdoc-bootstrap-template visual ownership |
| dependency-health (candidate) | Composer dependency graph/policy/explicit upgrades; not generic source refactoring | #381 |
| repository-metadata (candidate) | License/funding/CODEOWNERS/ignore/export/Composer metadata transformations; not global bootstrap | #382 |
| repository-governance (candidate) | Review intake, issues/PR procedures, labels/assignment/project lifecycle; not every Actions file | #383 |
| git-hooks | Hook payload/runtime; not a skill installer | #336, historical #296 remains closed |
| DevTools retained | Select profiles, resolve versions, compose result contracts, preview/apply upgrades, provenance/conflicts/rollback | #384; #142 doctor remains relevant |
| Skills migration, not central agents repo | Procedures belong with the above domains; role prompts become composition skills where equivalent | Reframed #195 |
| Optional runtime distribution | CPX/packaging tradeoffs and genuine in-process public API compatibility, not mandatory shared mega-runtime | Reframed #197 |
These are responsibility candidates, not approval to create six repositories. Bootstrap stays in DevTools. For dependency-health/metadata/governance, the first deliverable must compare actual independent consumers, code size, dependency/release cadence and overlap. If a candidate is too small or has no independent lifecycle, keep a clearly bounded module under the closest domain or orchestrator and record why; do not force micro-repositories. Generic filesystem/process/console helpers are not a new mandatory dev-tools-runtime without demonstrated need; reuse existing ecosystem primitives first.
A residual skills repository is a last-resort option only for procedures that genuinely fit no domain; see #195. It may offer explicit onboarding/configuration for LLM Skills, not a second installer or central copy of domain skills. Compare that with DevTools composition skills and using LLM Skills directly before choosing.
Responsibilities needing a deliberate follow-up decision
- Static source analysis is already Add dev-tools analyse command for standardized static analysis (PHPStan-first, extensible to Psalm) #14 with related Add php-assumptions support for explicit assumption analysis #265/Evaluate PHPat architecture rule enforcement integration #266/Evaluate phpcs-security-audit integration for PHPStan-based security checks #267; do not duplicate or close it. PhpMetrics currently lives in MetricsCommand and consumes JUnit within ReportsCommand. Decide a code-analysis module/package only when that capability plan warrants it; metrics output is supplied to documentation, never recomputed by the site publisher.
- Twig Evaluate Twig-CS-Fixer + twigcs + twig-linter integration for template quality #269 / magic values Evaluate phpmnd integration for magic value quality checks #268 remain optional code-standards capability evaluations. Mutation Add Infection command integration to evaluate mutation testing coverage #262 belongs with testing. NotebookLM Create NotebookLM integration skill for automated documentation updates #351 stays an optional docs adapter with verified target/authentication, not a default data transmission. Add component-preference skill/reference for Fast Forward dependency guidance #350 component guidance and Add first-class llms.txt support for AI-native repositories #144 llms.txt map by content, not by file format.
- Add github/local-action to dev-tools local workflow validation path #347/Integrate github/gh-aw for workflow/action inspection in dev-tools #348/Adopt github/spec-kit specs and pinned-action hash governance #349 validation/spec/pin capabilities survive. Apply validators in the domain repositories; maintain shared rollout/pin policy in Define release-safe refs for consumer workflow wrappers and checked-out actions #238. Normalize path-helper naming, namespace boundaries, and segment typing #163/Centralize repeated command process dispatch behind an explicit event-driven contract #164 runtime cleanup remains independent until actual implementation revalidation.
- .github#2 is already closed; .github#3 and github-actions#2 retain their history. This plan does not merge/close PRs or delete their repositories. The generic github-actions candidate requiring DevTools cannot become a runtime prerequisite that introduces a cycle.
Dependency and artifact contracts
- DevTools may consume released domain APIs or invoke independent CLIs. Domains must not require DevTools in production. Test/runtime API imports need compatibility fixtures even with CPX.
- One owner per implementation, workflow, Action and skill; role-based composition refers to canonical skills rather than copies. LLM Skills provenance and exact source/version remain visible.
- The aggregate standards/reports flow stays an orchestration concern. Testing emits coverage/JUnit; metrics emits its artifact; documentation assembles one Pages site. One publisher prevents overwrites.
- Domain descriptors expose capabilities/options/artifacts/exit-result schemas and compatible runtime/workflow/skill refs. DevTools records original rendered hashes and local overrides, plans deterministically, and never resolves a conflict by blind overwrite.
- No implicit publishing, plugin side effects, dependency upgrades, PR merges or permissions expansion merely from installation/sync.
Migration order and done definition
- Settle ownership and descriptor/result/provenance contracts with [architecture] Make DevTools the profile-based bootstrap and upgrade orchestrator for domain packages #384/[architecture] Map domain-owned skills and replace redundant agent distribution #195/Define release-safe refs for consumer workflow wrappers and checked-out actions #238, preserving feat!: distribute DevTools through CPX and portable skills #376 review state.
- Use changelog as proven baseline; pilot documentation [RFC / Architecture] Extract Wiki and docs into a standalone PHP package, CLI, skill and automation #367 and code-standards [architecture] Extract code-standards: formatting, PHPDoc policy and explicit refactoring #379 independently, then testing [architecture] Extract testing: PHPUnit execution, extensions, coverage and PR feedback #380 and hook Externalize git hook logic into a dedicated git-hooks package #336 compatibility; other candidates proceed only when justified.
- Inventory actual imports, workflows, skills, configs, hooks and outputs across all code-bearing repos. Current audit reports 12 dev-main consumers and framework ^1.26; refresh rather than treating these counts as permanent. PHP ^8.3 libraries, changelog ^8.5 and brand >=8.4 have intentional runtime differences.
- Define migration/rollback per repo: smallest library (clock), config/container with shared PHP APIs, custom test/report consumer, then remainder. Empty scaffolds and non-PHP domains are not forced into PHP CI.
- Publish and verify each independent package/runtime/archive/skill before consumer adoption; reviewable per-consumer PR updates compatible pins, required checks and provenance together.
- Verify equivalence, no-op reruns, no-write previews, manual overrides, fork trust, source SHA, report routes and rollback. Keep adapters until migrated consumers no longer depend on them.
- Retire duplicate implementation only after coverage and adoption are proven; update root AGENTS/README/docs and pending issue links. No blanket closure of bugs/features by architectural intent.
Historical proposal (preserved, no longer target architecture)
Original #240 — move shared GitHub Actions into .github
Objective
Evaluate and implement the extraction of shared GitHub Actions implementations and reusable workflow orchestration from php-fast-forward/dev-tools into the organization-level php-fast-forward/.github repository.
dev-tools would keep the consumer-facing workflow stubs currently stored under resources/github-actions/, and dev-tools:sync would continue copying those stubs into consumer repositories. The implementation details behind those stubs would move to php-fast-forward/.github, which is a more natural home for shared organization automation.
Motivation
dev-tools is becoming overloaded with two different responsibilities:
- shipping a PHP Composer plugin and command suite;
- acting as the organization automation repository for reusable workflows and composite GitHub Actions.
That coupling has started to create maintenance pressure and versioning questions. Consumer repositories currently depend on fast-forward/dev-tools as a Composer package, but their workflows call reusable workflows and actions from this repository. When automation implementation changes happen on main, consumers can observe workflow behavior that does not necessarily match the latest published PHP package release.
The organization repository php-fast-forward/.github already exists as the organization profile repository. It is also the repository GitHub users usually expect to contain shared organization-level defaults and automation. Moving reusable workflows and local actions there would make the architecture easier to explain:
.githubowns organization-level GitHub automation;dev-toolsowns the PHP package, Composer plugin, CLI commands, sync logic, and packaged consumer workflow wrappers;- consumer repositories keep thin wrappers copied by
dev-tools:sync.
Relationship To #238
This issue is closely related to #238.
#238 asks how consumer workflow wrappers and .github/actions checkouts should be versioned so consumers do not accidentally run unreleased dev-tools automation.
Extracting the reusable workflows/actions to php-fast-forward/.github may make #238 simpler because the version contract could become a contract of the automation repository instead of the PHP package repository. In that model:
- implement this extraction first;
- then resolve Define release-safe refs for consumer workflow wrappers and checked-out actions #238 against the new layout by deciding how consumer stubs reference
php-fast-forward/.githubversions or branches; - Define release-safe refs for consumer workflow wrappers and checked-out actions #238 may shrink from “separate PHP package release state from workflow/action state” into “define a versioning/update policy for the dedicated automation repository”.
If implementation shows that .github cannot own the automation cleanly, #238 remains required as the fallback path for release-safe refs inside dev-tools itself.
Proposed Direction
Create a migration plan where php-fast-forward/.github becomes the canonical source for:
- reusable workflows currently under
.github/workflows/that are consumed by other repositories; - composite actions currently under
.github/actions/; - supporting scripts/assets that exist only to power those workflows/actions;
- future organization-level automation such as a documentation/site pipeline if the profile repository gains a real project structure later.
Then adjust dev-tools so it keeps and syncs only the consumer wrappers, for example:
resources/github-actions/tests.ymlresources/github-actions/reports.ymlresources/github-actions/changelog.ymlresources/github-actions/wiki.ymlresources/github-actions/wiki-maintenance.ymlresources/github-actions/review.ymlresources/github-actions/auto-assign.ymlresources/github-actions/label-sync.ymlresources/github-actions/auto-resolve-conflicts.yml
Those wrappers would call reusable workflows from php-fast-forward/.github instead of php-fast-forward/dev-tools.
Suggested Migration Strategy
-
Inventory automation ownership
- Identify which
.github/workflows/*files are reusable workflows for consumers. - Identify which workflows are repository-local to
dev-toolsand should remain here. - Identify all
.github/actions/*dependencies for each reusable workflow.
- Identify which
-
Create the automation repository structure
- Add the reusable workflows and composite actions to
php-fast-forward/.github. - Decide whether they live directly under
.github/workflowsand.github/actions, or under a dedicated folder if the profile repository needs to preserve GitHub profile behavior cleanly. - Ensure local action paths still resolve correctly when reusable workflows run from the
.githubrepository.
- Add the reusable workflows and composite actions to
-
Update consumer wrappers in
dev-tools- Change
resources/github-actions/*.ymlto callphp-fast-forward/.github/.github/workflows/<workflow>.yml@<ref>or whichever path/ref policy is selected. - Keep
dev-tools:syncresponsible for copying wrappers to consumers. - Ensure copied wrappers remain thin and consumer-customizable.
- Change
-
Define the versioning policy
- Decide whether consumers reference
@main, immutable release tags, a moving major tag, or another stable ref fromphp-fast-forward/.github. - Coordinate this with Define release-safe refs for consumer workflow wrappers and checked-out actions #238 so the ref strategy is deliberate rather than inherited accidentally.
- If tags are used, define how releases/tags are created in
.githuband how consumers are updated.
- Decide whether consumers reference
-
Keep
dev-toolsself-hosting workabledev-toolsstill needs to test changes to wrappers and sync logic.- Decide whether
dev-toolsitself consumes.githubworkflows immediately or keeps local workflows for bootstrap/self-test purposes. - Avoid a circular dependency where changing automation requires a
dev-toolsrelease before it can be validated.
-
Document and validate the new contract
- Update GitHub Actions docs and consumer sync docs.
- Add static checks to detect stale references to
php-fast-forward/dev-tools/.github/workflows/*@mainonce migration is complete. - Add release/sync checks to ensure resources copied to consumers point at the intended automation repository/ref.
Design Questions
- Should
php-fast-forward/.githubbecome a real automation package with its own tags/releases, or should it stay branch-based at first? - If
.githubgains tags, should Dependabot update reusable workflow refs in consumers? - Should
dev-toolsrelease automation update consumer stubs to the latest.githubautomation tag, or should the.githubrepo own that update flow? - Which workflows are truly organization-wide and which are specific to PHP package repositories using
dev-tools? - Should the
.githubrepo eventually host an organization site or documentation built with the Fast Forward framework, and would that affect folder layout? - How should local composite actions that assume a PHP/Composer project be adapted when they live in a repository that currently has no Composer structure?
- Do any workflows require
dev-toolssource code directly, or can they install/use the Composer package from the consumer repository as they do today?
Scope
In scope:
- migration plan and implementation for shared reusable workflows/actions;
- wrapper updates in
resources/github-actions/; - documentation updates explaining the new ownership model;
- validation that consumers receive equivalent behavior after
dev-tools:sync; - coordination with Define release-safe refs for consumer workflow wrappers and checked-out actions #238 for release-safe refs.
Out of scope:
- rewriting the
dev-toolsPHP command architecture; - changing consumer workflow behavior beyond the repository/ref ownership migration;
- building a full organization website in
.githubas part of this task; - forcing every consumer customization to be overwritten.
Acceptance Criteria
Delivery Criteria
- A migration inventory identifies which workflows/actions move to
php-fast-forward/.githuband which remain indev-tools. -
php-fast-forward/.githubcontains the shared reusable workflow/action implementation needed by consumer repositories. -
dev-toolskeeps consumer-facing workflow wrappers underresources/github-actions/and those wrappers call the new automation repository. -
dev-tools:synccontinues to copy consumer workflow wrappers correctly. - The selected relationship with Define release-safe refs for consumer workflow wrappers and checked-out actions #238 is documented: either this issue must be completed before Define release-safe refs for consumer workflow wrappers and checked-out actions #238, or Define release-safe refs for consumer workflow wrappers and checked-out actions #238 remains a fallback if extraction is rejected.
- Documentation explains the new ownership split between
.github,dev-tools, and consumer repositories. - Static validation prevents newly migrated wrappers from drifting back to
php-fast-forward/dev-tools/.github/workflows/*@mainaccidentally.
Regression Criteria
- At least one consumer-style fixture or dry-run verifies that synced wrappers point at
php-fast-forward/.github. - Existing workflow summaries, wiki/report automation, changelog automation, label sync, review automation, and auto-assign behavior remain covered by equivalent workflows after migration.
- CI verifies local action paths still resolve from the new repository layout.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
coisa commentedon Apr 29, 2026
Started the
.githubside of this extraction:The first PR copies the reusable workflow/action implementation into
php-fast-forward/.github, adapts workflow action checkouts to the new repository, and adds adev-tools/setupcomposite action that prefers a project-localvendor/bin/dev-toolsbut can installfast-forward/dev-toolsglobally with a configurable Composer version/ref. The consumer wrapper updates indev-toolsremain the coordinated follow-up for this issue.[-]Extract shared GitHub Actions automation into php-fast-forward/.github[/-][+][architecture] Plan domain-owned tooling extraction and DevTools orchestration[/+]