Metadata-Version: 2.5
Name: juntai-configuration-client
Version: 1.0.2
Summary: Opaque configuration publication and resolution for Juntai
Project-URL: Homepage, https://github.com/zephytiju/JuntaiConfigurationClient
Project-URL: Repository, https://github.com/zephytiju/JuntaiConfigurationClient.git
Author-email: Juntai Team <dev@juntai.com>
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: grpcio<2,>=1.81.1
Requires-Dist: oras<0.3,>=0.2.42
Requires-Dist: protobuf<7,>=6.33.5
Description-Content-Type: text/markdown

# Juntai Configuration Client

`juntai-configuration-client` is the backend Python client for publishing and
resolving opaque configuration revisions. The stable import is
`juntai.configuration`.

After the corrected release is published, backend services install only:

```bash
python -m pip install "juntai-configuration-client>=1,<2"
```

The package pushes payload bytes directly to an OCI Distribution-compatible
registry, verifies the immutable manifest digest and media types, and registers
generic metadata through the internal Configuration Registry RPC service.
Resolution obtains the exact metadata through that service, pulls directly from
OCI by digest, and verifies every descriptor before returning opaque bytes.
Domain services continue to own serialization, schemas, and interpretation.

The previous `juntai-configuration` distribution and its associated evidence are
superseded and must not be used or republished. Its external deletion is not a
release gate and this project does not provide an alias or compatibility bridge.
A corrected `juntai-configuration-client` package is built only from the pinned
Configuration Registry v1.0.1 Protobuf release and the pinned FuseAPI generator.

Generated modules are an implementation detail. Callers use only the high-level
`ConfigurationClient` workflows. Browser applications, Console or Micro-UI code,
registry administration, and OCI credential behavior are outside this package.

Backend services that only need authoritative Registry metadata construct a
secure client without OCI and supply caller or delegation credentials for each
RPC. The credential is an opaque `grpc.CallCredentials` value or a
`CallCredentialsProvider` resolved for every retry attempt; it is never accepted
as generic metadata, cached, logged, or returned:

```python
from juntai.configuration import ConfigurationClient

with ConfigurationClient.connect(
    registry_target="dns:///configuration-registry.platform.svc:7443",
    registry_credentials=mtls_channel_credentials,
) as configurations:
    metadata = configurations.resolve_metadata(
        configuration_id=configuration_id,
        revision_id=revision_id,
        caller_credentials=request_call_credentials,
        timeout=5.0,
        correlation_id=correlation_id,
        cancellation=cancellation,
    )
    if metadata.deprecated:
        raise DeprecatedConfigurationError(metadata.deprecated_at)
```

This exact-pair workflow returns the Registry-owned `tenant_id`,
`configuration_id`, `revision_id`, `deprecated`, and `deprecated_at` values. It
does not accept aliases and never constructs or invokes an OCI transport. The
mTLS channel continues to prove the owning backend workload identity while the
call credential preserves the original caller or delegated tenant context.

Owning backend services inject platform-provided workload identity and an OCI
transport. This package constructs only a secure mTLS gRPC channel; it has no
insecure Registry mode and does not acquire workload or OCI credentials:

```python
from juntai.configuration import ConfigurationClient

with ConfigurationClient.from_workload(
    registry_target="dns:///configuration-registry.platform.svc:7443",
    oci=oci_transport,
    identity_provider=workload_identity_provider,
) as configurations:
    published = configurations.publish(
        namespace="runtime",
        name="credit-review",
        kind="axiom.workflow-runtime",
        payload=serialized_configuration,
        media_type="application/vnd.juntai.axiom.workflow-runtime.v1+json",
        provenance={"source_revision": source_revision, "build_id": build_id},
        idempotency_key=idempotency_key,
        correlation_id=correlation_id,
        deadline_seconds=10,
    )
    exact_bytes = configurations.resolve_and_download(
        published.reference,
        correlation_id=correlation_id,
        deadline_seconds=10,
    )
```

The metadata RPC accepts only the exact owner contract. Registration sends
`source_revision` and `build_id`; tenant, owner, producer identity, and creation
time are server-derived. Resolution always uses the exact tenant-scoped
`configuration_id + revision_id` pair and never follows an alias.

## Development

```bash
python scripts/check_production_boundary.py
uv sync --locked --all-groups --no-editable
uv run --locked --no-sync python scripts/generate_registry_grpc.py --check
uv run --locked --no-sync pytest
uv run --locked --no-sync ruff format --check .
uv run --locked --no-sync ruff check .
uv build
```

The OCI conformance vector is
`conformance/configuration-oci-v1.json`. The exact Registry v1.0.1 owner pin is
`contracts/upstream/configuration-registry.lock.json`; its source is reproduced
under `contracts/upstream/configuration-registry/v1`, and generated modules live
only under
`juntai.configuration.generated.juntai.registry.configuration.v1`.

Deterministic stub generation is pinned independently through
`juntai-fuse-api[grpc-generated]==1.1.2`, profile
`juntai.fuse.profile.grpc-generated` v1.0.0. Its immutable release identity and
toolchain are recorded in
`contracts/upstream/fuse-api-generation.lock.json`.
