Validation, authorization and limits
Every snapshot is fully downloaded and validated before publication: Go-compatible manifest canonicalization, SHA-256, sizes, paths and modes. Cache is in memory and private to each view/client; no shared disk/offline cache. Default limits: 10,000 files, 8 MiB per file/manifest, 64 MiB per snapshot, 256 KiB per SKILL.md parsing input. Concurrent/retained views multiply memory use; applications should limit concurrency and release references.
Every public read/catalog/export rechecks the explicit snapshot manifest online, even for cached bytes. Changed permissions invalidate a captured view; explicit credential revocation is sticky for that client instance. Network failure blocks the operation. No offline mode, transparent network retries, or model-task retries. An authorization race after the final check and previously delivered content cannot be undone. HTTP redirects are not followed; bearer tokens are not included in SDK error messages. Raw transport instrumentation can still expose credentials; configure logging accordingly. Environment proxy/CA settings are ignored by default (trust_env=False); opt in explicitly with trust_env=True if needed, and install httpx[socks] for SOCKS proxies. A custom HTTPX transport can supply application TLS/proxy settings.
Useful errors: VersionMismatch, ManifestChanged, AuthorizationDenied, IntegrityError, ProtocolError, LimitExceeded, SkillNotFound, TransportError, ClosedError.
Development and verification
uv sync --extra dev --extra pydantic-ai
uv run pytest -q
uv run ruff check src tests examples
uv run python -m build
uv run python examples/offline_demo.py
Tests use a controlled distribution fixture and Pydantic's actual FunctionModel agent loop, without external model calls. They cover updates/rollback, same-snapshot permission changes, concurrent reads/runs, old-content provenance, corruption, export isolation, and Go-generated manifest fixtures. The offline demo requires no server or credentials. It is not a substitute for deployment acceptance against your Skiva server and selected model provider.
See examples/ and CHANGELOG.md. Official integration references: Pydantic capabilities, Agent Skills implementation guide.
Detailed scenarios and recorded results: Testing guide.
Verification scope
Three complex Skills (expense-audit, release-review, data-contract) cover two releases, nested references, scripts, Unicode, binary and empty files, plus concurrent updates, rollback, revocation, corruption and multi-turn model loading.
Linux CI for verified commit 011bf4f passed 102 tests, package builds and the offline example on Python 3.11, 3.12 and 3.13. Agent tests use the actual Pydantic AI loop with scripted FunctionModel responses, not a live model; actual backend, provider and deployment acceptance is still required.
Continue reading
Python SDK quickstart · Snapshots and update policies · Pydantic AI integration · File export and framework integration
Authorization and outages
Missing, expired, disabled or revoked client credentials return 403 CLIENT_FORBIDDEN. Database failures return 503 DISTRIBUTION_UNAVAILABLE with Retry-After: 1; callers decide their retry boundary. SSE emits unavailable and closes on database failure, allowing reconnection; only actual credential denial emits revoked. No database details are exposed. An already delivered Skill or model context cannot be recalled.
Successful client authentication updates activity at most once per 30 seconds, including ordinary SDK requests. This is request activity, not proof an Agent task is healthy. It does not fabricate mount cache telemetry or a reported active snapshot.
Historical grant retention
Apply migration 00004_snapshot_grant_retention.sql before running the updated server. SKIVA_SNAPSHOT_GRANT_TTL_SECONDS is optional: unset or 0 preserves unlimited historical grants; a positive integer (maximum 315360000) gives newly created grants a fixed lifetime from first authorization. Reading a historical grant does not extend it. Existing unlimited grants are not retroactively shortened. Invalid configuration fails closed with 503.
An expired historical grant denies both manifest and object reads. Current channel targets and configured Profile pins remain authorized and can receive a new grant. Thus this is historical retention, not an administrative ban on a release. Rollback does not revoke previous grants. Remove profile permissions or revoke a client credential to stop further authorized reads. No grant garbage collection, snapshot deletion, or exported-file recall is implied. A stored SDK binding whose grant expires fails explicitly instead of falling back to latest.
Performance without stale authorization
The SDK sends If-None-Match using a bounded metadata cache. Server authorization and permission-filtered manifests are checked before 304. ETags include snapshot ID, manifest digest and channel generation, so equal-content snapshots cannot be confused. Object authorization uses an SQL membership query instead of reconstructing/canonicalizing the entire manifest per file. It still checks current profile permissions. These reduce redundant work; no throughput improvement is claimed without a benchmark.