artisanpack-ui / specification
Ingests specification.website's Open Knowledge Format into a local index and exposes the SpecCheck registry other ArtisanPack UI packages build checks on.
Requires
- php: ^8.3
- ext-pdo_sqlite: *
- ext-zlib: *
- artisanpack-ui/core: ^1.0
- illuminate/console: ^13.0
- illuminate/database: ^13.0
- illuminate/filesystem: ^13.0
- illuminate/http: ^13.0
- illuminate/support: ^13.0
- league/commonmark: ^2.7
- symfony/yaml: ^7.4|^8.0
Requires (Dev)
- artisanpack-ui/code-style: ^1.1
- artisanpack-ui/code-style-pint: ^1.1
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- friendsofphp/php-cs-fixer: ^3.75
- laravel/pint: ^1.26
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-11 14:34:00 UTC
README
Ingests The Website Specification's Open Knowledge Format (OKF) bundle into a local index and exposes the SpecCheck registry other ArtisanPack UI packages build checks on.
This package owns OKF ingestion, the local search index, the SpecCheck contract and registry, result aggregation, and CC BY 4.0 attribution. It never implements domain checks itself. Those live in their owner packages (seo, security, accessibility, performance, privacy, cms-framework, …). A single reference check for foundations/doctype ships in this package as the pattern to copy.
Requirements
- PHP 8.3+
- Laravel 13
ext-pdo_sqlite(with FTS5) andext-zlib
Installation
composer require artisanpack-ui/specification php artisan migrate php artisan keystone:spec-sync
Publish the config file (optional):
php artisan vendor:publish --tag=specification-config
The config is merged under the artisanpack.specification key. The package registers a weekly sync with the Laravel scheduler.
Usage
// Sync the OKF snapshot (idempotent and safe on cron). specification()->sync(); // Search the local index and look up topics. $hits = specification()->search( 'content security policy' ); $topic = specification()->topic( 'foundations/doctype' ); // Render topic text. Attribution is always attached. echo specification()->render( $topic )->toHtml(); // Run the registered checks and build a four-tier report. use ArtisanPackUI\Specification\Checks\SpecContext; $results = specification()->run( SpecContext::page( 'https://example.com', $html, $headers ) ); $report = specification()->report( $results );
Artisan Commands
| Command | Purpose |
|---|---|
keystone:spec-sync [--force] [--archive=] |
Sync the OKF bundle into the snapshot, topics table, and search index |
keystone:spec-diff [--since=] |
Show what the last sync changed and, with the MCP client enabled, what has changed upstream since |
keystone:spec-check [--category=] [--slug=*] [--url=] |
Run the registered checks against a URL. Fails if a Required check fails, an Avoid practice is present, or a check errors |
Authoring Checks (for Owner Packages)
Implement ArtisanPackUI\Specification\Contracts\SpecCheck and register it from your service provider:
use ArtisanPackUI\Specification\Checks\CheckRegistry; public function boot(): void { $this->callAfterResolving( CheckRegistry::class, function ( CheckRegistry $registry ): void { $registry->registerMany( [ XmlSitemapCheck::class ] ); } ); }
See src/Checks/Foundations/DoctypeCheck.php and the SpecCheck authoring guide.
Checks in This Package
| Slug | Status | Scope | Autofix | Registered by default |
|---|---|---|---|---|
foundations/doctype |
Required | Page | Yes, when the context provides an html_writer |
No. Add DoctypeCheck::class to artisanpack.specification.checks |
MCP Client
An optional client for the specification.website MCP server (list_topics, get_topic, get_changes, search) checks how fresh your snapshot is. It is disabled by default, and the package then runs snapshot-only. Enable it with SPECIFICATION_MCP_ENABLED=true. See MCP Client.
Attribution
Specification content is © The Website Specification contributors and licensed under CC BY 4.0. This package's code is MIT licensed.
Anywhere you display topic text, you must credit the topic title and The Website Specification, link to the topic, and name and link the license. Render topic bodies through specification()->render(), which always attaches the attribution. Echoing body_md directly bypasses it. Marketing surfaces are blocked, and paid surfaces put the attribution first. See Attribution Requirements.
Documentation
The full documentation is in docs/. For production setups (multiple servers, ephemeral filesystems, offline syncs), see Deployment & Operations.
Contributing
As an open-source project, this package is open to contributions from anyone. Please read through the contributing guidelines to learn more about how you can contribute to this project.