From 4e43857354d27fb2d701af4c2fc0dc3255d7324f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Tue, 27 Oct 2026 14:45:32 -0300 Subject: [PATCH] feat: publish a portable PHPDoc authoring skill --- .changelog/phpdoc-authoring-skill.md | 6 ++ AGENTS.md | 4 +- README.md | 10 ++- docs/instruction-map.rst | 2 +- .../fast-forward-code-standards/SKILL.md | 6 +- resources/skills/fast-forward-phpdoc/LICENSE | 21 +++++ resources/skills/fast-forward-phpdoc/NOTICE | 23 +++++ resources/skills/fast-forward-phpdoc/SKILL.md | 88 +++++++++++++++++++ .../fast-forward-phpdoc/references/cleanup.md | 48 ++++++++++ .../references/contracts.md | 48 ++++++++++ .../references/verification.md | 29 ++++++ tests/Distribution/ArchiveTest.php | 17 +++- 12 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 .changelog/phpdoc-authoring-skill.md create mode 100644 resources/skills/fast-forward-phpdoc/LICENSE create mode 100644 resources/skills/fast-forward-phpdoc/NOTICE create mode 100644 resources/skills/fast-forward-phpdoc/SKILL.md create mode 100644 resources/skills/fast-forward-phpdoc/references/cleanup.md create mode 100644 resources/skills/fast-forward-phpdoc/references/contracts.md create mode 100644 resources/skills/fast-forward-phpdoc/references/verification.md diff --git a/.changelog/phpdoc-authoring-skill.md b/.changelog/phpdoc-authoring-skill.md new file mode 100644 index 0000000..19bf631 --- /dev/null +++ b/.changelog/phpdoc-authoring-skill.md @@ -0,0 +1,6 @@ +--- +category: added +type: minor +--- + +Ship a dedicated portable PHPDoc authoring skill with concise interface-contract guidance, semantic-preservation checks and independent distribution references. diff --git a/AGENTS.md b/AGENTS.md index 4ddbf23..199f035 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,8 @@ type-analysis or Rector migration parity with DevTools. ## Ownership `src/` owns reusable behavior; the CLI and Actions orchestrate the same services. -The sole distributable skill is under `resources/skills/fast-forward-code-standards`. +Canonical distributable skills live under `resources/skills`: `fast-forward-code-standards` +owns tool consumption; `fast-forward-phpdoc` owns source-documentation authoring. Consumer examples live under `resources`, executable Actions under `.github/actions`, reusables under `.github/workflows/code-standards*.yml`, own event workflows use `repository-`. Ordinary folders share this root contract. @@ -83,3 +84,4 @@ for the exact local base/head before publication; do not claim remote CI evidenc - [Released channel helper](.github/update-release-channels.md): repository-only publication verification, CAS update and permission-failure recovery; never creates releases or changes repository settings. - [Instruction map](docs/instruction-map.rst): single root scope and skill ownership. - [Consumer skill](resources/skills/fast-forward-code-standards/SKILL.md): portable consumption procedure; no automatic installation or rollout. +- [PHPDoc skill](resources/skills/fast-forward-phpdoc/SKILL.md): concise source documentation and implementation-independent semantic contracts; no global installation required. diff --git a/README.md b/README.md index 5a4d393..f9dbc27 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,19 @@ Workflow guards and their contributor tests additionally require Bash and jq. Hosted Ubuntu runners provide both; the Composer library and CLI use the PHP dependencies declared in this package. -Composer exposes the portable skill through `extra.skills.source` at +Composer exposes the portable skills through `extra.skills.source` at `resources/skills`. `llm/skills` is an optional consumer integration; installation and activation are explicit. The development `check` script validates Composer metadata and the actual platform before running this package's tests and style check. +Use the [Code Standards skill](resources/skills/fast-forward-code-standards/SKILL.md) +for tool adoption and explicit formatting. Use the dedicated +[PHPDoc skill](resources/skills/fast-forward-phpdoc/SKILL.md) to write or review +concise summaries, semantic contracts, useful tags and inherited documentation. +Each payload includes its license and relative references; neither activates an +agent or installs another tool automatically. + For a reviewed source checkout: ```sh @@ -175,6 +182,7 @@ bin/code-standards CLI entrypoint config/ecs.php default native ECS configuration src/Config/ECSConfig.php reusable preset API resources/skills/fast-forward-code-standards/ canonical consumer skill +resources/skills/fast-forward-phpdoc/ portable PHPDoc authoring skill resources/workflows/code-standards.yml consumer workflow wrapper .github/actions/check/ small check adapter docs/ architecture, policy and integration guides diff --git a/docs/instruction-map.rst b/docs/instruction-map.rst index 3632565..7497745 100644 --- a/docs/instruction-map.rst +++ b/docs/instruction-map.rst @@ -3,7 +3,7 @@ Instruction map The initial directory was empty and had no repository contracts. The shared host bootstrap and Harness were read before implementation. This repository uses one root ``AGENTS.md``, following Changelog's single-root model: ordinary source, tests, docs, Actions and workflow folders have no different maintenance authority. -``resources/skills/fast-forward-code-standards/SKILL.md`` owns only the portable consumer procedure. It is not copied to ``.agents/skills`` and needs no host alias. Read root instructions, then only the linked domain guide or skill needed by the task. The root Child DOX Index provides the reading route. +``resources/skills/fast-forward-code-standards/SKILL.md`` owns the portable tool-consumption procedure; ``resources/skills/fast-forward-phpdoc/SKILL.md`` owns source PHPDoc authoring and review. These canonical payloads need no installed copy or host alias. Consumer installation and activation remain explicit. Read root instructions, then only the linked domain guide or skill needed by the task. The root Child DOX Index provides the reading route. The opt-in refactoring guide remains under this same root authority. It records the native Rector invocation and executable-config boundary; it introduces no new instruction subtree, automatic semantic profile or consumer installer. diff --git a/resources/skills/fast-forward-code-standards/SKILL.md b/resources/skills/fast-forward-code-standards/SKILL.md index 4d23d7e..f5d0e8d 100644 --- a/resources/skills/fast-forward-code-standards/SKILL.md +++ b/resources/skills/fast-forward-code-standards/SKILL.md @@ -100,7 +100,11 @@ the consumer's PHP platform or dependency constraints implicitly. Review native numeric/function/context exceptions explicitly. They are broad policy overrides, not per-finding baselines; do not auto-accept existing debt. -This directory is the sole source payload. Installation/host activation is explicit; +For authoring or reviewing semantic PHPDoc rather than executing a formatter, +select the separately distributed `fast-forward-phpdoc` skill. Ordinary check/fix +does not require that payload and cannot prove that a documented promise is true. + +This directory is the canonical payload for this skill. Installation/host activation is explicit; copying this skill does not install the runtime or authorize consumer rollout. LLM Skills owns discovery/install/update; follow the selected ref's distribution contract rather than adding another copy/symlink installer in this tool. diff --git a/resources/skills/fast-forward-phpdoc/LICENSE b/resources/skills/fast-forward-phpdoc/LICENSE new file mode 100644 index 0000000..f320900 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/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/resources/skills/fast-forward-phpdoc/NOTICE b/resources/skills/fast-forward-phpdoc/NOTICE new file mode 100644 index 0000000..6aaccd8 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/NOTICE @@ -0,0 +1,23 @@ +This skill adapts PHPDoc authoring guidance from php-fast-forward/dev-tools, +.agents/skills/phpdoc-code-style, at 84e154046e07cafa6ac09a9e12434b1ff5dcb5e0. +The original MIT notice is retained below. + +Copyright (c) 2026 Felipe Sayão 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/resources/skills/fast-forward-phpdoc/SKILL.md b/resources/skills/fast-forward-phpdoc/SKILL.md new file mode 100644 index 0000000..0c1bdf9 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/SKILL.md @@ -0,0 +1,88 @@ +--- +name: fast-forward-phpdoc +description: Write, review or clean PHPDoc in Fast Forward PHP projects, especially concise summaries, abstract interface contracts, descriptive tags and inherited documentation, while preserving behavior and public APIs. +license: MIT +compatibility: Documentation authoring requires source, contracts and tests from the target project. Optional Code Standards check/fix examples use the verified 0.3.2 baseline, PHP ^8.3 and Composer runtime API ^2.2; inspect the installed CLI before use. +metadata: + api-baseline: PHPDoc authoring; optional Code Standards check/fix 0.3.2 + repository: https://github.com/php-fast-forward/code-standards +--- + +# Fast Forward PHPDoc + +Use this skill to improve source documentation without changing execution, public +names, namespaces, member order, native types or compatibility. It works from this +payload alone and does not require DevTools, an installed global skill or a renderer. + +## Ordinary authoring route + +1. Read the target project's instructions, Git diff, relevant symbols, parent + contracts, callers and tests. Establish intended behavior separately from the + behavior observed in one implementation. Report contradictions or unknowns. +2. Write a short, objective, single-sentence summary of the element's purpose. + Add only useful semantics beyond it, in prose or the appropriate tag, once. +3. For an interface, describe observable obligations of **any** conforming + implementer. Keep concrete class names, incidental algorithms and mechanisms + on implementations. Apply the [contract checklist](references/contracts.md) + before introducing requirements or tool-specific types. +4. Preserve descriptions, units, sentinels, richer types, consumed annotations + and inheritance markers. Read [cleanup and examples](references/cleanup.md) + before deleting a tag or changing inherited documentation. Keep documentation + in the project's language; Fast Forward source documentation uses English. +5. Review the diff against the original meaning and another plausible conforming + implementation. Run the project's relevant checks and inspect rendered + semantics when rendering or inheritance changes. Report checks not available. + +For example, retain the semantic contribution even though the signature is typed: + +```php +/** + * Reads the configured lifetime. + * + * @return int Lifetime in seconds; zero disables expiry. + */ +public function lifetime(): int; +``` + +Removing the tag above would lose the unit and sentinel. Do not infer those facts +from a method name when the target API has no established contract. + +## Formatting and verification + +Preserve the project's existing header and legal notices. Do not invent ownership, +dates, license text, imports, suffixes or a universal header requirement. Formatting +follows the selected project configuration, not the old DevTools preset. + +When Code Standards is already installed, inspect its version and help, then run: + +```sh +composer show fast-forward/code-standards +vendor/bin/code-standards help check +vendor/bin/code-standards check --all +git diff --check +git diff +``` + +The optional check/fix route has a verified 0.3.2 baseline. Preserve an existing +consumer constraint; do not upgrade it just to follow this procedure. If absent, +installation requires an explicit request: `composer require --dev fast-forward/code-standards`. +Check does not change source. Fix requires an explicit request; inspect its diff +and rerun check. A clean formatter cannot establish that a contract is true, prove +RFC wording is appropriate or guarantee preservation under arbitrary overrides. + +Semantic refactoring is a separate opt-in task. Inspect the installed command and +native Rector rules before using it; never run it as implicit PHPDoc cleanup. +Executable configuration and consumer bootstraps are not sandboxed by dry-run. + +Use the [verification checklist](references/verification.md) for changed contracts, +failures and a bounded review report. Return actual evidence and open questions; +do not publish speculative guarantees merely to make documentation look complete. + +## Distribution + +This directory is the canonical `fast-forward-phpdoc` payload, including its +license and relative references. Composer advertises `resources/skills` through +`extra.skills.source`. A consumer may explicitly select LLM Skills for discovery +and installation; shipping this payload does not activate it, install a runtime, +grant plugin approval or authorize a consumer rollout. It has no global-skill +dependency and provides no installer or synchronization command. diff --git a/resources/skills/fast-forward-phpdoc/references/cleanup.md b/resources/skills/fast-forward-phpdoc/references/cleanup.md new file mode 100644 index 0000000..cf1dcc6 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/references/cleanup.md @@ -0,0 +1,48 @@ +# Cleanup and preservation + +Preserve useful local wording, attributes, imports, member order and legal headers. +Do not add a fixed DevTools namespace, header, author or year to consumer files. +Keep tag layout consistent with the consumer's active formatter configuration. + +These tags retain information beyond native types: + +```php +/** @return int Lifetime in seconds; zero disables expiry. */ +/** @param list $names Names in the caller's requested order. */ +/** @throws InvalidArgumentException When the supplied name is empty. */ +``` + +The examples are independent annotation snippets, not promises about an existing +API. When moving prose, preserve the full meaning and verify rendered output. +Do not always add or always remove `@return void`: a description can be useful. +Preserve array shapes, generics, tool annotations and intentional package/author +tags. Do not silently delete a described unused/virtual parameter or a described +`@final`/`@abstract` tag just because a fixer calls it redundant. + +For interfaces, remove redundant formal filler rather than replacing it with a +longer paragraph. For example, “Reads the configured lifetime.” states a purpose; +“This method MUST read the configured lifetime” repeats it without new semantics. +Do not fabricate deterministic output or failure guarantees from a classifier's +name. Do not repeat a package-wide RFC or license declaration on every method. + +## Inheritance + +Preserve `{@inheritDoc}` and inherited descriptions until the actual renderer, +analyzer and IDE behavior is qualified. A child summary or description can shadow +parent content. The [phpDocumentor inheritance guide](https://docs.phpdoc.org/guide/guides/inheritance.html) +describes inline inheritance, but a successful build alone does not prove that a +specific renderer/template retained the parent's obligations and exception text. + +Inspect the rendered child summary, description, parameters, return and failures +when changing inheritance. A source-preservation fixture proves only source +preservation. Do not promise universal IDE equivalence or mechanically replace a +standalone inheritance marker without checking the target toolchain. + +## Automated cleanup + +Inspect the effective rules, not just preset labels or skip entries. A removed +skip does not necessarily enable its fixer. Some PHPDoc cleanup rules remove +described return tags or inheritance; retain a skip when supported configuration +cannot preserve the required meaning. Do not enable a whole risky or docblock set +as an innocent formatting change. Validate golden output and a second pass under +the actual installed version, including local overrides. diff --git a/resources/skills/fast-forward-phpdoc/references/contracts.md b/resources/skills/fast-forward-phpdoc/references/contracts.md new file mode 100644 index 0000000..b9b2745 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/references/contracts.md @@ -0,0 +1,48 @@ +# Evidence and interface contracts + +Start from existing specifications, credible contracts and explicit requirements. +Use implementations, call sites and tests to check conformance, not to promote an +implementation accident into a requirement. Types constrain values; names alone +do not prove streaming, idempotence, atomicity, retries or absence of mutation. +Report conflicts instead of silently weakening an established promise. + +For each method, select only relevant and evidenced input meaning, outcomes, +preconditions, effects, failures and invariants. State caller versus implementer +responsibilities where the distinction matters. A replacement implementer must +not require stronger inputs or weaken promised results. Specific storage, +frameworks and algorithms belong on concrete implementations unless the public +specification explicitly requires them. + +Keep the summary one short purpose sentence. Place necessary conditions in prose +or tags without repeating them in both. Do not fill a category checklist with +guesses or force normative words into straightforward methods. + +## Requirement language + +Adopt BCP 14 once at an appropriate shared package or contract scope: + +> Uppercase requirement terms use BCP 14 (RFC 2119 and RFC 8174); lowercase words retain ordinary meaning. + +MUST and MUST NOT are requirements and prohibitions. SHOULD and SHOULD NOT allow +exceptions only after weighing their consequences. MAY grants a genuine choice; +it does not express uncertainty. Use these terms sparingly for material contract +constraints. Their use and the concise-summary convention here are project +choices, not requirements imposed on PHPDoc by the RFCs. + +## Supported types and tags + +Keep native types in signatures. Add `@param`, `@return` or `@throws` when they +carry descriptions, refined supported types or necessary metadata. Preserve +necessary analyzer-only annotations. Do not invent types or portable pre/post +tags. Verify shapes, generics and `@phpstan-*`/`@psalm-*` against actual versions. +For a positive finite timeout, use `@param float $timeout Positive, finite execution limit in seconds.`; +do not assume `positive-float` is a supported alias. + +Official references: [RFC 2119 §6](https://www.rfc-editor.org/rfc/rfc2119#section-6), +[RFC 8174 §2](https://www.rfc-editor.org/rfc/rfc8174#section-2), +[phpDocumentor DocBlocks](https://docs.phpdoc.org/guide/guides/docblocks.html), +[PHPStan types](https://phpstan.org/writing-php-code/phpdoc-types). +The [PSR-11 specification](https://www.php-fig.org/psr/psr-11/) and +[ContainerInterface 2.0.2](https://github.com/php-fig/container/blob/2.0.2/src/ContainerInterface.php) +illustrate implementation-independent semantics. Their conventions do not justify +copying unrelated obligations or boilerplate into another interface. diff --git a/resources/skills/fast-forward-phpdoc/references/verification.md b/resources/skills/fast-forward-phpdoc/references/verification.md new file mode 100644 index 0000000..5299763 --- /dev/null +++ b/resources/skills/fast-forward-phpdoc/references/verification.md @@ -0,0 +1,29 @@ +# Verification and reporting + +Before accepting an edit: + +- Compare the documented promises with the specification, implementations, + callers and tests. Distinguish intended requirements from observed behavior. +- Substitute a plausible different implementer: interface prose must still hold + without naming a concrete class, framework or incidental mechanism. +- Check short summaries, useful non-repeated descriptions, valid refinements and + exception conditions. Report unsupported guarantees or ambiguous contracts. +- Review described parameters and returns, richer types, intentional annotations + and standalone/inline inheritance markers after the real formatter dry-run. +- When changing cleanup policy, test preservation cases, violations, explicit fix + and second-pass idempotence; check must leave source unchanged. +- Inspect the actual generated text when rendering or inheritance is affected. + Exit zero and PHP syntax validation alone do not establish semantic retention. +- Run affected behavioral tests when a contract reveals a real implementation + defect; keep runtime fixes separate from a documentation-only change. + +Use the existing project's commands and PHP support floor. Do not invoke the +legacy `dev-tools phpdoc` command merely because this procedure originated there. +Do not execute untrusted executable configuration with secrets or a write token. + +A bounded report identifies changed files and intended semantics, source/tool +versions, commands actually run, their results, and unresolved contracts or +rendering limitations. Manual review, source fixtures, format validation, rendered +output and model task performance are distinct observations. Do not claim that +loading this skill guarantees compliant agent output or that ECS/Rector proves +the truth of normative contracts. diff --git a/tests/Distribution/ArchiveTest.php b/tests/Distribution/ArchiveTest.php index 81e4951..093bd90 100644 --- a/tests/Distribution/ArchiveTest.php +++ b/tests/Distribution/ArchiveTest.php @@ -22,7 +22,13 @@ protected function setUp(): void $root = dirname(__DIR__, 2); $paths = explode("\0", $this->execute(['git', 'ls-files', '-z'], $root)); $paths[] = '.gitattributes'; - $paths[] = 'resources/skills/fast-forward-code-standards/LICENSE'; + $skillFiles = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($root . '/resources/skills', \FilesystemIterator::SKIP_DOTS)); + foreach ($skillFiles as $file) { + self::assertFalse($file->isLink(), 'Canonical skills must be regular, portable files.'); + if ($file->isFile()) { + $paths[] = substr($file->getPathname(), strlen($root) + 1); + } + } foreach (array_unique($paths) as $path) { if ('' === $path || !is_file($root . '/' . $path)) { @@ -59,7 +65,7 @@ protected function tearDown(): void (new Filesystem())->remove($this->directory); } - /** Both routes honor one export-ignore policy while retaining the runtime, canonical skill and README artwork. */ + /** Both routes honor one export-ignore policy while retaining runtime, complete skill payloads and README artwork. */ public function testGitAndComposerExportTheSamePackageFiles(): void { mkdir($this->directory . '/.build/archives', recursive: true); @@ -76,6 +82,13 @@ public function testGitAndComposerExportTheSamePackageFiles(): void } self::assertSame(hash_file('sha256', dirname(__DIR__, 2) . '/LICENSE'), $git['resources/skills/fast-forward-code-standards/LICENSE']); self::assertSame(hash_file('sha256', dirname(__DIR__, 2) . '/resources/skills/fast-forward-code-standards/SKILL.md'), $git['resources/skills/fast-forward-code-standards/SKILL.md']); + $root = dirname(__DIR__, 2); + foreach (['SKILL.md', 'LICENSE', 'NOTICE', 'references/contracts.md', 'references/cleanup.md', 'references/verification.md'] as $name) { + $path = 'resources/skills/fast-forward-phpdoc/' . $name; + self::assertArrayHasKey($path, $git); + self::assertSame(hash_file('sha256', $root . '/' . $path), $git[$path]); + } + self::assertSame(hash_file('sha256', $root . '/LICENSE'), $git['resources/skills/fast-forward-phpdoc/LICENSE']); foreach (array_keys($git) as $path) { self::assertDoesNotMatchRegularExpression('~^(?:vendor|\.agents|\.build|\.phpunit\.cache|tests|\.github/workflows)/~', $path); }