Registry taxonomy.
Package kinds
Platform spec feature
Package kinds
Spec standingStandard
-
packageKind field
Context
Decision
Explicit packageKind on package manifest.
Consequences
Validators and UI.
Verification anchors
Server tests.
-
Historical reservation of `packageKind: tool` without a normative profile; superseded by D-TOOL-PCKG-0004.
Context
When the
packageKindfield was introduced onbeskid.package.v1, two kinds (library,template) had concrete validator profiles and dashboard routing;toolwas anticipated but not yet specified. The team did not want the absence oftoolrules to be interpreted as silent acceptance.Decision
Reserve
toolas a known-but-not-StandardpackageKindvalue. The pckg server accepted the literal string but did not commit to validator behavior, dashboard routing, or CLI flags. Publishers were warned that the contract would land in a follow-up decision.Consequences
- Validators recognised the kind without expanding the supported set: any deviation from the
libraryprofile would be a future, opt-in change. - The dashboard fell back to the
libraryrendering fortoolartifacts, which made the kind effectively invisible to users. - CLI tooling (
beskid pckg pack) had no--package-kindflag, so publishers could not deliberately mark an artifact astool.
Verification anchors
Verification responsibility transferred to D-TOOL-PCKG-0004; see
0004-tool-kind-standard.mdxfor the current test surface. - Validators recognised the kind without expanding the supported set: any deviation from the
-
beskid.templates.*
Context
Registry taxonomy.
Decision
First-party templates use beskid.templates.* prefix.
Consequences
Validators and UI.
Verification anchors
Server tests.
-
Normative validator profile, CLI routing, and dashboard surface for packageKind tool.
Context
D-TOOL-PCKG-0002 reserved
toolas a forbiddenpackageKindwhile validator profiles, CLI routing, and registry UI surfaces remained undefined. By the v0.3 baseline, three concrete needs converged:- External tool packs (custom diagnostics, formatter rule packs, language-server extensions) want to ship through pckg without being mis-classified as
library(which forcesapi.jsongeneration) ortemplate(which forces.beskid/template.json). - The registry dashboard already routes
libraryandtemplatekinds to distinct surfaces viaPackageDetails.razor. A third surface — with no Docs / Source tabs — is straightforward to add given the existing_isTemplatePackagepattern. - The Beskid CLI already supports per-profile packing in
beskid_pckg::pack::PackProfile. Extending the enum with aToolvariant and a--package-kind toolCLI flag is a localized change.
The platform-spec leads code: this ADR makes the validator profile, CLI routing, and dashboard surface normative so the implementation can land without ambiguity.
Decision
Lift
packageKind: toolfrom Reserved to Standard with the following normative profile:- Server validator (
PackageArtifactValidator) must acceptpackageKind: toolartifacts. The artifact must not contain.beskid/template.json; the artifact may contain.beskid/docs/api.json, but it must not be required byPckg:Publish:RequireStructuredApiDoc. The packedpackage.jsonmust not includedocumentation.apiJsonfor the tool kind. - Publish persistence must record the resolved
packageKindin the version metadata via the existingPackageManifestMetadataReaderpath. - Dashboard routing (
PackageDetails.razor) must mirror the template-kind pattern: an_isToolPackageflag selects an install/usage card and suppresses the Docs / Source tabs by default. The Ratings tab and Versions tab remain unchanged. - Rust pack flow (
beskid_pckg::pack) must add aPackProfile::Toolvariant and thebuild_package_jsonpath must emit"packageKind": "tool"without adocumentationblock. A newstrip_tool_pack_excludeshelper must remove.beskid/docs/api.jsonfrom the artifact body when the tool profile is selected. - CLI surface (
beskid_pckg::cli) must add a--package-kind <library|template|tool>flag topack. When set totool, the CLI must skip theapi.jsonpre-generation pass inbeskid_cli::cli::maybe_generate_docs_for_pack. The flag must refuse to combine with aProject.projwhoseproject.type = Template.
Consequences
- Forwards-compatible: Existing
libraryandtemplateartifacts are unaffected; pre-existingtool-rejection tests are updated rather than removed. - Server-side migration:
PackageKinds.IsSupportednow returns true fortool. Operators running validator policyRequireStructuredApiDoc = truesee no behavior change for library packages; tool packages explicitly bypass that requirement. - CLI ergonomics: Publishers who want to ship a developer tool through the registry no longer need to hand-author
package.json; thebeskid pckg pack --package-kind toolflow handles it. - Dashboard parity: The pckg UI uses Fluent UI Blazor patterns for the new tool card, matching the existing template install card. No new design tokens are introduced.
Verification anchors
pckg/src/Server.Tests/Unit/PackageArtifactValidatorTests.cs::ValidateAsync_Accepts_Tool_Artifact_Without_Api_Jsonpckg/src/Server.Tests/Unit/PackageArtifactValidatorTests.cs::ValidateAsync_Rejects_Tool_With_Template_Jsonpckg/src/Server.Tests/Integration/ToolPackagePublishIntegrationTests.cscompiler/crates/beskid_pckg/src/pack.rs::tests::build_package_json_tool_profile_omits_api_doc_pointercompiler/crates/beskid_pckg/src/pack.rs::tests::strip_tool_pack_excludes_removes_api_jsoncompiler/crates/beskid_pckg/src/cli.rs::tests::pack_args_accepts_package_kind_tool
- External tool packs (custom diagnostics, formatter rule packs, language-server extensions) want to ship through pckg without being mis-classified as
- No directly attached article pages for this node.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
| Section id | Required | Found |
|---|---|---|
what-this-feature-specifies | yes | yes |
implementation-anchors | yes | yes |
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
What this feature specifies
The packageKind field on beskid.package.v1 — discriminates library, template, and tool packages, each with a normative validator profile, dashboard surface, and CLI routing. tool is Standard as of D-TOOL-PCKG-0004 (this feature) — the previous Reserved status (D-TOOL-PCKG-0002) is superseded.
Implementation anchors
pckg/src/Server/Services/PackageKinds.cs— kind constants andIsSupported/IsTemplate/IsToolpredicatespckg/src/Server/Services/PackageArtifactValidator.cs— per-kind validator profiles (library / template / tool)pckg/src/Server/Services/PackagePublishDocumentation.cs— exemptstemplateandtoolfrom structuredapi.jsonrequirementspckg/src/Server/Components/Pages/PackageDetails.razor(.cs) — Fluent UI dashboard routing (badge, install-instructions card, hidden Documentation / Source tabs fortemplateandtool)compiler/crates/beskid_pckg/src/pack.rsandcli.rs— RustPackProfile(Library/Template/Tool),detect_pack_profile_with_override,strip_tool_pack_excludes, andbeskid pckg pack --package-kind {auto,tool}
Contract statement
Every published beskid.package.v1 artifact must declare its role through packageKind. Kinds drive validator profiles, registry UI routing, and CLI behavior. Unknown packageKind values must be rejected at publish time with a structured BadRequest diagnostic, never a 500.
project.type on Project.proj is the project-tree analogue (Host, Mod, Template, …); packageKind is the registry artifact analogue—they are related but not interchangeable.
Normative kinds
packageKind | Purpose | api.json requirement | .beskid/template.json | Primary CLI |
|---|---|---|---|---|
library (default) | Beskid source package consumed as dependency | Required when server policy mandates api.json | Forbidden | beskid pckg pack, consumer beskid fetch |
template | Scaffold package for beskid new | Forbidden in artifact body; structured docs hidden in UI | Required | beskid new install, beskid new <shortName> |
tool | CLI / developer-tool binaries and CLI-only packages distributed via pckg | Optional — server does not require it, validator does not reject its absence | Forbidden (tool and template are mutually exclusive) | beskid pckg pack --package-kind tool, consumer beskid pckg download <name> --version <v> --output <path> |
Unknown packageKind values must be rejected at publish time. The server must reject a tool artifact that contains .beskid/template.json (and vice versa) with a deterministic message naming the conflicting file.
Validator profile per kind
The pckg server applies the kind-specific validator profile during publish:
library— when the server enforces structured docs, the artifact must carry.beskid/docs/api.json; the artifact must not carry.beskid/template.json.template— the artifact must carry.beskid/template.jsonand must not carry.beskid/docs/api.json(server treats template-kind artifacts as scaffold-only; the dashboard hides the Documentation and Source tabs).tool— the artifact may omit.beskid/docs/api.jsonentirely (no docs-required diagnostic fires); it must not carry.beskid/template.json. The dashboard renders a Tool package Fluent badge and an install-instructions card with the registry download command (beskid pckg download …).
All kinds remain subject to the shared safeguards: zip-bomb / path-traversal guards, package-id authorization, and per-package owner gating.
CLI routing
The Beskid CLI surfaces packageKind through beskid pckg pack --package-kind {auto, tool}:
auto(default) — reproduces the historical manifest-driven detection.Project.projwithtype = Templatepacks atemplateartifact (template summary copied from.beskid/template.json); any other manifest or a missing manifest packs alibraryartifact.tool— packs atoolartifact even whenProject.projis absent, which is the expected layout for CLI-only tool packages.--package-kind toolmust reject template projects (manifest withtype = Template) so a template payload is never silently lost; the error message must name--package-kind toolso users can correct it.
tool pack runs strip generated .beskid/docs/** entries from the artifact (strip_tool_pack_excludes); tool package.json omits documentation.apiJson and the schema version pointer.
Consumers download tool artifacts with beskid pckg download <name> --version <v> --output <path>; the dashboard install card surfaces the exact command (e.g. beskid pckg download beskid-fmt-extra --version 0.1.0 --output ./beskid-fmt-extra.bpk).
Project.type alignment
project.type | Typical packageKind when published |
|---|---|
(absent) / Host | library (or tool via --package-kind tool for CLI-only packages with no Project.proj) |
Mod | library |
Template | template |
A library package must not publish with type: Template on Project.proj. A template package must include .beskid/template.json. A tool package must not include .beskid/template.json; it does not require Project.proj at all.
Versioning
All kinds share: registry-assigned publish semver, immutability per version, yank, checksum verification, and download URLs.
Decisions
- D-TOOL-PCKG-0001 — Explicit
packageKindfield onbeskid.package.v1(seeadr/0001-explicit-package-kind-field.mdx). - D-TOOL-PCKG-0002 — Superseded.
toolpackageKind no longer reserved; seeadr/0002-tool-kind-reserved.mdxfor the historical record andadr/0004-tool-kind-standard.mdxfor the active decision. - D-TOOL-PCKG-0003 —
beskid.templates.*identity prefix for template packages (seeadr/0003-beskid-templates-prefix.mdx). - D-TOOL-PCKG-0004 —
toolpackageKind is Standard with a normative validator profile, CLI override, and dashboard routing (adr/0004-tool-kind-standard.mdx).
Use the ADRs tab to expand each decision.
Verification and traceability
pckg/src/Server.Tests/Unit/PackageArtifactValidatorTests.cs—ValidateAsync_Accepts_Tool_Artifact_Without_Api_Json,ValidateAsync_Accepts_Tool_Artifact_With_Optional_Api_Json,ValidateAsync_Rejects_Tool_With_Template_Json,ValidateAsync_Rejects_Unknown_Package_Kind.pckg/src/Server.Tests/Unit/PackagePublishDocumentationTests.cs—EnsureStructuredApiDoc_skips_tool_packages.pckg/src/Server.Tests/Integration/ToolPackagePublishIntegrationTests.cs— end-to-end tool publish with structured docs absent, kind persisted on the version summary.compiler/crates/beskid_pckg/src/pack.rstests —pack_profile_helpers_track_variant,build_package_json_tool_profile_omits_api_doc_pointer,strip_tool_pack_excludes_removes_generated_docs,detect_pack_profile_with_override_forces_tool_when_no_manifest,detect_pack_profile_with_override_rejects_template_project,detect_pack_profile_auto_matches_legacy_behavior.compiler/crates/beskid_pckg/src/cli.rstests —pack_args_default_package_kind_is_auto,pack_args_package_kind_tool_flag_parses,pack_args_package_kind_rejects_unknown_value.
- Template packages — the
templatepackageKind. - pckg client contract — publish / download surface used by
toolpackages. - Formatter — representative tool delivered via
beskid format(a possible futurepackageKind: tooldistribution candidate). - api.json contract — applies to
librarypackages; does not apply totoolartifacts.