Files
shard-wiki/src/shard_wiki/adapters/contract.py
tegwick 9a4e00a05a feat(adapters): ShardAdapter contract + read-only FolderAdapter (WP-0007 T3)
Versioned ShardAdapter ABC (shard_id/profile/keys/read mandatory; optional verbs
raise NotSupported by default = honest absence). FolderAdapter reads a dir of
Markdown into Pages (relpath=key, mtime=source_rev, provenance envelope),
declaring a validated read-only file-store profile. 4 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:37:02 +02:00

53 lines
1.9 KiB
Python

"""The shard adapter contract — the bottom narrow waist (CoreArchitectureBlueprint §6, TSD §A).
A backend participates by implementing :class:`ShardAdapter`. ``shard_id``, ``profile`` and
``read`` are mandatory; everything else is an optional capability that defaults to raising
:class:`~shard_wiki.model.NotSupported` — so a limited backend is honest about what it can't do
(graceful degradation, I-8) and core never assumes a capability it wasn't given (capability-as-
data, I-3). Declared profiles are verified by the conformance suite (T4), never taken on trust.
"""
from __future__ import annotations
import abc
from collections.abc import Iterable
from shard_wiki.model import CapabilityProfile, NotSupported, Page
__all__ = ["ShardAdapter", "CONTRACT_VERSION"]
CONTRACT_VERSION = "0.1"
class ShardAdapter(abc.ABC):
"""Versioned interface a backend implements to attach as a shard."""
contract_version: str = CONTRACT_VERSION
@property
@abc.abstractmethod
def shard_id(self) -> str:
"""Stable id scoping every Identity this shard mints."""
@abc.abstractmethod
def profile(self) -> CapabilityProfile:
"""The (to-be-verified) capability profile of this binding."""
@abc.abstractmethod
def keys(self) -> Iterable[str]:
"""The stable page keys this shard offers (the handle half of Identity)."""
@abc.abstractmethod
def read(self, key: str) -> Page:
"""Read one page by its stable key. Raises ``KeyError`` if absent."""
# --- optional capability verbs: honest NotSupported by default ---
def write(self, key: str, body: str) -> Page: # noqa: ARG002
raise NotSupported(f"{type(self).__name__} does not support write")
def diff(self, key: str, other: str) -> str: # noqa: ARG002
raise NotSupported(f"{type(self).__name__} does not support diff")
def notify(self):
raise NotSupported(f"{type(self).__name__} does not support notify")