diff --git a/.changeset/protocol-0-2-consumer-support.md b/.changeset/protocol-0-2-consumer-support.md deleted file mode 100644 index d6e31f38..00000000 --- a/.changeset/protocol-0-2-consumer-support.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@agent-facets/protocol": minor ---- - -**Consumer support for archive format `0.2` (pre-1.0 breaking minor).** The protocol now verifies both legacy `0.1` and current `0.2` `.facet` archives with strict, exact `facetVersion` dispatch and no fallback between versions. This is the consumer-first release: verification support ships before any producer emits `0.2`. - -**Breaking API — `validateFacetArchive`.** The result shape is now `{ ok: true; data: VerifiedFacetArchive } | { ok: false; failure: ArchiveVerificationFailure }`. The previous `{ ok: false; errors: ValidationError[] }` arm is replaced by a single tagged `failure`. The success payload type `VerifiedArchive` is renamed to `VerifiedFacetArchive` and is now a discriminated union on `archiveVersion`: the legacy `0.1` arm keeps the flat `assets: VerifiedAsset[]` list, while the current `0.2` arm exposes `entries: VerifiedEntry[]` (each tagged `manifest` | `primary-asset` | `skill-companion` | `archive-only`). Consumers that read `.assets` unconditionally should migrate to the version-agnostic helpers `listVerifiedFiles(archive)` and `verifiedFileHashes(archive)`. - -**Structured failures.** `ArchiveVerificationFailure` is a tagged union (`container`, `invalid-json`, `duplicate-members`, `unsupported-facet-version`, `schema-violation`, `decompression`, `integrity`, `entry-integrity`, `validation`); classify on `failure.code` rather than parsing messages. No expected failure mode throws. - -**New public API.** `VerifiedFacetArchive`, `VerifiedEntry`, `ArchiveVerificationFailure`, `ValidateFacetArchiveResult`, `listVerifiedFiles`, `verifiedFileHashes`; versioned build-manifest and lockfile schemas plus their exact-dispatch parsers `parseBuildManifestDocument` and `parseLockfileDocument`; the shared archive plan (`planArchiveEntries`, `validateSupplementaryPath`, `portableCollisionKey`); strict raw tar-header validation (`validateRawTarEntries`, `RawTarValidationOptions`); and the archive-format constants `FACET_ARCHIVE_VERSION` (`0.2`), `LEGACY_FACET_ARCHIVE_VERSION` (`0.1`), and `SUPPORTED_FACET_VERSIONS`. `parseFacetArchive` now returns a version-tagged parsed build manifest and a structured `failure`. - -**Transitional exports retained.** `BuildManifestSchema`/`BuildManifest`, `LockfileSchema`/`Lockfile`, and `LOCKFILE_VERSION` (which equals the legacy value `1`, not the current `0.2`) remain exported and `@deprecated` for the compatibility window; they are removed once the engine lockfile-migration and producer work lands. Prefer the versioned parsers and `CURRENT_LOCKFILE_VERSION` in new code. - -This release intentionally carries **no** `@agent-facets/adapter` or `agent-facets` (CLI) version bump: the adapter API `0.0`→`0.1` cutover and the CLI `0.2` producer ship in later, separately gated releases. Other implementations of the spec (e.g. the registry) adopt this published package to gain dual-format verification. diff --git a/bun.lock b/bun.lock index fe1a57fb..8b0468c2 100644 --- a/bun.lock +++ b/bun.lock @@ -137,7 +137,7 @@ }, "packages/protocol": { "name": "@agent-facets/protocol", - "version": "0.25.0", + "version": "0.29.0", "dependencies": { "arktype": "2.2.0", "comment-json": "^5.0.0", diff --git a/packages/protocol/CHANGELOG.md b/packages/protocol/CHANGELOG.md index 80767260..b21e1b67 100644 --- a/packages/protocol/CHANGELOG.md +++ b/packages/protocol/CHANGELOG.md @@ -1,13 +1,24 @@ # @agent-facets/protocol +## 0.29.0 + +### Minor Changes + +- [#437](https://github.com/agent-facets/facets/pull/437) [`5a837c5`](https://github.com/agent-facets/facets/commit/5a837c5a35d74c3fa129c90ce3d5c5dd375dd4a9) Thanks [@eXamadeus](https://github.com/eXamadeus)! - **Consumer support for archive format `0.2` (pre-1.0 breaking minor).** The protocol now verifies both legacy `0.1` and current `0.2` `.facet` archives with strict, exact `facetVersion` dispatch and no fallback between versions. This is the consumer-first release: verification support ships before any producer emits `0.2`. + **Breaking API — `validateFacetArchive`.** The result shape is now `{ ok: true; data: VerifiedFacetArchive } | { ok: false; failure: ArchiveVerificationFailure }`. The previous `{ ok: false; errors: ValidationError[] }` arm is replaced by a single tagged `failure`. The success payload type `VerifiedArchive` is renamed to `VerifiedFacetArchive` and is now a discriminated union on `archiveVersion`: the legacy `0.1` arm keeps the flat `assets: VerifiedAsset[]` list, while the current `0.2` arm exposes `entries: VerifiedEntry[]` (each tagged `manifest` \| `primary-asset` \| `skill-companion` \| `archive-only`). Consumers that read `.assets` unconditionally should migrate to the version-agnostic helpers `listVerifiedFiles(archive)` and `verifiedFileHashes(archive)`. + **Structured failures.** `ArchiveVerificationFailure` is a tagged union (`container`, `invalid-json`, `duplicate-members`, `unsupported-facet-version`, `schema-violation`, `decompression`, `integrity`, `entry-integrity`, `validation`); classify on `failure.code` rather than parsing messages. No expected failure mode throws. + **New public API.** `VerifiedFacetArchive`, `VerifiedEntry`, `ArchiveVerificationFailure`, `ValidateFacetArchiveResult`, `listVerifiedFiles`, `verifiedFileHashes`; versioned build-manifest and lockfile schemas plus their exact-dispatch parsers `parseBuildManifestDocument` and `parseLockfileDocument`; the shared archive plan (`planArchiveEntries`, `validateSupplementaryPath`, `portableCollisionKey`); strict raw tar-header validation (`validateRawTarEntries`, `RawTarValidationOptions`); and the archive-format constants `FACET_ARCHIVE_VERSION` (`0.2`), `LEGACY_FACET_ARCHIVE_VERSION` (`0.1`), and `SUPPORTED_FACET_VERSIONS`. `parseFacetArchive` now returns a version-tagged parsed build manifest and a structured `failure`. + **Transitional exports retained.** `BuildManifestSchema`/`BuildManifest`, `LockfileSchema`/`Lockfile`, and `LOCKFILE_VERSION` (which equals the legacy value `1`, not the current `0.2`) remain exported and `@deprecated` for the compatibility window; they are removed once the engine lockfile-migration and producer work lands. Prefer the versioned parsers and `CURRENT_LOCKFILE_VERSION` in new code. + This release intentionally carries **no** `@agent-facets/adapter` or `agent-facets` (CLI) version bump: the adapter API `0.0`→`0.1` cutover and the CLI `0.2` producer ship in later, separately gated releases. Other implementations of the spec (e.g. the registry) adopt this published package to gain dual-format verification. + ## 0.25.0 ### Minor Changes - [#418](https://github.com/agent-facets/facets/pull/418) [`3ef7a65`](https://github.com/agent-facets/facets/commit/3ef7a6572a3b4c8ab834e3f27c8e9cbd4957af85) Thanks [@eXamadeus](https://github.com/eXamadeus)! - Enforce the Agent Skills name grammar for skill, command, and agent names everywhere names enter the system. - `@agent-facets/protocol` gains a canonical asset-name grammar (`schemas/asset-name.ts`) modeled on the [Agent Skills spec](https://agentskills.io/specification#name-field). New exports: `parseAssetName`, `parseAssetNameSegment`, `validateAssetName`, and `validateAssetNameSegment`, along with the `AssetNameResult` and `AssetNameSegmentResult` types. A single segment is 1–64 characters of lowercase ASCII letters, digits, and hyphens, must not start or end with a hyphen, and must not contain consecutive hyphens. Full asset names may carry `/`-separated namespace segments (`viper-plans/planning`), each validated independently; the parsers return discriminated-union results instead of throwing. - BREAKING CHANGE: `FacetManifestSchema` now validates every asset name against this grammar instead of the previous path-safety-only check. Manifests declaring non-conforming asset names (uppercase like `MySkill`, underscores like `foo_bar`, leading/trailing or consecutive hyphens, names over 64 characters) now fail at build **and** install — the schema validates fetched manifests too — rather than passing silently. Digit-start names (`2fa`) are now valid, diverging from the stricter facet-identity slug grammar. Lockfile asset names intentionally keep the weaker path-safety guard so existing installs continue to load and can be removed. - The `agent-facets` CLI routes `facet create` (wizard and headless), the create/edit TUI views, and `facet modify` (`--add` and `--rename`) through the shared validator, surfacing the grammar's own reason strings in errors. `facet modify --update`/`--remove` still accept legacy non-conforming names so users can fix or remove them. + `@agent-facets/protocol` gains a canonical asset-name grammar (`schemas/asset-name.ts`) modeled on the [Agent Skills spec](https://agentskills.io/specification#name-field). New exports: `parseAssetName`, `parseAssetNameSegment`, `validateAssetName`, and `validateAssetNameSegment`, along with the `AssetNameResult` and `AssetNameSegmentResult` types. A single segment is 1–64 characters of lowercase ASCII letters, digits, and hyphens, must not start or end with a hyphen, and must not contain consecutive hyphens. Full asset names may carry `/`-separated namespace segments (`viper-plans/planning`), each validated independently; the parsers return discriminated-union results instead of throwing. + BREAKING CHANGE: `FacetManifestSchema` now validates every asset name against this grammar instead of the previous path-safety-only check. Manifests declaring non-conforming asset names (uppercase like `MySkill`, underscores like `foo_bar`, leading/trailing or consecutive hyphens, names over 64 characters) now fail at build **and** install — the schema validates fetched manifests too — rather than passing silently. Digit-start names (`2fa`) are now valid, diverging from the stricter facet-identity slug grammar. Lockfile asset names intentionally keep the weaker path-safety guard so existing installs continue to load and can be removed. + The `agent-facets` CLI routes `facet create` (wizard and headless), the create/edit TUI views, and `facet modify` (`--add` and `--rename`) through the shared validator, surfacing the grammar's own reason strings in errors. `facet modify --update`/`--remove` still accept legacy non-conforming names so users can fix or remove them. ## 0.24.1 diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 34306d39..fbdaa54b 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -5,7 +5,7 @@ "url": "https://github.com/agent-facets/facets", "directory": "packages/protocol" }, - "version": "0.25.0", + "version": "0.29.0", "type": "module", "files": [ "dist"