Metadata-Version: 2.5
Name: juntai-configuration-client
Version: 1.1.0
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 exact 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
the canonical JSON payload through the internal Configuration Registry Publish RPC.
Publication succeeds only after the Registry publishes the exact Meridian reference.
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.1.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.1.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`.

## Exact Meridian publication

SDK 1.1.0 requires Registry 1.1.1 for publication. Supply canonical UTF-8 JSON
object bytes (sorted keys, compact separators, finite numbers, 1 byte to 2 MiB).
An optional `schema_ref` passes the exact domain SchemaRef; when omitted, the
Registry resolves its configured kind-to-SchemaRef mapping. The owning service
must provision that schema in the configured public Meridian runtime.

The SDK sends the same bytes whose immutable OCI layer it uploaded and checks
the returned `payload_digest`. `published.reference.oci.manifest_digest` keeps
its OCI manifest meaning. Application Metadata's contribution digest must use
`published.payload_digest`. It resolves `(tenant, "configuration", configuration_id,
revision_id)` through Meridian. No Meridian package is needed in the SDK or Builder.

Retry an interrupted publication with the same input and idempotency key. This
also reconciles compatible historical receipts without changing their IDs or
manifest digests. Missing runtime/schema, unsupported old servers, digest mismatch,
or deprecation returns an error; the SDK never falls back to legacy registration.
Metadata-only resolution and OCI download keep their existing behavior.
