Feature development
Build and audit a framework feature across API, conformance, documentation, audit and quality gates.
Feature development
Signals features usually cross several contracts even when the implementation looks local. The feature-development lane makes those contracts explicit and reports mechanical evidence from the framework's own catalogues and registries.
Start with the normal service-layer conventions, implement focused Pest coverage, then work in this order: code; conformance and committed snapshots; documentation and generated references; audit and temporal coverage; final quality gates. Do not overlap Pest runs on a shared machine.
Audit the current branch
php artisan signals:feature-coverage --since=origin/dev --fail-on=new --report=storage/feature-coverage.md
The report uses four verdicts: COVERED, MISSING, N/A with a reason, and REVIEW. Missing evidence is always MISSING. Interpretive choices remain REVIEW, with a recommendation, so the command does not silently turn product judgement into policy.
Lanes never add waivers. Report MISSING and stop. Waivers are added only by a maintainer by explicit instruction, with owner+expiry+reason.
Retro-audit an existing area
php artisan signals:feature-coverage \
--path=app/Services/RentalProjects \
--route='api.v1.rentals.*' \
--report=storage/rentals-feature-coverage.md
You can also repeat --class, --route, and --area; add --json for automation. --fail-on=new ignores valid time-bounded waivers while --fail-on=any includes them. Changelog evidence may use a route name, a normalised URI template, resource and verb wording, or an explicit <!-- routes: api.v1.x, api.v1.y --> marker. Shared OpenAPI error-response components may carry one reusable example for referenced 401/403/404 responses.
Targeting audits by area
The committed feature-area map groups application files, API routes, webhook events, settings groups, MCP tools, and documentation pages under stable slugs. List the available audit targets and their counts with:
php artisan signals:feature-areas
Inspect one area before starting an audit, then pass the same slug to the coverage gate:
php artisan signals:feature-areas --area=rental-projects
php artisan signals:feature-coverage \
--area=rental-projects \
--report=framework-notes/coverage/area-rental-projects.md
config/feature-areas.php owns the taxonomy seeds. php artisan signals:feature-areas:build expands those seeds across import, call, and reference edges in the read-only CodeGraph index and rewrites resources/architecture/feature-areas.json deterministically. When CodeGraph is unavailable, the command warns and writes a seeds-only artifact with expanded set to false; the freshness architecture test then skips with an explicit reason.
Every application file in the mapped roots must resolve to exactly one area. Genuinely cross-cutting presentation infrastructure is recorded separately in resources/architecture/feature-area-allow-list.json, with a reason for every pattern; feature-specific files must not use that exception list.
What supplies the evidence
The gate reads ApiEndpointCatalogue, RegistryInventory, WebhookEventRegistry, SettingsRegistry, conformance overrides and fixture registration, compatibility snapshots, the DocsService index, language coverage, and changelog files. Its verdict rows name the producing tool or architecture test. Existing conformance, OpenAPI, Postman, audit, mutation-inventory, language, skills, performance and manifest gates remain authoritative.
Generate target-specific handoffs
Generate cross-repository notes only for repositories affected by the final contract diff:
php artisan signals:handoff \
--target=scan-ios \
--pr=123 \
--commit=abc123 \
--coverage-report=storage/feature-coverage.md
With --commit, the command reads and hashes the committed resources/docs/openapi.json via git show; it never substitutes a regenerated or working-tree document. If --commit is omitted, it deliberately uses the working-tree export and labels that fallback in the handoff. The comparison starts at the merge-base of the commit and origin/dev; pass --base=<ref> to select another base ref, including when reconstructing a merged historical PR.
The sdk target receives every operation and schema-component delta. The identical scan-ios and scan-android bodies receive only scan, scannable-identifier, scan-context, /v1/me, idempotency-marker, error-code enum, and transitively referenced schema changes. The plugins target receives public RegistryInventory contracts, plugin-* registries, released webhook/event names, typed settings schemas, and curated MCP tool changes. Empty filters explicitly say there are no relevant changes.
Each structural change is one short bullet naming whether it was added, removed, or changed and whether it affects a schema, parameter, extension, or another contract. Description/example-only churn is grouped into one documentation-only count. When --coverage-report points to a feature-coverage JSON or Markdown report, its framework gate counts are embedded beside the PR link, commit, spec SHA, and target-specific action list.
Files are written to framework-notes/handoffs/. GitHub is contacted only when --create-issue is supplied.