Add living specifications system#835
Open
edwh wants to merge 7 commits into
Open
Conversation
|
Introduces a code-first living documentation system that embeds user stories directly in controller code via PHP 8 attributes (#[Feature], #[UserStory], #[NoStory]), extracts them into a JSON manifest, and builds a browsable VitePress static site with dual navigation by feature and by persona. - 3 PHP attribute classes in app/Attributes/ - specs:extract artisan command using nikic/php-parser AST analysis (already a transitive composer dependency, no new requirement) - JSON manifest at docs/specs/manifest.json, 8 narrative markdown files in docs/specs/narratives/ - Standalone VitePress site in specs-site/ with prebuild page generation (independent package.json, does not touch the app's Vite/npm setup) - GitHub Actions workflow for GitHub Pages deployment - Removes the historical features/ directory (Gherkin-style specs), superseded by the annotation system; untouched since this branch first diverged from develop so nothing current is lost - Adds a Living Specifications section to CLAUDE.md describing the workflow for keeping annotations current Rebuilt from the original feature/living-specs branch (~600 commits behind develop) on top of current develop. The @story annotations on controllers and tests are ported in follow-up commits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous commit's message described this addition but the section was left out of what got staged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the user story attributes from the original feature/living-specs branch onto the current controller code. Annotated via #[Feature] on each controller class and #[UserStory]/#[NoStory] on public action methods, matched by method name against the branch's final annotated state and merged with a 3-way text merge (base = branch's original divergence point, mine = current develop, theirs = branch tip) so that unrelated evolution of these files (return-type hints added since) is preserved alongside the new attributes. 168 user stories across 8 features and 6 personas, grouped into themes within each feature. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports @story:ClassName::method docblock references from the original feature/living-specs branch onto the current test suite, linking test methods to the user stories added in the previous commit. specs:extract picks these up via regex over docblocks so the VitePress site can show per-story test coverage. Merged the same way as the controller annotations: a 3-way text merge per file (branch divergence point / current develop / branch tip), which correctly threads new docblock lines through method signatures that have since gained return-type hints, without disturbing them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
edwh
force-pushed
the
feature/living-specs
branch
from
July 15, 2026 09:09
fc617f1 to
a0299fd
Compare
Collaborator
Author
|
Rebuilt this branch on current develop rather than rebasing — the original was ~600 commits behind and the @story docblock diffs no longer applied after the Vite migration and general drift. What changed:
Needs human follow-up:
|
SonarCloud (rightly) wants write permissions scoped to the deploy job rather than granted workflow-wide. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzY1phBjyT3HogpeS53zon
- generate-pages.mjs: give every string sort an explicit localeCompare comparator (default sort is lexicographic-by-code-unit) - SpecsExtract: coalesce php-parser dynamic-property iterables to [] - the analyzer cannot see them initialized, and a malformed node would genuinely make them so Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzY1phBjyT3HogpeS53zon
Sonar's PHP analyzer cannot see php-parser's vendor property declarations, so it treats every AST property read as uninitialized even behind a null-coalesce. Assign to explicit locals and mark the three reads NOSONAR with justification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzY1phBjyT3HogpeS53zon
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
#[Feature],#[UserStory],#[NoStory])specs:extractartisan command that uses nikic/php-parser AST analysis to extract 168 user stories across 8 feature areas and 6 personas from 29 controllers into a JSON manifest@story:ControllerClass::methoddocblock annotations to test files, linking 165 of 168 stories (98%) to their testsfeatures/directory (100+ Gherkin files) — all relevant content has been folded into the new code-level annotationsLive preview: https://therestartproject.github.io/restarters.net/
What this enables
#[UserStory]attributes are visible inline, prompting updates when behaviour changesphp artisan specs:extract --checkdetects manifest drift, unannotated public methods, and stale narratives@story:references in test filesFeature areas
Events (53 stories), Groups (36), Users (25), Devices (14), Platform (20), Networks (15), Administration (3), Dashboard (2)
Personas
Admin, Host, Restarter, NetworkCoordinator, Guest, ThirdParty
Test plan
php artisan specs:extractgenerates valid manifest.json with 168 stories@story:annotationsnpm run buildin specs-site/ produces working static site