Repository navigation
[RFC / Architecture] Extract Wiki and docs into a standalone PHP package, CLI, skill and automation #367
Description
RFC: standalone Fast Forward documentation tooling
Summary
Extract Wiki and phpDocumentor documentation from DevTools into a proposed php-fast-forward/documentation repository: a PHP library, first-class CLI, portable CLI skill, packaged Docker runtime, GitHub Actions and reusable workflows. This follows the complete product model of Changelog, rather than relocating YAML alone.
Proposed identifiers: Composer package fast-forward/documentation, namespace FastForward\Documentation, CLI ff-documentation. These names and interfaces are proposals; the repository and release do not exist yet. This issue records investigation and an implementation plan, not completed extraction.
Problem and observed baseline
The 2026-10-14 inventory examined all 40 organization repositories and found 14 immediate migration targets, including DevTools itself. They currently use DevTools for both Wiki and HTML/report generation. Twelve use the shared Wiki entrypoint; two have custom publishers. HTML/report publishing has ten native Pages wrappers, two legacy wrappers, the DevTools producer and one custom consumer.
Moving only workflows would retain the coupled runtime: DevTools is a Composer plugin with 42 direct require entries, including platform constraints and quality tooling. Its Docs, Wiki and Reports commands total 815 lines. Documentation should run locally and in CI without loading the entire development plugin.
Reports also include coverage and PHP metrics. Extracting documentation must preserve those site sections without moving test/metrics generation into the documentation domain.
Proposed ownership
flowchart LR
C[Consumer projects] --> D[Documentation PHP library and CLI]
A[Actions and reusable workflows] --> D
S[Portable CLI skill] --> D
V[DevTools compatibility commands] --> D
D --> H[phpDocumentor HTML]
D --> W[Wiki Markdown]
H --> T[phpdoc-bootstrap-template]
B[.github brand source] --> T
Q[Existing coverage and metrics producers] --> P[Single site publisher]
H --> P
W --> G[Wiki publisher]
- Documentation owns project discovery, renderer configuration, HTML/Markdown generation, output validation, site assembly and controlled publication. Library services are reused by the CLI; actions/workflows are adapters.
- phpdoc-bootstrap-template continues to own Twig, styles, browser behavior and visual assets. Its current released baseline is v2.1.0.
- .github remains the canonical brand/design source and keeps its independent brand Pages site.
- DevTools retains quality commands, report orchestration where needed, and temporary compatibility/synchronization adapters.
- The skill teaches an agent how to use the released CLI. It neither reimplements the CLI nor grants install, push or publication authority.
No production dependency from Documentation back to DevTools. Reuse existing PHP dependencies where useful, without introducing another plugin, DI framework or generic automation platform.
Alternatives considered
| Alternative | Benefit | Main drawback | Recommendation |
|---|---|---|---|
| Keep everything in DevTools | No migration | Documentation remains coupled to plugin/quality runtime | Baseline only |
| Move YAML to .github or github-actions | Centralized workflow maintenance | Still needs DevTools commands; lacks independent local runtime | Insufficient alone |
| One documentation package with CLI, skill and automation | Shared implementation; local and hosted execution; one release contract | Requires explicit publisher/compatibility boundaries | Recommended |
| Separate Wiki and HTML repositories | Independent releases | Duplicates discovery, packaging and operational policy | Revisit only if ownership genuinely diverges |
| Put the pipeline in phpdoc-bootstrap-template | Fewer repositories | Mixes visual template with generation/publication and Wiki | Reject |
Compatibility and migration
Keep current paths, manual Wiki content, no-submodule behavior, preview URL policy and Dash/logo references, including docs/_static/mascot-banner.png. Preserve API-only, guide-only and empty-project behavior explicitly: HTML can render guides without an API; Wiki skips when no API exists. Wiki guide rendering would require a separate feature decision.
Support PHP 8.3 consumers without silently raising their application requirement. Decide separately the host CLI minimum and packaged runtime PHP version; Changelog's current PHP 8.5 minimum is a precedent for runtime isolation, not a requirement to copy.
One workflow must own a combined Pages site. It may assemble documentation with externally generated coverage/metrics artifacts; two independent deployments must not overwrite each other.
Publish and verify a release before pinning consumers to its final, reachable commit and image digest. Update synchronized DevTools defaults as well as committed callers. Immutable old Wiki pins will not change merely because DevTools main changes.
Acceptance criteria for implementation
- Independent library + local CLI + Docker runtime operate without a production DevTools dependency or dependency cycle.
- Actions and reusable Wiki/docs workflows invoke the same implementation, with read-only builds and isolated authorized publishers.
- Portable CLI skill is packaged, licensed, versioned and tested against actual released CLI commands.
- PoC comparisons preserve HTML/Wiki routes, guides, manual pages, Dash/logo assets and coverage/metrics sections.
- All 14 existing consumers have an explicit migration/rollback plan and validated final refs.
- Packaged runtime, Composer archive and skill resources work outside the development checkout.
- Fork PRs cannot publish; stale Wiki artifacts and invalid ownership paths cannot overwrite current/manual content.
- Compatibility commands/defaults have a documented deprecation window; removing them is a later versioned decision.
Action plan
Investigate and settle contracts → extract minimal PHP core and CLI → package runtime and skill → compare outputs without publishing → pilot Wiki/native Pages/legacy previews → release → migrate consumer cohorts → deprecate compatibility after adoption. Deep dives below define concrete gates and rollback.
Questions to settle
- Accept
documentation/fast-forward/documentation/ff-documentationnaming? - Keep host CLI compatibility at PHP 8.3 initially, while isolating newer renderer/runtime requirements?
- Which compatibility window should DevTools aliases and workflow wrappers receive?
- Preserve legacy published PR previews through an explicit trusted publisher, or deprecate them separately?
- Which optional coverage/metrics artifacts and routes belong in the common site assembly contract?
Related work and scope coordination
- DevTools issue 240, .github issue 2 and .github PR 3 propose broader workflow relocation. This RFC extracts the Wiki/docs domain and runtime; if accepted, coordinate/supersede that portion rather than duplicating it in two repositories.
- DevTools issue 238 concerns release-safe refs; reuse that contract.
- DevTools issue 197 concerns a future shim. Composer + Docker can establish this independent package without making Box/PHP-Scoper a prerequisite.
- github-actions PR 2 currently proposes a runtime that requires DevTools. Documentation must not depend on it while that creates a cycle.
Deep-dive directory
- Current code, dependencies and ownership
- Library, CLI, skill and release surfaces
- Publication trust, ownership and lifecycle
- Exact consumer inventory and migration obligations
- Phased action plan, validation and rollback
Investigation limits and metadata
Snapshot: 2026-10-14, exact source revisions in the consumer deep dive. Committed workflows were inspected; effective Pages settings, Wiki availability and organization secret grants still need implementation-time verification. No consumer edits, repository creation or release are part of this RFC publication.
Issue type: Feature. Existing labels: enhancement, documentation, github-actions. No milestone, assignee or project is guessed.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
coisa commentedon Oct 14, 2026
Deep dive: current code, dependencies and ownership
Evidence
The source baseline is DevTools main
c637e7f9d8ae6059b8655996e56f6d17f874792c.The HTML template defaults to
vendor/fast-forward/phpdoc-bootstrap-template. Native reports require an installed template >=2.1.0, while the Composer manifest allows ^2.0. The new released runtime must reconcile this discrepancy instead of inheriting an implicit workflow-only minimum.The current Wiki workflow bridges Markdown template assets into an isolated runtime. Extracting the renderer and its resources together should eliminate the DevTools-relative path workaround.
Minimal PHP design
Separate only responsibilities that have a concrete reason to change:
Keep CLI orchestration readable. Do not create an interface for every class or introduce a new plugin/service-container layer merely to perform extraction. Unit-test transformations; integration-test renderers and publisher boundaries.
RST guides are part of the current pipeline. phpDocumentor's hand-written documentation guide describes combined guide/API generation. Markdown support must be demonstrated with the selected renderer version and fixtures; this RFC is not a Sphinx migration.
Dependency direction
dev-tools -> documentation -> renderer/templateis acceptable.documentation -> dev-toolsis not.The main branch of github-actions is presently a scaffold. Its pending PR 2, at
28da75de2b349d4c01809994d1661062f7daf0dd, has a production requirement onfast-forward/dev-tools ^1.24. Depending on that runtime while DevTools delegates to Documentation would create:documentation -> github-actions -> dev-tools -> documentationUse small in-package adapters initially. Consider generic helper reuse only once that package has an independent, released dependency direction.
Visual ownership stays with phpdoc-bootstrap-template and the .github brand source. Do not copy the design system into a second documentation repository.
coisa commentedon Oct 14, 2026
Deep dive: library, CLI, skill and release surfaces
Follow the complete Changelog model
The inspected Changelog package is an independent library with a CLI, Docker runtime, Docker-backed operation actions, reusable workflows and a portable skill. Its
setup-dockerhelper is composite; that does not mean every operation action is composite.Documentation should provide the same product surfaces with a single implementation. Names below are proposed contracts, not existing commands:
ff-documentation build htmlff-documentation build wikiff-documentation validateff-documentation publish wikiAvoid a monolithic command that generates and publishes by default. Local generation must not need GitHub credentials. Keep native Pages deployment in GitHub's supported actions rather than implementing a second Pages transport solely for CLI symmetry.
CLI contract
Support explicit project/source, guides, target, cache, template and repository/source-SHA options; retain useful current defaults through compatibility mapping. Reject missing explicitly requested inputs. Define API-only, guides-only and empty-project outcomes, including a machine-readable skipped reason for valid empty projects. Guides-only HTML must remain supported; Wiki without an API skips rather than acquiring a new guide-rendering feature.
Use non-interactive execution, stderr diagnostics and optional JSON results. Specify stable exit semantics before consumers rely on them. Report paths and source identity, but never credentials or complete environment dumps. Resolve package assets from the installed runtime, not consumer
vendorassumptions.Changelog currently requires PHP ^8.5; DevTools and its consumers include PHP 8.3. Prefer an initial PHP 8.3-compatible local CLI if the extracted dependency graph supports it, with a separately pinned container runtime. Confirm this with Composer/platform fixtures. A newer tool runtime must not silently change a consumer's application minimum.
Portable CLI skill
Proposed canonical package:
.github/skills/documentation/SKILL.mdplus license and only necessary references. Mirror Changelog's single real source and deliberate host adapters where useful; do not invent a second procedure per host.The skill must:
listand relevant--helpbefore selecting commands;docs/_static/mascot-banner.png, template/brand ownership and manual Wiki content;Installing a skill installs instructions, not PHP, Composer, Docker or the CLI. No automatic global installation or host-link modification. Packaging tests must retain canonical skill resources and verify example commands against the released CLI. Format validation and copy/discovery checks do not prove native activation in Codex/Claude/Copilot; report that separately.
Coherent release
Use a tested Composer release and a Docker image carrying the same implementation and locked renderer/template versions. Pin deployments to a verified image digest (GitHub registry documentation).
Workflow, action, image and skill compatibility must be documented for the same release. Prefer release-relative in-repository adapters where supported; verify every externally fetched helper ref. Do not use mutable
mainor an unmerged branch as the product's release contract.Test Composer installation, Git archive contents, container invocation and packaged skill discovery in disposable directories. Add optional PHAR distribution only if a demonstrated consumer need justifies it; the first release need not solve the separate DevTools shim RFC.
coisa commentedon Oct 14, 2026
Deep dive: publication trust, ownership and lifecycle
Build and publish are different operations
The recent direct Wiki migration established no-submodule publishing, source freshness and preservation of manual content. Extraction must retain that behavior.
Build jobs may read consumer code and execute its dependency/autoload behavior, so they must not hold Wiki or Pages write credentials. Install consumer dependencies with plugins and scripts disabled where the build permits it; Composer documents this boundary in its untrusted-package guidance. Approved tool dependencies are installed independently. This reduces exposure but does not make arbitrary project execution trusted.
Writers consume only validated artifacts and must not run PHP, scripts, templates or hooks from the consumer checkout. Artifact metadata should identify the repository, source commit, triggering run and expected output; validate these against the trusted GitHub run, not just user-editable artifact fields. Store metadata inside temporary artifacts, not additional committed consumer manifests.
Wiki invariants
Use the present direct publisher and container's custom writer as the behavior baseline. Copying obsolete pointer/preview helper actions would reintroduce responsibilities the recent migration removed.
Pages and reports
One deployment owns each combined site. If documentation, coverage and metrics are produced separately, assemble their validated artifacts before one Pages upload/deploy. Define missing optional-report behavior instead of uploading a second site that erases existing sections.
Keep read-only build and Pages writer jobs separate. Callers must grant the required Pages/environment permissions explicitly; reusable workflows cannot elevate permissions granted by callers.
Preserve published URLs, API anchors, guide navigation, Dash/logo files and asset hash checks. Native publication checks must inspect the deployed site, not merely the uploaded artifact.
Framework, enum and DevTools currently have legacy gh-pages preview/cleanup behavior. Decide an explicit compatibility profile: artifact-only for untrusted/fork PRs; optionally publish reviewed same-repository previews through a trusted writer. Never execute a PR checkout with secrets via a privileged trigger. Retaining or deprecating
/previews/pr-N/routes is a separate visible decision.Version reachability
GitHub recommends commit SHA refs for reusable workflow stability (official reuse guide). The recently merged Wiki rollout also demonstrated that a pre-merge branch SHA can cease to be a valid workflow entrypoint after squash/deletion even when a file API still retrieves its blob.
Publish the final protected-main/release revision first. Verify workflow resolution in a real consumer, then pin migration PRs. Check again after merge. Changing DevTools main cannot update consumers already pinned to the old direct Wiki SHA.
Operational checks not yet performed by this RFC
Implementation must inspect each consumer's effective Pages environment, Wiki availability and secret grants. The source inventory does not prove these settings. Tokens remain scoped to publication; no new organization-wide credential or broad
secrets: inheritis required by default.coisa commentedon Oct 14, 2026
Deep dive: exact consumer inventory and migration obligations
Snapshot date: 2026-10-14. All 40 organization repositories were examined. Fourteen already consume both DevTools Wiki and documentation/report generation; twenty repositories are empty.
Immediate migration targets
Each link pins the audited committed workflow directory. Recheck main and workflow configuration when opening implementation PRs.
70518e88a47f542cf09d92b92d2d57a0a132a4969a76b880969d07a1745f944db277965050a9e6a147b0a3316cab2d8ec2179c97d7a4d819fb41202d02115eddb561af1964ef3c7a4091ddec47e55d9392102251a76a72d50f65c697fb66aa3eaf62f58085199244197ae18a02672a9bc02ca66462e877132f4fe229981906ecfd548b341ac1b97f5c2dda1aab978d0bf68e7f89084afe5afbaa631b71e74ad105ae9bbe9d7a6f6a16a30b90feec27b9e161a0e8e8c2b2607a60395469594c9a0d164e0dab2f0964df162266c50f1ea8e374be578765fe1ffb8a840fc637e7f9d8ae6059b8655996e56f6d17f874792cd6a6fa4a64d9a4316c03596ef77b265b7d29f46b68ed6305e1aac233e1781b4887abf6b44c55e127Current refs: eleven external shared Wiki callers pin
dev-tools/.github/workflows/wiki-direct.yml@c637e7f9d8ae6059b8655996e56f6d17f874792c; DevTools calls it locally. Config checks out Wiki helpers atf09a1d97c595ad2da58b0154fab1e697353d3234; container atd5a3b7eec9896f9ea50974ff09b23c32887acbc0. Both custom paths still run DevTools commands.Ten native report wrappers use
reports-native.yml@main. Framework/enum usereports.yml@main. Config's custom reports still use DevTools helpers at main and verify root, coverage and metrics routes.What every migration PR must inspect
Update the committed Wiki/reports caller and any nested report invocation in tests workflows. Also inspect DevTools-synchronized workflow resources: a later sync must not restore old defaults. Keep test/quality execution with its existing owner.
Preserve URLs, branch/event filters, PHP/platform settings, permissions, environment configuration, Wiki namespace/manual content, preview policy and deployed Dash/logo checks. Preserve existing README asset references. Do not add consumer asset READMEs or generation manifests.
For each consumer, record the old caller refs, new released refs, build comparison and post-merge publishing result. Immutable old pins require explicit changes; a compatibility edit to DevTools main is not sufficient.
Existing repositories outside immediate migration
The twenty empty repositories need future defaults, not migration PRs now:
memoize,cache,logger,console,template-renderer,feature-toggle,promises,http-middleware,scheduler,http-content-negotiation,http-healthcheck,dockerfiles,http-cache,http-apcu,http-phpinfo,application,http-error-handler,runtime,php-fast-forward,http-server.These counts describe committed source at the snapshot, not effective remote deployment settings.
coisa commentedon Oct 14, 2026
Deep dive: phased action plan, validation and rollback
Phase A — settle scope and compatibility
Accept the documentation repository/package boundary, CLI name, PHP compatibility, preview policy and DevTools deprecation window. Coordinate Wiki/docs ownership with issue 240, .github issue 2/PR 3 and the pending github-actions runtime. Do not move all organization automation into this RFC.
Deliverable: a small command/input/output contract and an ownership map. No speculative generic platform.
Phase B — independent runtime
Extract capability/configuration and HTML/Wiki generation into PHP, add thin CLI commands, package renderer resources and use Composer for dependencies. Establish a locked Docker runtime. Do not depend on DevTools or the pending github-actions package while it requires DevTools.
Keep reusable behavior shared between CLI and automation. Bash is limited to runner setup/transport where needed; avoid Python/Node helper chains. Any repository maintenance validator needed for skill adapters should also be PHP.
Deliverable: local CLI + Composer/archive/container fixtures, with generation and validation usable without GitHub credentials.
Phase C — skill and GitHub adapters
Ship one licensed portable CLI skill against the real command surface; validate examples, resource packaging, discovery and host-adapter representation. Native host activation remains a separate check.
Implement read-only build actions and reusable Wiki/docs workflows. Isolate publishers and temporary artifact metadata; preserve current freshness and ownership protections. Update future synchronized defaults and documented compatibility aliases.
Deliverable: version-coherent CLI, skill, actions and workflows with explicit credentials/permissions.
Phase D — comparison and pilots
First generate in disposable outputs without publishing, comparing the old and new implementations from the same consumer commit and dependency state. Compare meaningful routes/content/assets rather than unstable timestamps.
Suggested pilots:
Do not enable two writers for the same Wiki/site during pilots.
Deliverable: comparison evidence and a released revision proven reachable by real workflow callers.
Phase E — release and migration cohorts
Publish the package/runtime/actions/workflows/skill release before updating consumers to its final commit/digest. Validate startup, generation and publication after merge, not only inside PRs.
Then open coordinated migration PRs for all fourteen targets. Migrate the native shared group after pilots; handle config and legacy previews separately. Change DevTools compatibility and packaged synchronization defaults in the same release sequence so subsequent syncs cannot regress consumers.
Deliverable per consumer: old/new refs, preserved behavior, post-merge Wiki/Pages result and rollback instructions.
Phase F — retire compatibility
Keep existing useful aliases (
docs,reports:docs,reports:phpdoc,phpDocumentor, Wiki/report entrypoints where supported) delegating during the agreed window. Remove legacy pointer helpers and compatibility only after verified adoption and a versioned deprecation decision. Keep original tags/refs reachable.Required test matrix
Measure tool/dependency footprint and cold/warm build duration only if used to justify improvement; no performance claim is established by this investigation.
Rollback
For each pilot/cohort, keep the previous caller ref and restore it in a small revert PR if behavior fails. Disable the new writer before restoring the old one; never leave two deployments racing. A workflow revert restores execution, not already changed remote content: retain the prior Wiki commit and Pages artifact/commit as appropriate so approved content recovery is possible.
Do not delete previous generated/manual content or old release refs during extraction. Defer irreversible compatibility cleanup until the migration evidence supports it.
Completion evidence
The implementation is complete only when all fourteen consumer call sites and synchronized defaults are accounted for, final release refs resolve, the deployed Wiki/Pages surfaces pass checks, and the CLI skill matches the released runtime. This RFC publication itself performs none of those migrations.