From 14896e8d028d73dab6f8509fa3efc544ec67261f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 11:43:00 -0300 Subject: [PATCH 1/8] ci: adopt Fast Forward Changelog 0.3.0 --- .../.fast-forward-install.json | 21 +++ .agents/skills/fast-forward-changelog/LICENSE | 21 +++ .../skills/fast-forward-changelog/SKILL.md | 162 ++++++++++++++++++ .../examples/contribution.php | 45 +++++ .../references/automation.md | 89 ++++++++++ .../fast-forward-changelog/references/cli.md | 77 +++++++++ .../references/php-api.md | 40 +++++ .changelog/adopt-fast-forward-changelog.md | 6 + .gitattributes | 3 + .github/workflows/changelog.yml | 43 +++++ CONTRIBUTING.md | 25 +++ README.md | 4 + 12 files changed, 536 insertions(+) create mode 100644 .agents/skills/fast-forward-changelog/.fast-forward-install.json create mode 100644 .agents/skills/fast-forward-changelog/LICENSE create mode 100644 .agents/skills/fast-forward-changelog/SKILL.md create mode 100644 .agents/skills/fast-forward-changelog/examples/contribution.php create mode 100644 .agents/skills/fast-forward-changelog/references/automation.md create mode 100644 .agents/skills/fast-forward-changelog/references/cli.md create mode 100644 .agents/skills/fast-forward-changelog/references/php-api.md create mode 100644 .changelog/adopt-fast-forward-changelog.md create mode 100644 .github/workflows/changelog.yml create mode 100644 CONTRIBUTING.md diff --git a/.agents/skills/fast-forward-changelog/.fast-forward-install.json b/.agents/skills/fast-forward-changelog/.fast-forward-install.json new file mode 100644 index 0000000..fdfb45a --- /dev/null +++ b/.agents/skills/fast-forward-changelog/.fast-forward-install.json @@ -0,0 +1,21 @@ +{ + "schema": 1, + "owner": "fast-forward/changelog", + "name": "fast-forward-changelog", + "scope": "project", + "target": ".agents/skills/fast-forward-changelog", + "source": { + "package": "fast-forward/changelog", + "version": "v0.3.0", + "reference": "85474de5a16bb08f83c9f30e0ed72f331a210f07" + }, + "files": { + "LICENSE": "58bd7c00603e499c575d53a97b8b8c1d1398f584ea5f9f77d369780efb2066ab", + "SKILL.md": "a71cfdffae34b69e555955b6b82be858bf65e4406f954d566b651cda0f0cd952", + "examples/contribution.php": "46f2b30277b4f880a8fc4f5d503d2a4fd13c6802a929159b1895f55f9a97dd2e", + "references/automation.md": "0cb96ff6d62f44c19f514fcbb42b88fbe5f7382bcfed87c533c8ac6fd3bc95bb", + "references/cli.md": "787f33efcbc72d40ce5b55507f6f0a59b686bffe4d7edfcf4242c427d7db023e", + "references/php-api.md": "32b67728f3c4ba5870a40f5ad88946dd274f84619676d4783642780a172cade8" + }, + "payload_sha256": "f1969293e2f761bfea32eb4d3e04980cf7a8f2a48313188a20d15390751eb681" +} diff --git a/.agents/skills/fast-forward-changelog/LICENSE b/.agents/skills/fast-forward-changelog/LICENSE new file mode 100644 index 0000000..f320900 --- /dev/null +++ b/.agents/skills/fast-forward-changelog/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Felipe Sayao Lobato Abreu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.agents/skills/fast-forward-changelog/SKILL.md b/.agents/skills/fast-forward-changelog/SKILL.md new file mode 100644 index 0000000..e43f1c0 --- /dev/null +++ b/.agents/skills/fast-forward-changelog/SKILL.md @@ -0,0 +1,162 @@ +--- +name: fast-forward-changelog +description: Adopt Fast Forward Changelog's GitHub lifecycle, write and check independent fragments, review version PRs, and perform authorized release maintenance. Discover the selected release's documentation and CLI capabilities before choosing integration details. +license: MIT +compatibility: Requires access to the application repository and the selected release's documentation. Verify that release's runner or PHP requirements before execution. Local CLI examples use CPX; PHP integration uses the application's Composer installation. GitHub credentials are needed only for authorized remote operations. +metadata: + author: php-fast-forward + source: original + repository: https://github.com/php-fast-forward/changelog + api-baseline: Verify the selected published release; commands and integration details are release-specific. +--- + +# Fast Forward Changelog + +Ordinary contributions add independent `.changelog/*.md` fragments. GitHub +automation checks each contribution, maintains PR feedback and prepares a +reviewable version PR. That PR consolidates the accepted fragments into +`CHANGELOG.md` and deletes only the consumed files. Publication follows a +separate approval for the exact result; a green check or prepared PR is not that +approval. + +## Select the real contract + +1. Read application instructions, Git status and its existing changelog setup. + Use its reviewed version for an ordinary task; do not upgrade it incidentally. + If its ref is a moving channel, resolve the current commit and corresponding + published full tag before selecting a local runtime. `v0` is not Composer `0`. +2. For new adoption or a requested update, discover the latest published stable + release in the [official repository](https://github.com/php-fast-forward/changelog/releases). + Confirm the complete release tag and its commit, exclude drafts/prereleases, + and respect any explicitly selected maintenance line. For CPX or PHP use, + confirm the same version is available on + [Packagist](https://packagist.org/packages/fast-forward/changelog). +3. Read that tag's README and relevant documentation, not `main` or an old copy + of this skill. Before adding a workflow, inspect its + `resources/workflows/changelog.yml`, companion README and the reusable workflow + they reference. Copy the release's caller, review inputs/permissions and set + its product references to that verified full tag or immutable release commit; + do not retain an obsolete embedded pin blindly. After setting the final ref, + inspect the reusable workflow at that exact ref and confirm its inputs, + permissions and runner requirements before saving the application caller. + If that release offers a project `install` command, inspect its help and prefer + its guided preview for a missing integration. Explain the release branch, + publication default and optional skill before accepting writes. + The lifecycle defaults to `publish: true`; confirm this at the selected ref. + Its automatic route publishes a version tag and GitHub Release + after the reviewed managed PR is merged; it does not merge the PR. A + validation-only trial must choose `publish: false` explicitly. Installation must + not publish anything. Preserve an existing caller, its pin and settings; + migration or upgrades need their own task scope. +4. For local CLI work, set `CHANGELOG_VERSION` to the verified exact numeric + release, without the tag's `v`. Discover commands and inspect their arguments: + + ```sh + cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" list --raw + cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help add + cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help check + ``` + + Use [CPX's official setup](https://github.com/laravel/cpx) when installation is + authorized; do not pin the executor in these commands. `--skip-local` selects + its separate tool installation. CPX may handle `--help` or `--version` itself, + so use `help ` for changelog help. An existing reviewed project binary + may be used directly instead. Confirm prerequisites from the chosen release. + +Installing this skill installs instructions, independently of the runtime. If +the selected CLI offers skill installation/check/update operations, inspect +their help and use only the supported operation and requested scope. Otherwise +follow that release's skill-installation guide; do not invent a command. + +Native installation can record the source package version, commit and payload +integrity. Compare an installed copy with the selected CLI through its documented +check operation; do not confuse that local comparison with a latest-version +lookup. Preserve NPX or other installer ownership and its lockfile rather than +trying to adopt the copy or rewrite metadata into a merely similar JSON format. + +This procedure avoids a frozen API inventory. A breaking release can still +change the lifecycle or these entrypoints: when documentation and capabilities +disagree, resolve the mismatch before writes rather than guessing compatibility. + +## Write and check a contribution + +Read the change and describe its observable effect. For example, create one +unique `.changelog/preserve-markdown-spaces.md`: + +```markdown +--- +category: fixed +type: patch +--- + +Preserves meaningful Markdown spaces when parsing fragments. +``` + +Keep existing notes and Markdown intact. Use the selected release's fragment +schema. For the established category scheme, `added`, `changed` and `deprecated` +default to `minor`, `removed` to `major`, and `fixed`/`security` to `patch`. +Persist the effective type explicitly; a justified override may express a +compatible dependency change as `changed`/`patch`. Apply the application's +versioning policy deliberately, especially during `0.x` development. + +After help confirms these arguments, the CLI can create and validate that note +from the application directory instead of writing the example manually: + +```sh +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" add "Preserves meaningful Markdown spaces when parsing fragments." --category=fixed --no-interaction +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" check --no-interaction +``` + +Verify that exactly one intended fragment was created and central history stayed +unchanged. Do not run both authoring routes for the same note. Fix diagnostics +and rerun the check. Before a committed PR comparison, inspect `help check`, +fetch the intended baseline under existing authority, then use its supported +comparison option, for example: + +```sh +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" check --since=origin/main --no-interaction +``` + +That comparison requires committed contribution changes. A local uncommitted +fragment can pass local validation without satisfying the PR comparison. + +Optional PR/issue/author metadata must come from verified evidence. When the +origin PR is already known and supported, use `--pull-request=` or +`pull_request: ` after confirming its repository and exact head. Leave +unknown fields absent; do not invent a number or require a second fragment +commit after opening a PR. If the selected release resolves PR origins during +compilation, follow its documented policy consistently across preparation and +publication. No qualifying PR should become an invented commit or author link. + +Ordinary work preserves inherited fragments and published history. Do not add a +new `Unreleased` section. Editorial replacement, history maintenance and release +consolidation require their own task scope. + +## Verify the lifecycle + +For adoption, open a small pilot PR and inspect the exact head's required status, +sticky comment and independent application checks. Exercise a missing or +malformed note and any enabled bot route. Inspect the generated version PR: +planned version/impact, exact notes, central-history changes and only the accepted +fragment deletions. Review again after its head changes. The workflow does not +merge its own version PR. + +For the selected release, verify how committed history and ancestral tags define +the version baseline. The current lifecycle advances from the greatest stable +version in either source: tag `v1.7.0`, committed history through `1.7.1` and a +new patch produce `1.7.2`. Skipping publication does not block the next PR or +authorize retroactive publication of `1.7.1`. Preserve earlier history and review +the proposed next version; do not create missing tags as an incidental repair. + +Load only the reference needed for the task: + +- [Automation](references/automation.md): selected caller, optional settings, + credentials, maintenance lines and pilot verification. +- [CLI maintenance](references/cli.md): previews, consolidation, history, + interrupted transactions and separately authorized publication. +- [PHP integration](references/php-api.md): release-specific application + services and the bundled example, only when programmatic integration is needed. + +Retain authority already given, but do not infer commit, push, merge, installation +elsewhere or publication authority from an ordinary fragment task. Report changed +paths, executed checks and the verified version/PR/SHA relevant to the result. diff --git a/.agents/skills/fast-forward-changelog/examples/contribution.php b/.agents/skills/fast-forward-changelog/examples/contribution.php new file mode 100644 index 0000000..1fdd8de --- /dev/null +++ b/.agents/skills/fast-forward-changelog/examples/contribution.php @@ -0,0 +1,45 @@ + + * @license https://opensource.org/licenses/MIT MIT License + */ + +use FastForward\Changelog\Container\ServiceProvider\ChangelogServiceProvider; +use FastForward\Changelog\Fragment\FragmentWriterInterface; +use FastForward\Changelog\Release\Factory\ReleaseOptionsFactoryInterface; +use FastForward\Changelog\Validation\CheckServiceInterface; + +use function FastForward\Container\container; + +$autoload = $argv[1] ?? ''; +$directory = realpath($argv[2] ?? ''); +if ('' === $autoload || !is_file($autoload) || !isset($argv[2]) || false === $directory || !is_dir($directory)) { + fwrite(STDERR, "Usage: php contribution.php /consumer/vendor/autoload.php /existing/project\n"); + exit(2); +} +require $autoload; + +$container = container(ChangelogServiceProvider::class); +$options = $container->get(ReleaseOptionsFactoryInterface::class)->create([ + 'workingDirectory' => $directory, + 'source' => 'tags', +]); +$path = $container->get(FragmentWriterInterface::class)->add( + $options, + 'Preserves meaningful Markdown spaces when parsing fragments.', + category: 'fixed', + name: 'php-api-example.md', +); +$expected = "---\ncategory: fixed\ntype: patch\n---\n\nPreserves meaningful Markdown spaces when parsing fragments.\n"; +if ($expected !== file_get_contents($path)) { + throw new RuntimeException('The fragment does not match the expected application output.'); +} +if (!$container->get(CheckServiceInterface::class)->check($options)->isValid()) { + throw new RuntimeException('The pending fragment inventory is invalid.'); +} +fwrite(STDOUT, "Contribution example PASS\n"); diff --git a/.agents/skills/fast-forward-changelog/references/automation.md b/.agents/skills/fast-forward-changelog/references/automation.md new file mode 100644 index 0000000..46fe275 --- /dev/null +++ b/.agents/skills/fast-forward-changelog/references/automation.md @@ -0,0 +1,89 @@ +# GitHub lifecycle adoption + +Load when installing or changing workflows, configuring credentials or runners, +selecting maintenance lines, or diagnosing feedback. Discover the latest stable +published release for new adoption, respecting an explicitly selected release +line. For ordinary work, retain the application's reviewed implementation. + +## Use the selected release's caller + +From the verified full tag, read `README.md`, +`resources/workflows/changelog.yml`, its companion README, and the reusable +workflow referenced by that caller. Consult that tag's relevant guides, including +`docs/reusable-lifecycle.md`, `docs/github-app.md` and `docs/automation-map.md` when +present. If paths moved, follow that release's README rather than guessing. +Do not combine a caller from one version with settings copied from `main`. + +If that release lists `install`, inspect its command help and installation guide +before choosing a route. Guided setup can ask for the release branch, publication +choice, advanced overrides and optional project skill, then preview a missing +caller. It must preserve an existing caller and refuse ambiguous or competing +automation. Use read-only preview first; noninteractive application requires its +documented confirmation option. For a new caller, select the published release +through that command's supported release option; its installer can pin `uses` +to the verified commit and retain the version as a readable comment. Confirm +both identities in the preview. Preserve the selected pin of an existing caller. +The workflow and bundled skill may have separate +provenance: a workflow ref does not change the executing CLI's instructions. + +For manual setup, copy the caller into the application's `.github/workflows/`, review its events, +inputs and effective permissions, then set its product references to the selected +published complete tag or verified immutable release commit. Review older pins +embedded in the copied caller. After replacing a pin, inspect the reusable +workflow at the final selected ref and verify its actual inputs, permissions and +runner requirements before saving the application caller. +GitHub `uses` references the executable reusable +workflow under `.github/workflows`; the resource caller is a copyable asset. +Internal `repository-*` workflows belong to the library, not the consumer. + +Explain the selected reusable's publication default before installing its caller. +The lifecycle defaults to `publish: true`; verify this at the final selected ref. +The automatic route publishes the exact version tag and GitHub Release after a +reviewed managed version PR is merged. The workflow does not merge the PR. +Setup itself does not publish anything. +Choose `publish: false` explicitly when the task is a validation-only trial; +do not silently carry that override into an installation meant to publish. +Choose base and managed branches, +fragment/history paths, historical sources and PR-reference policy consistently +across enabled operations. For parallel maintenance, select a separate managed +branch per release line and verify its actual planned version; a branch's name +does not enforce a SemVer range. Use individual workflows or Docker actions only +when their release-specific contracts suit the application's orchestration. + +Full tags identify concrete releases; an immutable commit pin also keeps execution +bound to the reviewed code if an upstream tag is changed. A moving major channel +is an explicit update policy and must be documented by the selected product release; +do not assume it exists. In particular `@v0` may cross breaking `0.x` minors and +does not mean Composer `^0.1`. Changing a workflow ref is a deliberate update. + +## Credentials and acceptance + +Use the selected workflow's documented token/App route and the application's +approved secret storage. Preserve the verified automation identity and narrow +permissions. Never check out untrusted PR code in a privileged custom job. +Token-generated events may behave differently from human/App events; consult +the selected release and GitHub's current rules before promising downstream CI. + +For an explicitly validation-only pilot, use `publish: false`. Verify a valid +fragment, missing or malformed notes, the exact PR head's required status and sticky-comment recovery, +any enabled bot operation, and the generated version PR. Check the actual runner +requirements and access when changing Linux/self-hosted selection. Test custom +policy changes relevant to the application rather than assuming a default-branch +green run proves its generated head. + +The version PR must preserve exact notes and consume only its accepted fragment +set, with no technical plan files or new `Unreleased` section. Head changes need +fresh review and checks. Successful preparation does not authorize merging or +publication. Retain existing publication authority for the verified result, +using the selected release's committed evidence and recovery procedure. + +## Consolidation without publication + +Confirm the selected release's version-baseline rule. The current lifecycle uses +the greatest stable version in committed source history or ancestral stable +tags. With tag `v1.7.0` and committed history through `1.7.1`, a new patch prepares +`1.7.2` while preserving the earlier history. An explicit `publish: false` +creates neither tag nor GitHub Release, but does not block subsequent version +PRs. Enabling publication for a later merge does not publish older consolidated +versions retroactively. Do not remove history or manufacture a missing tag merely +to make another PR possible. diff --git a/.agents/skills/fast-forward-changelog/references/cli.md b/.agents/skills/fast-forward-changelog/references/cli.md new file mode 100644 index 0000000..55eea75 --- /dev/null +++ b/.agents/skills/fast-forward-changelog/references/cli.md @@ -0,0 +1,77 @@ +# CLI maintenance + +Load for release previews, history maintenance, recovery or authorized +publication. First select the real release and inspect `list --raw` and +`help ` as described in the skill. Read `docs/cli-fragments.md` and the +relevant maintenance/publication guide from that complete release tag. Verify +that its PHP and Git requirements match the environment. Do not infer arguments +or current behavior from an older installed skill. + +## Execute the selected CLI + +Run from the application's directory. `CHANGELOG_VERSION` is the verified exact +numeric product version, not a range frozen into this skill: + +```sh +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" list --raw +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help status +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help version +``` + +CPX keeps tool dependencies separate from the application's Composer project; +the command still operates on application files. It is not a filesystem sandbox +or a PHP runtime. CPX's own update/help/version commands concern the executor. +An existing reviewed `vendor/bin/changelog` may run the same supported arguments +without changing the application's dependencies. + +When `list` offers instruction-management operations, inspect their help before +using install, check or update options. Use the requested project/global scope +and preserve local changes. Their existence is a discovered capability, not a +promise that every published changelog version contains them. Runtime updates, +instruction installation and host-session activation remain separate results. + +## Preview before consolidation + +For releases offering these arguments, inspect the read-only plan first: + +```sh +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" status --json --source=tags --no-interaction +cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" version --dry-run --source=tags --no-interaction +``` + +Review the baseline/current/next version, effective impact, accepted fragment +paths, notes and affected files. Choose the relevant maintenance branch and +historical source explicitly. A branch name alone does not establish a release +range. Check command help before treating an exit code as success or failure; +check modes may use a nonzero result for drift as well as errors. + +The normal GitHub lifecycle prepares the version PR. Applying a local version +transaction requires existing consolidation authority and the same reviewed +options as the preview. Preserve exact committed input bytes, custom-template +trust requirements and any PR-resolution setting required by that release. +Verify only central history and consumed-fragment deletions are changed; no +technical plan file or new `Unreleased` section belongs in the version PR. + +If interrupted, preserve the recovery journal and remaining files. Follow that +release's recovery procedure with the same inputs. Do not edit a journal, delete +newer notes or replace history merely to force a retry. + +## Additional maintenance and publication + +Backfill, format, notes extraction and custom templates are optional operations. +Discover their actual commands and read that release's guide before using them. +Keep published descriptions, unknown dates, existing references and pending +fragments intact as required by the operation. Executable PHP templates require +explicit trust. Preview mutations and review the resulting diff. + +Publication requires separate authority for an exact approved full commit SHA. +Read that release's publication guide and command help, preview when supported, +and supply the verified target explicitly. Use the application's approved +credential mechanism. Verify the approved version, notes, consumed fragments, +tag and source commit; PR text or a moving branch is not transaction evidence. +Preparation and publication must use the same policies that affect the output. + +Do not move conflicting concrete tags or overwrite divergent published notes. +After an uncertain response, inspect remote evidence and follow the selected +release's idempotent recovery route under the existing authority. Report what +was actually published or recovered separately from successful validation. diff --git a/.agents/skills/fast-forward-changelog/references/php-api.md b/.agents/skills/fast-forward-changelog/references/php-api.md new file mode 100644 index 0000000..2dc88e4 --- /dev/null +++ b/.agents/skills/fast-forward-changelog/references/php-api.md @@ -0,0 +1,40 @@ +# Optional PHP integration + +Load only when the application needs injected services instead of the CLI or +GitHub lifecycle. CPX executes a separate tool; it does not provide an application +autoloader. Inspect the application's Composer installation with +`composer show fast-forward/changelog`, then read the PHP integration/API guide, +manifest requirements and migration notes from that exact release tag. + +Use the installed namespaces and method signatures. Keep the application's +existing command loader, container precedence and secret mechanism. Expose only +the needed domain services and inject external boundaries in application tests. +Resolving a service or writing a fragment does not authorize commits or releases. + +## Bundled contribution example + +The complete [contribution program](../examples/contribution.php) illustrates the +`0.1.0` PHP API: explicit consumer autoloader and target directory, provider +composition, fragment creation and validation. It is an optional example, not +the contract for every later release. Before using it with another version, +compare its imports/signatures with that release's documented API or use the +example shipped with the selected release. + +For a matching API, run it first in a disposable target: + +```sh +php .agents/skills/fast-forward-changelog/examples/contribution.php ./vendor/autoload.php /absolute/project +vendor/bin/changelog check --no-interaction +``` + +Success prints `Contribution example PASS`; exactly one +`.changelog/php-api-example.md` is created, with no commit or central-history +change. A repeated run must expose the filename collision rather than overwrite +the file. Missing inputs and runtime failures remain nonzero. Do not report +success after a failed write or ignore the validation report. + +Keep PR/issue/author fields absent unless verified. Service access follows the +same fragment, version-transaction and publication boundaries as the selected +release's CLI. Learn optional configuration, planner/history services and +approved-commit publication from that version's documentation when the task +requires them; do not load an API inventory for an ordinary fragment task. diff --git a/.changelog/adopt-fast-forward-changelog.md b/.changelog/adopt-fast-forward-changelog.md new file mode 100644 index 0000000..68b2609 --- /dev/null +++ b/.changelog/adopt-fast-forward-changelog.md @@ -0,0 +1,6 @@ +--- +category: changed +type: patch +--- + +Automate changelog checks, PR feedback and reviewed releases with Fast Forward Changelog, including the project agent skill. diff --git a/.gitattributes b/.gitattributes index 0a74ce0..8cf3182 100755 --- a/.gitattributes +++ b/.gitattributes @@ -13,4 +13,7 @@ /phpunit.xml export-ignore /docs/ export-ignore /README*.md export-ignore +/.agents/ export-ignore +/.changelog/ export-ignore +/CONTRIBUTING.md export-ignore /composer-dependency-analyser.php export-ignore diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000..7771866 --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,43 @@ +name: Changelog + +on: + pull_request: + branches: + - main + types: + - opened + - synchronize + - reopened + - ready_for_review + - labeled + - unlabeled + pull_request_target: + branches: + - main + types: + - opened + - synchronize + - reopened + - ready_for_review + - labeled + - unlabeled + - closed + push: + branches: + - main + workflow_dispatch: null + +permissions: {} + +jobs: + changelog: + permissions: + contents: write + pull-requests: write + issues: read + statuses: write + uses: php-fast-forward/changelog/.github/workflows/changelog.yml@85474de5a16bb08f83c9f30e0ed72f331a210f07 # v0.3.0 + with: + source: tags + version-pr-title: 'chore(release): http {current_version} → {next_version}' + base-branch: main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..623cfb7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing + +Include one unique `.changelog/*.md` fragment for each observable change. Use +PHP 8.5+ and [CPX](https://github.com/laravel/cpx) to run the isolated tooling; +the library itself does not gain a runtime dependency: + +```sh +cpx --skip-local fast-forward/changelog:0.3.0 add "Describe the change." --category=fixed --type=patch --no-interaction +cpx --skip-local fast-forward/changelog:0.3.0 check --no-interaction +# Compare committed changes with the contribution base: +cpx --skip-local fast-forward/changelog:0.3.0 check --since=origin/main --no-interaction +``` + +Select the category and semantic impact that describe the change. Keep published +history intact; pending notes belong in fragments rather than an `Unreleased` +section. The project skill is installed at +[`.agents/skills/fast-forward-changelog/SKILL.md`](.agents/skills/fast-forward-changelog/SKILL.md). +Check its local integrity with +`cpx --skip-local fast-forward/changelog:0.3.0 skill:install --check --json`. + +The pinned [workflow](.github/workflows/changelog.yml) validates PR notes, +maintains PR feedback and prepares one version PR on `changelog/version`. +Review that PR's version, history and consumed fragments before merging. +After that approved version PR is merged into `main`, automatic publication +creates its version tag and GitHub Release. The workflow never merges PRs. diff --git a/README.md b/README.md index bc99f9e..faf6f47 100644 --- a/README.md +++ b/README.md @@ -92,3 +92,7 @@ See the documentation sources in [`docs/`](docs/) for: ## License Fast Forward HTTP is licensed under the [MIT license](LICENSE). + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for changelog fragments, local checks and the release-review flow. From e3f5ec8875c5de66111e4200883991c41d2086a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 11:46:16 -0300 Subject: [PATCH 2/8] fix: preserve published release notes during history import --- .github/workflows/changelog.yml | 2 +- CONTRIBUTING.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 7771866..91625e6 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -38,6 +38,6 @@ jobs: statuses: write uses: php-fast-forward/changelog/.github/workflows/changelog.yml@85474de5a16bb08f83c9f30e0ed72f331a210f07 # v0.3.0 with: - source: tags + source: github version-pr-title: 'chore(release): http {current_version} → {next_version}' base-branch: main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 623cfb7..3f2fbc3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,3 +23,7 @@ maintains PR feedback and prepares one version PR on `changelog/version`. Review that PR's version, history and consumed fragments before merging. After that approved version PR is merged into `main`, automatic publication creates its version tag and GitHub Release. The workflow never merges PRs. + +Historical notes are imported from GitHub Releases, preserving the published +descriptions when the first central changelog is prepared. Empty release bodies +still need editorial review; no PR attribution is inferred from prose alone. From 9cabd14d43c94a96e1b9c5f0fd90abcf792af5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 12:34:56 -0300 Subject: [PATCH 3/8] chore: complete history and follow the v0 release channel --- .github/workflows/changelog.yml | 4 ++-- CHANGELOG.md | 27 +++++++++++++++++++++++++++ CONTRIBUTING.md | 15 ++++++++------- 3 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 91625e6..b3fd82f 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -36,8 +36,8 @@ jobs: pull-requests: write issues: read statuses: write - uses: php-fast-forward/changelog/.github/workflows/changelog.yml@85474de5a16bb08f83c9f30e0ed72f331a210f07 # v0.3.0 + uses: php-fast-forward/changelog/.github/workflows/changelog.yml@v0 with: source: github - version-pr-title: 'chore(release): http {current_version} → {next_version}' + version-pr-title: 'chore(release): fast-forward/http v{current_version} → v{next_version}' base-branch: main diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..af591e0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.0] - 2026-03-29 + +**Full Changelog**: https://github.com/php-fast-forward/http/compare/v1.0.1...v1.1.0 + +## [1.0.1] - 2025-08-01 + +Release notes are unavailable for this version. + +## [1.0.0] - 2025-08-01 + +Release notes are unavailable for this version. + +## [0.1.0] - 2025-08-01 + +Release notes are unavailable for this version. + +[1.1.0]: https://github.com/php-fast-forward/http/compare/v1.0.1...v1.1.0 +[1.0.1]: https://github.com/php-fast-forward/http/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/php-fast-forward/http/compare/v0.1.0...v1.0.0 +[0.1.0]: https://github.com/php-fast-forward/http/releases/tag/v0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f2fbc3..cf932de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,10 +5,10 @@ PHP 8.5+ and [CPX](https://github.com/laravel/cpx) to run the isolated tooling; the library itself does not gain a runtime dependency: ```sh -cpx --skip-local fast-forward/changelog:0.3.0 add "Describe the change." --category=fixed --type=patch --no-interaction -cpx --skip-local fast-forward/changelog:0.3.0 check --no-interaction +cpx --skip-local fast-forward/changelog add "Describe the change." --category=fixed --type=patch --no-interaction +cpx --skip-local fast-forward/changelog check --no-interaction # Compare committed changes with the contribution base: -cpx --skip-local fast-forward/changelog:0.3.0 check --since=origin/main --no-interaction +cpx --skip-local fast-forward/changelog check --since=origin/main --no-interaction ``` Select the category and semantic impact that describe the change. Keep published @@ -16,14 +16,15 @@ history intact; pending notes belong in fragments rather than an `Unreleased` section. The project skill is installed at [`.agents/skills/fast-forward-changelog/SKILL.md`](.agents/skills/fast-forward-changelog/SKILL.md). Check its local integrity with -`cpx --skip-local fast-forward/changelog:0.3.0 skill:install --check --json`. +`cpx --skip-local fast-forward/changelog skill:install --check --json`. -The pinned [workflow](.github/workflows/changelog.yml) validates PR notes, +The [workflow](.github/workflows/changelog.yml) validates PR notes, maintains PR feedback and prepares one version PR on `changelog/version`. Review that PR's version, history and consumed fragments before merging. After that approved version PR is merged into `main`, automatic publication creates its version tag and GitHub Release. The workflow never merges PRs. -Historical notes are imported from GitHub Releases, preserving the published -descriptions when the first central changelog is prepared. Empty release bodies +`CHANGELOG.md` includes all four published stable versions, backfilled from +GitHub Releases. The workflow preserves that evidence with `source: github`. +Empty release bodies still need editorial review; no PR attribution is inferred from prose alone. From a6f6a333133a34fb002c241520920592c228dda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 13:16:44 -0300 Subject: [PATCH 4/8] chore: manage Changelog skill through Composer --- .../.fast-forward-install.json | 21 --- .agents/skills/fast-forward-changelog/LICENSE | 21 --- .../skills/fast-forward-changelog/SKILL.md | 162 ------------------ .../examples/contribution.php | 45 ----- .../references/automation.md | 89 ---------- .../fast-forward-changelog/references/cli.md | 77 --------- .../references/php-api.md | 40 ----- .../composer-managed-changelog-skill.md | 6 + .gitattributes | 1 + .gitignore | 1 + CONTRIBUTING.md | 12 +- composer.json | 6 +- skills.json | 21 +++ 13 files changed, 41 insertions(+), 461 deletions(-) delete mode 100644 .agents/skills/fast-forward-changelog/.fast-forward-install.json delete mode 100644 .agents/skills/fast-forward-changelog/LICENSE delete mode 100644 .agents/skills/fast-forward-changelog/SKILL.md delete mode 100644 .agents/skills/fast-forward-changelog/examples/contribution.php delete mode 100644 .agents/skills/fast-forward-changelog/references/automation.md delete mode 100644 .agents/skills/fast-forward-changelog/references/cli.md delete mode 100644 .agents/skills/fast-forward-changelog/references/php-api.md create mode 100644 .changelog/composer-managed-changelog-skill.md create mode 100644 skills.json diff --git a/.agents/skills/fast-forward-changelog/.fast-forward-install.json b/.agents/skills/fast-forward-changelog/.fast-forward-install.json deleted file mode 100644 index fdfb45a..0000000 --- a/.agents/skills/fast-forward-changelog/.fast-forward-install.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "schema": 1, - "owner": "fast-forward/changelog", - "name": "fast-forward-changelog", - "scope": "project", - "target": ".agents/skills/fast-forward-changelog", - "source": { - "package": "fast-forward/changelog", - "version": "v0.3.0", - "reference": "85474de5a16bb08f83c9f30e0ed72f331a210f07" - }, - "files": { - "LICENSE": "58bd7c00603e499c575d53a97b8b8c1d1398f584ea5f9f77d369780efb2066ab", - "SKILL.md": "a71cfdffae34b69e555955b6b82be858bf65e4406f954d566b651cda0f0cd952", - "examples/contribution.php": "46f2b30277b4f880a8fc4f5d503d2a4fd13c6802a929159b1895f55f9a97dd2e", - "references/automation.md": "0cb96ff6d62f44c19f514fcbb42b88fbe5f7382bcfed87c533c8ac6fd3bc95bb", - "references/cli.md": "787f33efcbc72d40ce5b55507f6f0a59b686bffe4d7edfcf4242c427d7db023e", - "references/php-api.md": "32b67728f3c4ba5870a40f5ad88946dd274f84619676d4783642780a172cade8" - }, - "payload_sha256": "f1969293e2f761bfea32eb4d3e04980cf7a8f2a48313188a20d15390751eb681" -} diff --git a/.agents/skills/fast-forward-changelog/LICENSE b/.agents/skills/fast-forward-changelog/LICENSE deleted file mode 100644 index f320900..0000000 --- a/.agents/skills/fast-forward-changelog/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2026 Felipe Sayao Lobato Abreu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/.agents/skills/fast-forward-changelog/SKILL.md b/.agents/skills/fast-forward-changelog/SKILL.md deleted file mode 100644 index e43f1c0..0000000 --- a/.agents/skills/fast-forward-changelog/SKILL.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -name: fast-forward-changelog -description: Adopt Fast Forward Changelog's GitHub lifecycle, write and check independent fragments, review version PRs, and perform authorized release maintenance. Discover the selected release's documentation and CLI capabilities before choosing integration details. -license: MIT -compatibility: Requires access to the application repository and the selected release's documentation. Verify that release's runner or PHP requirements before execution. Local CLI examples use CPX; PHP integration uses the application's Composer installation. GitHub credentials are needed only for authorized remote operations. -metadata: - author: php-fast-forward - source: original - repository: https://github.com/php-fast-forward/changelog - api-baseline: Verify the selected published release; commands and integration details are release-specific. ---- - -# Fast Forward Changelog - -Ordinary contributions add independent `.changelog/*.md` fragments. GitHub -automation checks each contribution, maintains PR feedback and prepares a -reviewable version PR. That PR consolidates the accepted fragments into -`CHANGELOG.md` and deletes only the consumed files. Publication follows a -separate approval for the exact result; a green check or prepared PR is not that -approval. - -## Select the real contract - -1. Read application instructions, Git status and its existing changelog setup. - Use its reviewed version for an ordinary task; do not upgrade it incidentally. - If its ref is a moving channel, resolve the current commit and corresponding - published full tag before selecting a local runtime. `v0` is not Composer `0`. -2. For new adoption or a requested update, discover the latest published stable - release in the [official repository](https://github.com/php-fast-forward/changelog/releases). - Confirm the complete release tag and its commit, exclude drafts/prereleases, - and respect any explicitly selected maintenance line. For CPX or PHP use, - confirm the same version is available on - [Packagist](https://packagist.org/packages/fast-forward/changelog). -3. Read that tag's README and relevant documentation, not `main` or an old copy - of this skill. Before adding a workflow, inspect its - `resources/workflows/changelog.yml`, companion README and the reusable workflow - they reference. Copy the release's caller, review inputs/permissions and set - its product references to that verified full tag or immutable release commit; - do not retain an obsolete embedded pin blindly. After setting the final ref, - inspect the reusable workflow at that exact ref and confirm its inputs, - permissions and runner requirements before saving the application caller. - If that release offers a project `install` command, inspect its help and prefer - its guided preview for a missing integration. Explain the release branch, - publication default and optional skill before accepting writes. - The lifecycle defaults to `publish: true`; confirm this at the selected ref. - Its automatic route publishes a version tag and GitHub Release - after the reviewed managed PR is merged; it does not merge the PR. A - validation-only trial must choose `publish: false` explicitly. Installation must - not publish anything. Preserve an existing caller, its pin and settings; - migration or upgrades need their own task scope. -4. For local CLI work, set `CHANGELOG_VERSION` to the verified exact numeric - release, without the tag's `v`. Discover commands and inspect their arguments: - - ```sh - cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" list --raw - cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help add - cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help check - ``` - - Use [CPX's official setup](https://github.com/laravel/cpx) when installation is - authorized; do not pin the executor in these commands. `--skip-local` selects - its separate tool installation. CPX may handle `--help` or `--version` itself, - so use `help ` for changelog help. An existing reviewed project binary - may be used directly instead. Confirm prerequisites from the chosen release. - -Installing this skill installs instructions, independently of the runtime. If -the selected CLI offers skill installation/check/update operations, inspect -their help and use only the supported operation and requested scope. Otherwise -follow that release's skill-installation guide; do not invent a command. - -Native installation can record the source package version, commit and payload -integrity. Compare an installed copy with the selected CLI through its documented -check operation; do not confuse that local comparison with a latest-version -lookup. Preserve NPX or other installer ownership and its lockfile rather than -trying to adopt the copy or rewrite metadata into a merely similar JSON format. - -This procedure avoids a frozen API inventory. A breaking release can still -change the lifecycle or these entrypoints: when documentation and capabilities -disagree, resolve the mismatch before writes rather than guessing compatibility. - -## Write and check a contribution - -Read the change and describe its observable effect. For example, create one -unique `.changelog/preserve-markdown-spaces.md`: - -```markdown ---- -category: fixed -type: patch ---- - -Preserves meaningful Markdown spaces when parsing fragments. -``` - -Keep existing notes and Markdown intact. Use the selected release's fragment -schema. For the established category scheme, `added`, `changed` and `deprecated` -default to `minor`, `removed` to `major`, and `fixed`/`security` to `patch`. -Persist the effective type explicitly; a justified override may express a -compatible dependency change as `changed`/`patch`. Apply the application's -versioning policy deliberately, especially during `0.x` development. - -After help confirms these arguments, the CLI can create and validate that note -from the application directory instead of writing the example manually: - -```sh -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" add "Preserves meaningful Markdown spaces when parsing fragments." --category=fixed --no-interaction -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" check --no-interaction -``` - -Verify that exactly one intended fragment was created and central history stayed -unchanged. Do not run both authoring routes for the same note. Fix diagnostics -and rerun the check. Before a committed PR comparison, inspect `help check`, -fetch the intended baseline under existing authority, then use its supported -comparison option, for example: - -```sh -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" check --since=origin/main --no-interaction -``` - -That comparison requires committed contribution changes. A local uncommitted -fragment can pass local validation without satisfying the PR comparison. - -Optional PR/issue/author metadata must come from verified evidence. When the -origin PR is already known and supported, use `--pull-request=` or -`pull_request: ` after confirming its repository and exact head. Leave -unknown fields absent; do not invent a number or require a second fragment -commit after opening a PR. If the selected release resolves PR origins during -compilation, follow its documented policy consistently across preparation and -publication. No qualifying PR should become an invented commit or author link. - -Ordinary work preserves inherited fragments and published history. Do not add a -new `Unreleased` section. Editorial replacement, history maintenance and release -consolidation require their own task scope. - -## Verify the lifecycle - -For adoption, open a small pilot PR and inspect the exact head's required status, -sticky comment and independent application checks. Exercise a missing or -malformed note and any enabled bot route. Inspect the generated version PR: -planned version/impact, exact notes, central-history changes and only the accepted -fragment deletions. Review again after its head changes. The workflow does not -merge its own version PR. - -For the selected release, verify how committed history and ancestral tags define -the version baseline. The current lifecycle advances from the greatest stable -version in either source: tag `v1.7.0`, committed history through `1.7.1` and a -new patch produce `1.7.2`. Skipping publication does not block the next PR or -authorize retroactive publication of `1.7.1`. Preserve earlier history and review -the proposed next version; do not create missing tags as an incidental repair. - -Load only the reference needed for the task: - -- [Automation](references/automation.md): selected caller, optional settings, - credentials, maintenance lines and pilot verification. -- [CLI maintenance](references/cli.md): previews, consolidation, history, - interrupted transactions and separately authorized publication. -- [PHP integration](references/php-api.md): release-specific application - services and the bundled example, only when programmatic integration is needed. - -Retain authority already given, but do not infer commit, push, merge, installation -elsewhere or publication authority from an ordinary fragment task. Report changed -paths, executed checks and the verified version/PR/SHA relevant to the result. diff --git a/.agents/skills/fast-forward-changelog/examples/contribution.php b/.agents/skills/fast-forward-changelog/examples/contribution.php deleted file mode 100644 index 1fdd8de..0000000 --- a/.agents/skills/fast-forward-changelog/examples/contribution.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @license https://opensource.org/licenses/MIT MIT License - */ - -use FastForward\Changelog\Container\ServiceProvider\ChangelogServiceProvider; -use FastForward\Changelog\Fragment\FragmentWriterInterface; -use FastForward\Changelog\Release\Factory\ReleaseOptionsFactoryInterface; -use FastForward\Changelog\Validation\CheckServiceInterface; - -use function FastForward\Container\container; - -$autoload = $argv[1] ?? ''; -$directory = realpath($argv[2] ?? ''); -if ('' === $autoload || !is_file($autoload) || !isset($argv[2]) || false === $directory || !is_dir($directory)) { - fwrite(STDERR, "Usage: php contribution.php /consumer/vendor/autoload.php /existing/project\n"); - exit(2); -} -require $autoload; - -$container = container(ChangelogServiceProvider::class); -$options = $container->get(ReleaseOptionsFactoryInterface::class)->create([ - 'workingDirectory' => $directory, - 'source' => 'tags', -]); -$path = $container->get(FragmentWriterInterface::class)->add( - $options, - 'Preserves meaningful Markdown spaces when parsing fragments.', - category: 'fixed', - name: 'php-api-example.md', -); -$expected = "---\ncategory: fixed\ntype: patch\n---\n\nPreserves meaningful Markdown spaces when parsing fragments.\n"; -if ($expected !== file_get_contents($path)) { - throw new RuntimeException('The fragment does not match the expected application output.'); -} -if (!$container->get(CheckServiceInterface::class)->check($options)->isValid()) { - throw new RuntimeException('The pending fragment inventory is invalid.'); -} -fwrite(STDOUT, "Contribution example PASS\n"); diff --git a/.agents/skills/fast-forward-changelog/references/automation.md b/.agents/skills/fast-forward-changelog/references/automation.md deleted file mode 100644 index 46fe275..0000000 --- a/.agents/skills/fast-forward-changelog/references/automation.md +++ /dev/null @@ -1,89 +0,0 @@ -# GitHub lifecycle adoption - -Load when installing or changing workflows, configuring credentials or runners, -selecting maintenance lines, or diagnosing feedback. Discover the latest stable -published release for new adoption, respecting an explicitly selected release -line. For ordinary work, retain the application's reviewed implementation. - -## Use the selected release's caller - -From the verified full tag, read `README.md`, -`resources/workflows/changelog.yml`, its companion README, and the reusable -workflow referenced by that caller. Consult that tag's relevant guides, including -`docs/reusable-lifecycle.md`, `docs/github-app.md` and `docs/automation-map.md` when -present. If paths moved, follow that release's README rather than guessing. -Do not combine a caller from one version with settings copied from `main`. - -If that release lists `install`, inspect its command help and installation guide -before choosing a route. Guided setup can ask for the release branch, publication -choice, advanced overrides and optional project skill, then preview a missing -caller. It must preserve an existing caller and refuse ambiguous or competing -automation. Use read-only preview first; noninteractive application requires its -documented confirmation option. For a new caller, select the published release -through that command's supported release option; its installer can pin `uses` -to the verified commit and retain the version as a readable comment. Confirm -both identities in the preview. Preserve the selected pin of an existing caller. -The workflow and bundled skill may have separate -provenance: a workflow ref does not change the executing CLI's instructions. - -For manual setup, copy the caller into the application's `.github/workflows/`, review its events, -inputs and effective permissions, then set its product references to the selected -published complete tag or verified immutable release commit. Review older pins -embedded in the copied caller. After replacing a pin, inspect the reusable -workflow at the final selected ref and verify its actual inputs, permissions and -runner requirements before saving the application caller. -GitHub `uses` references the executable reusable -workflow under `.github/workflows`; the resource caller is a copyable asset. -Internal `repository-*` workflows belong to the library, not the consumer. - -Explain the selected reusable's publication default before installing its caller. -The lifecycle defaults to `publish: true`; verify this at the final selected ref. -The automatic route publishes the exact version tag and GitHub Release after a -reviewed managed version PR is merged. The workflow does not merge the PR. -Setup itself does not publish anything. -Choose `publish: false` explicitly when the task is a validation-only trial; -do not silently carry that override into an installation meant to publish. -Choose base and managed branches, -fragment/history paths, historical sources and PR-reference policy consistently -across enabled operations. For parallel maintenance, select a separate managed -branch per release line and verify its actual planned version; a branch's name -does not enforce a SemVer range. Use individual workflows or Docker actions only -when their release-specific contracts suit the application's orchestration. - -Full tags identify concrete releases; an immutable commit pin also keeps execution -bound to the reviewed code if an upstream tag is changed. A moving major channel -is an explicit update policy and must be documented by the selected product release; -do not assume it exists. In particular `@v0` may cross breaking `0.x` minors and -does not mean Composer `^0.1`. Changing a workflow ref is a deliberate update. - -## Credentials and acceptance - -Use the selected workflow's documented token/App route and the application's -approved secret storage. Preserve the verified automation identity and narrow -permissions. Never check out untrusted PR code in a privileged custom job. -Token-generated events may behave differently from human/App events; consult -the selected release and GitHub's current rules before promising downstream CI. - -For an explicitly validation-only pilot, use `publish: false`. Verify a valid -fragment, missing or malformed notes, the exact PR head's required status and sticky-comment recovery, -any enabled bot operation, and the generated version PR. Check the actual runner -requirements and access when changing Linux/self-hosted selection. Test custom -policy changes relevant to the application rather than assuming a default-branch -green run proves its generated head. - -The version PR must preserve exact notes and consume only its accepted fragment -set, with no technical plan files or new `Unreleased` section. Head changes need -fresh review and checks. Successful preparation does not authorize merging or -publication. Retain existing publication authority for the verified result, -using the selected release's committed evidence and recovery procedure. - -## Consolidation without publication - -Confirm the selected release's version-baseline rule. The current lifecycle uses -the greatest stable version in committed source history or ancestral stable -tags. With tag `v1.7.0` and committed history through `1.7.1`, a new patch prepares -`1.7.2` while preserving the earlier history. An explicit `publish: false` -creates neither tag nor GitHub Release, but does not block subsequent version -PRs. Enabling publication for a later merge does not publish older consolidated -versions retroactively. Do not remove history or manufacture a missing tag merely -to make another PR possible. diff --git a/.agents/skills/fast-forward-changelog/references/cli.md b/.agents/skills/fast-forward-changelog/references/cli.md deleted file mode 100644 index 55eea75..0000000 --- a/.agents/skills/fast-forward-changelog/references/cli.md +++ /dev/null @@ -1,77 +0,0 @@ -# CLI maintenance - -Load for release previews, history maintenance, recovery or authorized -publication. First select the real release and inspect `list --raw` and -`help ` as described in the skill. Read `docs/cli-fragments.md` and the -relevant maintenance/publication guide from that complete release tag. Verify -that its PHP and Git requirements match the environment. Do not infer arguments -or current behavior from an older installed skill. - -## Execute the selected CLI - -Run from the application's directory. `CHANGELOG_VERSION` is the verified exact -numeric product version, not a range frozen into this skill: - -```sh -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" list --raw -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help status -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" help version -``` - -CPX keeps tool dependencies separate from the application's Composer project; -the command still operates on application files. It is not a filesystem sandbox -or a PHP runtime. CPX's own update/help/version commands concern the executor. -An existing reviewed `vendor/bin/changelog` may run the same supported arguments -without changing the application's dependencies. - -When `list` offers instruction-management operations, inspect their help before -using install, check or update options. Use the requested project/global scope -and preserve local changes. Their existence is a discovered capability, not a -promise that every published changelog version contains them. Runtime updates, -instruction installation and host-session activation remain separate results. - -## Preview before consolidation - -For releases offering these arguments, inspect the read-only plan first: - -```sh -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" status --json --source=tags --no-interaction -cpx --skip-local "fast-forward/changelog:$CHANGELOG_VERSION" version --dry-run --source=tags --no-interaction -``` - -Review the baseline/current/next version, effective impact, accepted fragment -paths, notes and affected files. Choose the relevant maintenance branch and -historical source explicitly. A branch name alone does not establish a release -range. Check command help before treating an exit code as success or failure; -check modes may use a nonzero result for drift as well as errors. - -The normal GitHub lifecycle prepares the version PR. Applying a local version -transaction requires existing consolidation authority and the same reviewed -options as the preview. Preserve exact committed input bytes, custom-template -trust requirements and any PR-resolution setting required by that release. -Verify only central history and consumed-fragment deletions are changed; no -technical plan file or new `Unreleased` section belongs in the version PR. - -If interrupted, preserve the recovery journal and remaining files. Follow that -release's recovery procedure with the same inputs. Do not edit a journal, delete -newer notes or replace history merely to force a retry. - -## Additional maintenance and publication - -Backfill, format, notes extraction and custom templates are optional operations. -Discover their actual commands and read that release's guide before using them. -Keep published descriptions, unknown dates, existing references and pending -fragments intact as required by the operation. Executable PHP templates require -explicit trust. Preview mutations and review the resulting diff. - -Publication requires separate authority for an exact approved full commit SHA. -Read that release's publication guide and command help, preview when supported, -and supply the verified target explicitly. Use the application's approved -credential mechanism. Verify the approved version, notes, consumed fragments, -tag and source commit; PR text or a moving branch is not transaction evidence. -Preparation and publication must use the same policies that affect the output. - -Do not move conflicting concrete tags or overwrite divergent published notes. -After an uncertain response, inspect remote evidence and follow the selected -release's idempotent recovery route under the existing authority. Report what -was actually published or recovered separately from successful validation. diff --git a/.agents/skills/fast-forward-changelog/references/php-api.md b/.agents/skills/fast-forward-changelog/references/php-api.md deleted file mode 100644 index 2dc88e4..0000000 --- a/.agents/skills/fast-forward-changelog/references/php-api.md +++ /dev/null @@ -1,40 +0,0 @@ -# Optional PHP integration - -Load only when the application needs injected services instead of the CLI or -GitHub lifecycle. CPX executes a separate tool; it does not provide an application -autoloader. Inspect the application's Composer installation with -`composer show fast-forward/changelog`, then read the PHP integration/API guide, -manifest requirements and migration notes from that exact release tag. - -Use the installed namespaces and method signatures. Keep the application's -existing command loader, container precedence and secret mechanism. Expose only -the needed domain services and inject external boundaries in application tests. -Resolving a service or writing a fragment does not authorize commits or releases. - -## Bundled contribution example - -The complete [contribution program](../examples/contribution.php) illustrates the -`0.1.0` PHP API: explicit consumer autoloader and target directory, provider -composition, fragment creation and validation. It is an optional example, not -the contract for every later release. Before using it with another version, -compare its imports/signatures with that release's documented API or use the -example shipped with the selected release. - -For a matching API, run it first in a disposable target: - -```sh -php .agents/skills/fast-forward-changelog/examples/contribution.php ./vendor/autoload.php /absolute/project -vendor/bin/changelog check --no-interaction -``` - -Success prints `Contribution example PASS`; exactly one -`.changelog/php-api-example.md` is created, with no commit or central-history -change. A repeated run must expose the filename collision rather than overwrite -the file. Missing inputs and runtime failures remain nonzero. Do not report -success after a failed write or ignore the validation report. - -Keep PR/issue/author fields absent unless verified. Service access follows the -same fragment, version-transaction and publication boundaries as the selected -release's CLI. Learn optional configuration, planner/history services and -approved-commit publication from that version's documentation when the task -requires them; do not load an API inventory for an ordinary fragment task. diff --git a/.changelog/composer-managed-changelog-skill.md b/.changelog/composer-managed-changelog-skill.md new file mode 100644 index 0000000..53fe1f5 --- /dev/null +++ b/.changelog/composer-managed-changelog-skill.md @@ -0,0 +1,6 @@ +--- +category: changed +type: patch +--- + +Restore the Changelog contributor skill through the development-only Composer skill manager and its reviewed GitHub source instead of versioning generated skill copies. diff --git a/.gitattributes b/.gitattributes index 8cf3182..d787e0d 100755 --- a/.gitattributes +++ b/.gitattributes @@ -17,3 +17,4 @@ /.changelog/ export-ignore /CONTRIBUTING.md export-ignore /composer-dependency-analyser.php export-ignore +/skills.json export-ignore diff --git a/.gitignore b/.gitignore index e2856dd..774e249 100755 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ tmp/ vendor/ composer.lock *.cache +/.agents/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cf932de..75f0bef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,10 +13,14 @@ cpx --skip-local fast-forward/changelog check --since=origin/main --no-interacti Select the category and semantic impact that describe the change. Keep published history intact; pending notes belong in fragments rather than an `Unreleased` -section. The project skill is installed at -[`.agents/skills/fast-forward-changelog/SKILL.md`](.agents/skills/fast-forward-changelog/SKILL.md). -Check its local integrity with -`cpx --skip-local fast-forward/changelog skill:install --check --json`. +section. + +Run `composer install` to restore the project skill into +`.agents/skills/fast-forward-changelog` through the development-only `llm/skills` +plugin and the reviewed GitHub source in `skills.json`. Generated skill files +are ignored by Git. Use `composer skills:show` to inspect the source and +`composer skills:update --from=github` for an explicit refresh within its +configured version range. Review `skills.json` before changing that range. The [workflow](.github/workflows/changelog.yml) validates PR notes, maintains PR feedback and prepares one version PR on `changelog/version`. diff --git a/composer.json b/composer.json index 3e5a8ad..40b60e1 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "middlewares/utils": "^4.0" }, "require-dev": { - "fast-forward/dev-tools": "dev-main" + "fast-forward/dev-tools": "dev-main", + "llm/skills": "^1.15" }, "minimum-stability": "stable", "autoload": { @@ -41,7 +42,8 @@ "fast-forward/dev-tools": true, "phpdocumentor/shim": true, "phpro/grumphp": true, - "pyrech/composer-changelogs": true + "pyrech/composer-changelogs": true, + "llm/skills": true }, "platform": { "php": "8.3.0" diff --git a/skills.json b/skills.json new file mode 100644 index 0000000..386ea94 --- /dev/null +++ b/skills.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://raw.githubusercontent.com/roxblnfk/skills/master/resources/skills.schema.json", + "target": ".agents/skills", + "aliases": [], + "discovery": false, + "auto-sync": true, + "vendor-sources": false, + "dependencies": { + "composer": false + }, + "sources": [ + { + "from": "github", + "package": "php-fast-forward/changelog", + "ref": "^0.3.0", + "skills": [ + "fast-forward-changelog" + ] + } + ] +} From b1c246ccaecad2a8b994fe59bb2940a0a55af940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 13:53:14 -0300 Subject: [PATCH 5/8] chore: restore Container consumer skill through Composer --- .changelog/container-consumer-skill.md | 6 ++++++ CONTRIBUTING.md | 10 ++++++++++ skills.json | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 .changelog/container-consumer-skill.md diff --git a/.changelog/container-consumer-skill.md b/.changelog/container-consumer-skill.md new file mode 100644 index 0000000..04fe24d --- /dev/null +++ b/.changelog/container-consumer-skill.md @@ -0,0 +1,6 @@ +--- +category: added +type: patch +--- + +Restores the Fast Forward Container consumer skill through the existing development-only Composer skill manager, alongside the configured contributor skills, without changing runtime dependencies. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 75f0bef..c8cbe75 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,3 +32,13 @@ creates its version tag and GitHub Release. The workflow never merges PRs. GitHub Releases. The workflow preserves that evidence with `source: github`. Empty release bodies still need editorial review; no PR attribution is inferred from prose alone. + +## Container consumer skill + +The same development-only manager also restores `fast-forward-container` from +`php-fast-forward/container` within `^1.10.0`, alongside the other configured +skills. Inspect all sources with `composer skills:show` and refresh them with +`composer skills:update --from=github`. Generated copies stay ignored; this +configuration does not upgrade the runtime library. Check the installed +Container version before following the skill: its API contract supports `^1.10` +and requires reporting earlier versions instead of assuming compatibility. diff --git a/skills.json b/skills.json index 386ea94..1cdce21 100644 --- a/skills.json +++ b/skills.json @@ -16,6 +16,14 @@ "skills": [ "fast-forward-changelog" ] + }, + { + "from": "github", + "package": "php-fast-forward/container", + "ref": "^1.10.0", + "skills": [ + "fast-forward-container" + ] } ] } From 5ff47ad080d6b4a11da7ec2dfe511ab31342b3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 15:47:31 -0300 Subject: [PATCH 6/8] chore: synchronize skills from installed Composer dependencies --- .changelog/composer-dependency-skills.md | 6 ++++++ skills.json | 16 +++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 .changelog/composer-dependency-skills.md diff --git a/.changelog/composer-dependency-skills.md b/.changelog/composer-dependency-skills.md new file mode 100644 index 0000000..5e53781 --- /dev/null +++ b/.changelog/composer-dependency-skills.md @@ -0,0 +1,6 @@ +--- +category: changed +type: patch +--- + +Synchronize the Config and Container consumer skills from the installed Composer dependencies through an explicit trusted-package list instead of independent GitHub sources. diff --git a/skills.json b/skills.json index 1cdce21..87f8ea0 100644 --- a/skills.json +++ b/skills.json @@ -6,7 +6,13 @@ "auto-sync": true, "vendor-sources": false, "dependencies": { - "composer": false + "composer": { + "trusted": [ + "fast-forward/config", + "fast-forward/container" + ], + "trusted-replace": true + } }, "sources": [ { @@ -16,14 +22,6 @@ "skills": [ "fast-forward-changelog" ] - }, - { - "from": "github", - "package": "php-fast-forward/container", - "ref": "^1.10.0", - "skills": [ - "fast-forward-container" - ] } ] } From cf914e1befee142840ef9a3dd2953da8e1667d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 15:49:26 -0300 Subject: [PATCH 7/8] docs: describe installed Composer skill donors --- CONTRIBUTING.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8cbe75..306146a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,12 +33,17 @@ GitHub Releases. The workflow preserves that evidence with `source: github`. Empty release bodies still need editorial review; no PR attribution is inferred from prose alone. -## Container consumer skill - -The same development-only manager also restores `fast-forward-container` from -`php-fast-forward/container` within `^1.10.0`, alongside the other configured -skills. Inspect all sources with `composer skills:show` and refresh them with -`composer skills:update --from=github`. Generated copies stay ignored; this -configuration does not upgrade the runtime library. Check the installed -Container version before following the skill: its API contract supports `^1.10` -and requires reporting earlier versions instead of assuming compatibility. +## Composer dependency skills + +The development-only manager restores `fast-forward-container` and +`fast-forward-config` from the installed Composer packages, including Config as +a transitive dependency. `skills.json` explicitly trusts only those two Composer +donors; dependency trust does not extend to other installed packages. No separate +GitHub source or version pin is used for either library. + +Inspect donors with `composer skills:show` and refresh their payloads with +`composer skills:update --from=composer`. The existing GitHub source continues +to manage the Changelog contributor skill independently. Generated copies remain +ignored. Synchronization does not upgrade runtime dependencies; an installed +version without a bundled skill contributes no skill. Check installed versions +and the bundled skill's supported contract before using its instructions. From 04ff41c60c2c94b6a41628de2c605d58a43252fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 20 Oct 2026 15:57:41 -0300 Subject: [PATCH 8/8] chore(deps): require fast-forward/container ^1.10 --- .changelog/container-1-10.md | 6 ++++++ composer.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changelog/container-1-10.md diff --git a/.changelog/container-1-10.md b/.changelog/container-1-10.md new file mode 100644 index 0000000..d51616f --- /dev/null +++ b/.changelog/container-1-10.md @@ -0,0 +1,6 @@ +--- +category: changed +type: patch +--- + +Require fast-forward/container ^1.10 so installed Composer dependencies supply the supported Container consumer skill alongside the runtime library. diff --git a/composer.json b/composer.json index 40b60e1..f200973 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ }, "require": { "php": "^8.3", - "fast-forward/container": "^1.5", + "fast-forward/container": "^1.10", "fast-forward/http-client": "^1.0", "fast-forward/http-factory": "^1.1", "middlewares/utils": "^4.0"