diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index 429e963..0000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Release Please - -on: - push: - branches: [main] - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-22.04 - steps: - - uses: googleapis/release-please-action@v5 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a6dd98..4dca3f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,12 @@ name: Release # Tag-triggered distribution. On a `vX.Y.Z` tag this publishes the user-facing # install channels; docker.yml (gateway image) and release-airgap.yml (offline # bundle) fire on the same tag, so one tag fans out to every channel. +# +# The tag is the version authority (ADR-0053): scripts/stamp_versions.py stamps +# X.Y.Z onto every workspace component + the rag-platform meta before building, +# npm stamps the TS SDK, and helm stamps the chart — so every artifact a tag +# produces carries the same platform version, and the meta's `==X.Y.Z` pins +# resolve against the component dists published from the very same run. on: push: tags: ["v*.*.*"] @@ -12,6 +18,10 @@ on: description: "Build artifacts but skip publishing" type: boolean default: true + version: + description: "Platform version to stamp on non-tag builds" + type: string + default: "0.0.0" permissions: contents: read @@ -21,7 +31,7 @@ env: jobs: pypi: - name: PyPI (rag-platform + SDK) + name: PyPI (components + rag-platform + SDK) runs-on: ubuntu-22.04 permissions: id-token: write # PyPI Trusted Publishing (OIDC) — no API token @@ -30,11 +40,26 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.12" - - run: pip install build - - name: Build meta-distribution + SDK + - uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "uv.lock" + - name: Resolve platform version + id: ver + env: + INPUT_VERSION: ${{ inputs.version }} run: | - python -m build --outdir dist-pypi packaging/rag-platform - python -m build --outdir dist-pypi sdks/python + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + else + echo "version=${INPUT_VERSION}" >> "$GITHUB_OUTPUT" + fi + - name: Stamp the platform version onto every dist + run: python scripts/stamp_versions.py "${{ steps.ver.outputs.version }}" + - name: Build every workspace component + the Python SDK + run: uv build --all-packages --out-dir dist-pypi + - name: Build the rag-platform meta-distribution + run: uv build packaging/rag-platform --out-dir dist-pypi - name: Publish to PyPI if: ${{ github.event_name == 'push' || !inputs.dry_run }} uses: pypa/gh-action-pypi-publish@release/v1 @@ -52,9 +77,20 @@ jobs: with: node-version: 20 registry-url: "https://registry.npmjs.org" + - name: Resolve platform version + id: ver + env: + INPUT_VERSION: ${{ inputs.version }} + run: | + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + else + echo "version=${INPUT_VERSION}" >> "$GITHUB_OUTPUT" + fi - working-directory: sdks/typescript run: | npm ci + npm version "${{ steps.ver.outputs.version }}" --no-git-tag-version --allow-same-version npm run build - name: Publish (with provenance) if: ${{ github.event_name == 'push' || !inputs.dry_run }} @@ -119,11 +155,26 @@ jobs: - uses: actions/checkout@v6 - uses: azure/setup-helm@v4 - uses: sigstore/cosign-installer@v3 - - name: Package + push + sign + - name: Resolve platform version + id: ver + env: + INPUT_VERSION: ${{ inputs.version }} + run: | + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + else + echo "version=${INPUT_VERSION}" >> "$GITHUB_OUTPUT" + fi + - name: Package (chart version = platform version) + run: | + helm package infra/helm/rag-platform --destination . \ + --version "${{ steps.ver.outputs.version }}" \ + --app-version "${{ steps.ver.outputs.version }}" + - name: Push + sign + if: ${{ github.event_name == 'push' || !inputs.dry_run }} run: | echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login "${REGISTRY}" -u "${{ github.actor }}" --password-stdin repo="oci://${REGISTRY}/$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')/agentcontextos/charts" - helm package infra/helm/rag-platform --destination . chart="$(ls rag-platform-*.tgz)" out="$(helm push "${chart}" "${repo}" 2>&1)"; echo "${out}" digest="$(echo "${out}" | awk '/Digest:/ {print $2}')" diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index b27433c..0000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "packages/core": "0.2.0", - "apps/gateway": "0.2.0" -} diff --git a/CLAUDE.md b/CLAUDE.md index def505d..2d16c9f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -261,3 +261,7 @@ Add a **Documentation** section listing the doc file(s) added or updated so revi - Every SPI method takes `ctx: RequestContext` first (Step 1.1a onward). - Every retrieval / ingest / egress call site consults `PolicyEngine` (Step 1.1c onward). - Hot-path discipline: Pydantic at SPI boundaries only; `model_construct()` / msgspec inside loops. +- One platform version (ADR-0053): every workspace member, literal `__version__`, and the + `rag-platform` meta (its `==` pins included) carry the same version in lockstep — never bump a + single package by hand. Re-stamp with `task version:stamp -- X.Y.Z` + (`scripts/stamp_versions.py`); gated by `tests/packaging/`. Release tags re-stamp in CI. diff --git a/TRACKER.md b/TRACKER.md index d15c09d..7fe4131 100644 --- a/TRACKER.md +++ b/TRACKER.md @@ -16,11 +16,11 @@ | **Last updated** | 2026-06-10 | | **Current phase** | Phase 7 — Pilot, Harden, GA (**10 / 10 steps ✅**) — **all phases complete** | | **Overall** | **84 / 84 steps ✅ — v1.0.0 GA** | -| **Next action** | **🎉 GA reached.** Engineering scope (Phases 0–7) complete; `v1.0.0` cut. Remaining items are external/process (external pentest, SOC 2 audit, registry first-publish, signed referenceable customers, on-call staffing + status page, launch assets) — tracked in the [GA readiness checklist](docs/ga/ga-readiness-checklist.md). Post-GA: cut the **v1.0.1** patch tag (serve-path fix below; note: GitHub Actions runs are currently blocked by an account **billing/spending-limit** failure — every `docker.yml` run since GA failed at job start, so the GHCR image was never actually published), then the V1.1 backlog. | +| **Next action** | **🎉 GA reached.** Engineering scope (Phases 0–7) complete; `v1.0.0` cut. Remaining items are external/process (external pentest, SOC 2 audit, registry first-publish, signed referenceable customers, on-call staffing + status page, launch assets) — tracked in the [GA readiness checklist](docs/ga/ga-readiness-checklist.md). Post-GA: cut the **v1.0.1** patch tag (serve-path + PyPI lockstep-publishing fixes below; note: GitHub Actions runs are currently blocked by an account **billing/spending-limit** failure — every `docker.yml` run since GA failed at job start, so the GHCR image was never actually published; also **3 PyPI name collisions** — `rag-agent`/`rag-reranker`/`rag-retrieval` are owned by unrelated third-party projects, so rename those dists *before* the first publish — see the [registry item](docs/ga/ga-readiness-checklist.md#distribution)), then the V1.1 backlog. | **Recently shipped** -- **v1.0.1** ✅ *(patch)* — **production serve path fixed end-to-end.** The image's default CMD (a Phase-0 placeholder that printed the version and exited) now serves via the new config-driven **`rag_gateway.serve:create_app`** uvicorn-factory entrypoint: `RAG_CONFIG_PATH` set → `build_app_from_config(load(path))`, unset → noop `build_app()`, set-but-broken → **fail fast** (`ConfigError`), never a silent noop fallback. The image **build** itself was also broken — the full `uv sync` needs every workspace member on disk but `sdks/python` was never copied (`Distribution not found`); both stages now copy it. New public **`GET /readyz`** backs the Helm chart's readiness probe (liveness stays `/healthz`). The chart's ConfigMap previously rendered an *invalid* `rag.yaml` (`env:/log_level:/service:` against the strict `extra='forbid'` schema → guaranteed CrashLoop); it now renders a minimal valid document with a **`config.ragYaml`** passthrough for full platform configs (`${VAR}` env interpolation keeps secrets out of the ConfigMap), chart `0.2.0` / `appVersion` `1.0.1` (the old `0.1.0` appVersion pointed the default image tag at a tag that never existed), `values.dev.yaml` `env: development` → `local`. Docs: image tags are published *without* the `v` prefix — `:v1.0.0`-style pulls in README/release-notes never matched. [release notes](docs/release-notes/v1.0.1.md) [#185](https://github.com/officialCodeWork/AgentContextOS/pull/185) +- **v1.0.1** ✅ *(patch)* — **production serve path fixed end-to-end.** The image's default CMD (a Phase-0 placeholder that printed the version and exited) now serves via the new config-driven **`rag_gateway.serve:create_app`** uvicorn-factory entrypoint: `RAG_CONFIG_PATH` set → `build_app_from_config(load(path))`, unset → noop `build_app()`, set-but-broken → **fail fast** (`ConfigError`), never a silent noop fallback. The image **build** itself was also broken — the full `uv sync` needs every workspace member on disk but `sdks/python` was never copied (`Distribution not found`); both stages now copy it. New public **`GET /readyz`** backs the Helm chart's readiness probe (liveness stays `/healthz`). The chart's ConfigMap previously rendered an *invalid* `rag.yaml` (`env:/log_level:/service:` against the strict `extra='forbid'` schema → guaranteed CrashLoop); it now renders a minimal valid document with a **`config.ragYaml`** passthrough for full platform configs (`${VAR}` env interpolation keeps secrets out of the ConfigMap), chart `0.2.0` / `appVersion` `1.0.1` (the old `0.1.0` appVersion pointed the default image tag at a tag that never existed), `values.dev.yaml` `env: development` → `local`. Docs: image tags are published *without* the `v` prefix — `:v1.0.0`-style pulls in README/release-notes never matched. **One reported version**: `rag_gateway.__version__` (0.7.0), the OpenAPI `info.version` (0.10.0), and `GET /v1/info` (0.9.0) had each hard-coded a different stale number — all now read the `rag-gateway` package version, single-sourced in `apps/gateway/pyproject.toml` (**1.0.1**, matching the platform release) via `importlib.metadata` (`rag_gateway._version`); `dist/openapi.*` + REST reference regenerated; `rag-platform` meta → `1.0.1` (its `rag-gateway==1.0.0` pin pointed at a version that never existed); a gateway test pins every surface to the package metadata. **PyPI channel actually publishes** ([ADR-0053](docs/adr/ADR-0053-lockstep-component-publishing.md)): `release.yml` only ever built the meta + SDK — none of the 16 pinned component dists were published, one pin named a dist that doesn't exist (`ragctl`; the workspace dist is `rag-ragctl`), 15 transitive components were unpinned, the `[backends]`/`[kms]` extras referenced extras `rag-backends` never declared, the metadata-only meta wheel didn't even build (hatchling needs `bypass-selection`), and workspace versions ranged 0.1.0–0.26.0 — so `pip install rag-platform` could **never resolve**. Now: **one lockstep platform version stamped from the tag** — `scripts/stamp_versions.py` rewrites every version site (member pyprojects + literal `__version__`s + the meta and all its `==` pins; `task version:stamp`), `release.yml` stamps then publishes the **complete closure (33 dists)** via `uv build --all-packages` + Trusted Publishing, npm (`npm version`) + Helm (`--version/--app-version`, chart version = platform version) stamp natively in the same run; the meta pins all **31** components exactly; `tests/packaging/test_meta_package.py` gates lockstep + closure-completeness + extras-validity; vestigial **release-please removed** (2/32 members, manifest frozen at 0.2.0, `core-v*` tags matched no workflow — the tag is the only version authority). Verified end-to-end: all 33 dists build and `pip install rag-platform==1.0.1` resolves + imports + runs `ragctl` from them. [release notes](docs/release-notes/v1.0.1.md) [#185](https://github.com/officialCodeWork/AgentContextOS/pull/185) [#186](https://github.com/officialCodeWork/AgentContextOS/pull/186) - **7.10** ✅ **GA cutover — v1.0.0** 🎉 — the close of an 8-phase, 84-step build. Cut **`v1.0.0`** with **Semantic Versioning** over the drift-gated public contracts (REST/OpenAPI · gRPC proto · `rag.yaml` · SDKs · `ragctl`) + a deprecation policy ([ADR-0052](docs/adr/ADR-0052-ga-cutover.md)); the `rag-platform` meta bumped to 1.0.0. GA **release notes** ([v1.0.0](docs/release-notes/v1.0.0.md)) + a **GA readiness checklist** ([ga-readiness-checklist](docs/ga/ga-readiness-checklist.md)) that maps every Phase 7 exit gate to a CI gate / in-repo artifact, with inherently-external items (external pentest, SOC 2 audit, registry first-publish, signed customers, on-call staffing, launch assets) marked **(external)** — the same in-repo-machine vs external-deliverable split used across Phase 7. The `v1.0.0` tag fans out to every channel via `docker.yml` + `release.yml` + `release-airgap.yml`. - **7.9** ✅ Billing & metering — per-tenant usage accounting, **mirroring the 5.6c cost pattern** (dataclasses in `rag-observability`, the gateway wraps a Pydantic response → **no `dist/schemas` churn**). New `rag_observability.billing`: a `UsageMeter` (observe-only per-tenant, per-dimension counters: queries / docs / storage / reranker / LLM tokens) fed O(1) from `record_request_usage` independent of quotas; `GET /v1/billing/usage` serves the per-tenant dashboard; pure `generate_invoice` + `PricingModel`/`load_pricing` price an invoice **from `marketplace/pricing.yaml`** (a price change is config) and **reconcile with metered usage ±0.5% by construction**; a `BillingProvider` Protocol seam for Stripe / marketplace metering (degrade-open). Inert by default (`cfg.billing`); `ragctl billing` drives meter→invoice→reconcile; **no governed SPI call** (policy-coverage linter unchanged); only `dist/openapi` + `dist/rag.schema` regenerate. Deferred: the concrete Stripe/marketplace adapters, the docs/reranker/storage feed points, an admin usage card. [ADR-0051](docs/adr/ADR-0051-billing-metering.md) [#182](https://github.com/officialCodeWork/AgentContextOS/pull/182) - **7.8** ✅ Support, SLAs & on-call — the support model + ops runbooks, **grounded in the platform's own signals**. Four support tiers + per-tier SLA targets (matching `marketplace/pricing.yaml`) in [`support-sla.md`](docs/guides/support-sla.md); a new `docs/runbooks/` area with **one runbook per alert type** (`alerts.md` — acl/tenant escape · `breaker.opened` · `drift.detected` · cost anomaly · `quota.exceeded` · injection spike · gateway degraded · latency/availability SLO · `eval.regression` · ingest), each naming the exact event / `/v1/status/*` / SLO that raises it; an incident-response process + a blameless postmortem template; the status page reads **measured** health (`/v1/status/health` + Grafana SLOs), not manual toggles. **Paging reuses the Step 3.9 webhook system** (PagerDuty as a subscriber — no new code). Deferred: hosted status-page deploy, the PagerDuty account, staffing. [ADR-0050](docs/adr/ADR-0050-support-sla-oncall.md) [#181](https://github.com/officialCodeWork/AgentContextOS/pull/181) @@ -1064,6 +1064,7 @@ Complete log of every PR. Routine Dependabot bumps are grouped; everything else | [#183](https://github.com/officialCodeWork/AgentContextOS/pull/183) | 2026-06-10 | chore(release): GA cutover — v1.0.0 release notes + readiness checklist + SemVer policy (Step 7.10) | | [#184](https://github.com/officialCodeWork/AgentContextOS/pull/184) | 2026-06-10 | docs: GA polish — site publishing scope, HLD v1.2, ragctl reference, port + link fixes | | [#185](https://github.com/officialCodeWork/AgentContextOS/pull/185) | 2026-06-10 | fix(gateway): v1.0.1 — container/Helm serve path: config-driven entrypoint + /readyz + valid chart config | +| [#186](https://github.com/officialCodeWork/AgentContextOS/pull/186) | 2026-06-10 | fix(release): v1.0.1 — lockstep component publishing: stamp the tag version onto every dist, publish the complete closure (ADR-0053) | | #78–#80, #116–#118 | Open | Dependabot bumps — awaiting merge | | #81 | Closed | Dependabot bump — superseded | diff --git a/Taskfile.yml b/Taskfile.yml index bc9f8bd..96fbaf6 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -276,6 +276,19 @@ tasks: cmds: - uv run pip-audit + # --------------------------------------------------------------------------- + # Release engineering (ADR-0053) — one platform version, stamped from the tag + # --------------------------------------------------------------------------- + version:stamp: + desc: "Stamp the platform version onto every dist (usage: task version:stamp -- 1.0.2)" + cmds: + - "{{.PYTHON}} scripts/stamp_versions.py {{.CLI_ARGS}}" + + version:check: + desc: Verify every version site agrees on one platform version (lockstep gate) + cmds: + - "{{.PYTHON}} scripts/stamp_versions.py --check" + # --------------------------------------------------------------------------- # IaC — Terraform + Helm # --------------------------------------------------------------------------- diff --git a/apps/gateway/pyproject.toml b/apps/gateway/pyproject.toml index cc98735..1661657 100644 --- a/apps/gateway/pyproject.toml +++ b/apps/gateway/pyproject.toml @@ -4,8 +4,8 @@ build-backend = "hatchling.build" [project] name = "rag-gateway" -version = "0.10.0" -description = "AgentContextOS — HTTP/gRPC/MCP API gateway (Step 4.4: per-backend circuit breakers)" +version = "1.0.1" +description = "AgentContextOS — REST/gRPC/MCP/OpenAI-compatible API gateway" readme = "README.md" requires-python = ">=3.12" dependencies = [ diff --git a/apps/gateway/src/rag_gateway/__init__.py b/apps/gateway/src/rag_gateway/__init__.py index b1a2da4..b1db206 100644 --- a/apps/gateway/src/rag_gateway/__init__.py +++ b/apps/gateway/src/rag_gateway/__init__.py @@ -16,6 +16,7 @@ for the design. """ +from rag_gateway._version import __version__ from rag_gateway.app import ( app, build_app, @@ -28,9 +29,8 @@ ) from rag_gateway.mcp import build_mcp_server -__version__ = "0.7.0" - __all__ = [ + "__version__", "app", "build_app", "build_default_embedder", diff --git a/apps/gateway/src/rag_gateway/_version.py b/apps/gateway/src/rag_gateway/_version.py new file mode 100644 index 0000000..9c0ee54 --- /dev/null +++ b/apps/gateway/src/rag_gateway/_version.py @@ -0,0 +1,21 @@ +"""Single source of truth for the gateway's reported version. + +The version is declared once, in ``apps/gateway/pyproject.toml``, and read +back here from the installed distribution metadata. Every surface that +reports a version imports this constant — ``rag_gateway.__version__``, the +FastAPI ``app.version`` (which becomes OpenAPI ``info.version`` in +``dist/openapi.*`` and the generated REST reference), and ``GET /v1/info`` — +so they cannot disagree. It tracks the platform release (SemVer, +[ADR-0052](../../../../docs/adr/ADR-0052-ga-cutover.md)): bump +``pyproject.toml``, ``uv sync``, then regenerate the drift-gated artifacts +(``task openapi:gen`` + ``task docs:api``). +""" + +from __future__ import annotations + +from importlib.metadata import PackageNotFoundError, version + +try: + __version__ = version("rag-gateway") +except PackageNotFoundError: # pragma: no cover - source tree without an installed dist + __version__ = "0.0.0+unknown" diff --git a/apps/gateway/src/rag_gateway/app.py b/apps/gateway/src/rag_gateway/app.py index 6d7a18f..23e7ee0 100644 --- a/apps/gateway/src/rag_gateway/app.py +++ b/apps/gateway/src/rag_gateway/app.py @@ -116,6 +116,7 @@ ) from rag_webhooks import build_default_dispatcher, ingest_completed_event +from rag_gateway._version import __version__ from rag_gateway.agent import build_default_agent_loop, make_agent_router from rag_gateway.audit import make_audit_router from rag_gateway.compliance import make_compliance_router @@ -460,7 +461,7 @@ def build_app( """ app = FastAPI( title="AgentContextOS Gateway", - version="0.10.0", + version=__version__, description=( "RAG gateway. Native routes for ingest, query, retrieve, and " "corpus discovery, plus OpenAI-compatible /v1/embeddings and " @@ -861,7 +862,7 @@ async def readyz() -> dict[str, str]: async def info() -> dict[str, Any]: return { "service": "rag-gateway", - "version": "0.9.0", + "version": __version__, "endpoints": [ "POST /v1/ingest/document", "POST /v1/query", diff --git a/apps/gateway/tests/test_status.py b/apps/gateway/tests/test_status.py index bd7579f..9116eee 100644 --- a/apps/gateway/tests/test_status.py +++ b/apps/gateway/tests/test_status.py @@ -3,10 +3,11 @@ from __future__ import annotations import logging +from importlib.metadata import version as dist_version from fastapi.testclient import TestClient from rag_core.types import TenantId -from rag_gateway import build_app +from rag_gateway import __version__, build_app from rag_gateway.status import ConnectorStatusView, InMemoryConnectorStatusStore from rag_observability.logbuffer import get_log_tail @@ -205,7 +206,17 @@ def test_cors_can_be_disabled() -> None: # --------------------------------------------------------------------------- def test_info_lists_status_endpoints() -> None: body = _client().get("/v1/info").json() - assert body["version"] == "0.9.0" + assert body["version"] == __version__ joined = " ".join(body["endpoints"]) assert "/v1/status/health" in joined assert "/v1/status/ws" in joined + + +def test_version_is_single_sourced() -> None: + """Every surface quotes the installed ``rag-gateway`` dist version: + ``rag_gateway.__version__``, ``app.version`` (→ OpenAPI ``info.version`` + → ``dist/openapi.*``), and ``GET /v1/info``.""" + assert __version__ == dist_version("rag-gateway") + app = build_app() + assert app.version == __version__ + assert app.openapi()["info"]["version"] == __version__ diff --git a/dist/openapi.json b/dist/openapi.json index e9b9437..6e761cd 100644 --- a/dist/openapi.json +++ b/dist/openapi.json @@ -4862,7 +4862,7 @@ "info": { "description": "RAG gateway. Native routes for ingest, query, retrieve, and corpus discovery, plus OpenAI-compatible /v1/embeddings and /v1/chat/completions (with retrieval pre-fetch). Operator status surface at /v1/status/* (health, metrics, logs tail + SSE/WS). OpenAPI 3.1 at /openapi.json; Swagger UI at /docs.", "title": "AgentContextOS Gateway", - "version": "0.10.0" + "version": "1.0.1" }, "openapi": "3.1.0", "paths": { diff --git a/dist/openapi.yaml b/dist/openapi.yaml index 9e152cc..80088c2 100644 --- a/dist/openapi.yaml +++ b/dist/openapi.yaml @@ -4247,7 +4247,7 @@ info: retrieval pre-fetch). Operator status surface at /v1/status/* (health, metrics, logs tail + SSE/WS). OpenAPI 3.1 at /openapi.json; Swagger UI at /docs. title: AgentContextOS Gateway - version: 0.10.0 + version: 1.0.1 openapi: 3.1.0 paths: /healthz: diff --git a/docs/README.md b/docs/README.md index 3e9d076..add1114 100644 --- a/docs/README.md +++ b/docs/README.md @@ -135,7 +135,7 @@ | [design-partner-pilots.md](guides/design-partner-pilots.md) | Design-partner pilot runbook (Step 7.4): the pilot lifecycle (qualify → onboard → run → review → graduate); roles; onboarding as a configured deployment; **signed success criteria** (quality/latency/integration/security) each tied to a platform signal; the **weekly KPI** dashboard pulled from `GET /v1/status/{metrics,feedback,drift,cost,health}` + the eval harness (assembled by `ragctl pilot report`); the intake → triage → incorporate → close feedback loop; acceptance (≥ 3 consecutive green weeks · 3 referenceable tenants) + the case study; the in-repo-machine vs external-GTM split | | [documentation-site.md](guides/documentation-site.md) | The documentation site (Step 7.5): the Docusaurus app under `website/` that serves `docs/` in place; running/building it; the generated REST API reference; the CI gates (API-ref drift · quickstart doc-tests · spell-check · `lychee` link-check · site build); adding docs | | [marketplace-listings.md](guides/marketplace-listings.md) | Cloud marketplace listings (Step 7.6): what's in-repo (`marketplace/` — one canonical `pricing.yaml` + shared listing copy + per-cloud AWS/Azure/GCP specs) vs the external approval/procurement process; reusing the Helm/AMI/airgap/GHCR delivery; the submission checklists + the procurement acceptance test | -| [packaging-distribution.md](guides/packaging-distribution.md) | Packaging & distribution (Step 7.7): the one-command install per channel (PyPI `rag-platform`, npm `@agentcontextos/sdk`, GHCR images, Helm OCI, air-gap); how one `vX.Y.Z` tag fans out across `docker.yml` + `release.yml` + `release-airgap.yml`; cosign-keyless + SPDX SBOM + OIDC/provenance signing; verification commands | +| [packaging-distribution.md](guides/packaging-distribution.md) | Packaging & distribution (Step 7.7, publishing fixed in v1.0.1): the one-command install per channel (PyPI `rag-platform`, npm `@agentcontextos/sdk`, GHCR images, Helm OCI, air-gap); how one `vX.Y.Z` tag fans out across `docker.yml` + `release.yml` + `release-airgap.yml` and stamps the platform version onto every dist (ADR-0053); the cutting-a-release checklist; cosign-keyless + SPDX SBOM + OIDC/provenance signing; verification commands | | [support-sla.md](guides/support-sla.md) | Support, SLAs & on-call (Step 7.8): the four support tiers + response targets; SLA targets per tier (matching `marketplace/pricing.yaml`); the follow-the-sun on-call + escalation; wiring platform alerts to **PagerDuty** via the Step 3.9 webhook system (no new code) | | [curl-quickstart.md](guides/curl-quickstart.md) | 🥈 Curl-able RAG (Step 3.1): 5-minute walkthrough from `curl` to gateway response, including ingest, query, generate, OpenAPI | | [grpcurl-quickstart.md](guides/grpcurl-quickstart.md) | gRPC quickstart (Step 3.2): 5-minute walkthrough using `grpcurl` against the in-process server — health check, list corpora, server-streaming query, structured errors | @@ -206,6 +206,7 @@ broken, and what to fix before committing to the next phase. | [ADR-0049-packaging-distribution.md](adr/ADR-0049-packaging-distribution.md) | Decision (Step 7.7): a `rag-platform` PyPI **meta-package** pins the workspace component dists (one-command server install); keep the existing `agentcontextos` SDK scope (no rename); **one `vX.Y.Z` tag fans out** to PyPI/npm/GHCR/Helm-OCI/air-gap across `docker.yml` + a new `release.yml` + `release-airgap.yml`; cosign-keyless + SPDX SBOM + OIDC/provenance everywhere; deferred Go/Java/.NET publish + worker/eval-runner images; rejected a `ragplatform` rename + one mega-workflow | | [ADR-0050-support-sla-oncall.md](adr/ADR-0050-support-sla-oncall.md) | Decision (Step 7.8): **runbooks grounded in the platform's own signals** — one per alert type, each naming the exact event / `/v1/status/*` / SLO that raises it; **paging reuses the Step 3.9 webhook system** (PagerDuty as a subscriber, no new code) + Grafana SLOs; the status page reflects **measured** health (not manual toggles); SLA tiers match `marketplace/pricing.yaml`; rejected a new alerting subsystem, generic runbooks, a separate SLA datastore | | [ADR-0051-billing-metering.md](adr/ADR-0051-billing-metering.md) | Decision (Step 7.9): **mirror the 5.6c cost pattern** — dataclasses in `rag-observability`, gateway wraps in a Pydantic response (**no `dist/schemas` churn**); metering is **observe-only** (no governed SPI call, fed from `record_request_usage` independent of quotas); invoicing is offline + pure + **priced from config** (`marketplace/pricing.yaml`, reconciles ±0.5% by construction); Stripe/marketplace via a `BillingProvider` Protocol seam; rejected a new `rag-billing` package + core types, metering-through-quotas, hard-coded prices | +| [ADR-0053-lockstep-component-publishing.md](adr/ADR-0053-lockstep-component-publishing.md) | Decision (v1.0.1, post-GA): the release tag is the **only version authority** — `scripts/stamp_versions.py` stamps one platform version onto every workspace dist + the `rag-platform` meta before `release.yml` builds and publishes the **complete component closure** (33 dists, Trusted Publishing); the meta pins all 31 components exactly (was 16, incl. a dist name that didn't exist + ghost extras → `pip install rag-platform` could never resolve); lockstep + closure-completeness are `tests/packaging/` CI gates; release-please retired (covered 2/32 members, stale manifest, tags no workflow matched); rejected per-component versions, vendoring a mega-dist, git-derived dynamic versions | | [ADR-0052-ga-cutover.md](adr/ADR-0052-ga-cutover.md) | Decision (Step 7.10, GA): cut **v1.0.0** with **SemVer** over the drift-gated public contracts (REST/OpenAPI · gRPC proto · `rag.yaml` · SDKs · `ragctl`) + a deprecation policy (≥ 1 MINOR before removal); the GA bar is a **checklist of gates**, not a declaration, with inherently-external items marked **(external)**; one platform version cut as a tag that fans out to every channel; rejected staying 0.x, no platform version, declaring GA without a checklist | | [ADR-0048-marketplace-listings.md](adr/ADR-0048-marketplace-listings.md) | Decision (Step 7.6): one canonical `marketplace/pricing.yaml` (metered dims = the Step 7.9 signals) + one shared listing copy mapped to all three clouds, so listings can't drift and prices reconcile with metering; **reuse existing delivery** (Helm / AMI / airgap / GHCR) — the per-cloud Marketplace wrappers are thin shells; approval + procurement are documented external process, not a faked status; rejected per-cloud pricing, custom packaging, encoding a "live" status | | [ADR-0042-compliance-posture.md](adr/ADR-0042-compliance-posture.md) | Decision (Step 6.10, Phase-6 capstone): add the three compliance pieces on top of the controls the platform already ships (audit/ACL/PII/BYOK/SSO/quotas). New `rag-compliance` package (config-free, like rag-feedback/rag-drift): `RetentionEnforcer` drives tenant-scoped `purge_*`; `compliance_posture`/`residency_ok` are pure. **Retention is a capability on the existing stores, not a new SPI** — non-abstract `purge_before`/`purge_tenant` (default no-op) on Feedback/Provenance, with `dry_run` in the SPI so a preview counts-without-deleting uniformly (ProvenanceStore has no `list`). **Audit is never purged in place** (the hash chain would break) — audit retention is the 6.6b WORM export; `audit_days` is advisory. **Right-to-erasure is always-on, tenant-self-service, two-flag** — `POST /v1/compliance/erase` erases the *calling* tenant's data (scope from the principal, never the body), dry-run by default, delete needs `dry_run=false` AND `confirm=true`. **Residency = declared per tenant + enforced at ingest** (`tenants[].data_region` vs `cfg.compliance.region` → 403), opt-in, a single-deployment assertion not multi-region routing. **The SOC 2 / GDPR mapping is a doc backed by a live posture** (`GET /v1/status/compliance` reports which controls are on, so the mapping is checkable). Deferred: subject-level (vs tenant-level) erasure, an admin retention-sweep endpoint, multi-region routing, automated audit-evidence bundles; rejected purging the audit chain, a `Purgeable` SPI mixin, a static doc with no live backing | diff --git a/docs/adr/ADR-0049-packaging-distribution.md b/docs/adr/ADR-0049-packaging-distribution.md index 023bbeb..ba0e723 100644 --- a/docs/adr/ADR-0049-packaging-distribution.md +++ b/docs/adr/ADR-0049-packaging-distribution.md @@ -4,6 +4,7 @@ **Date:** 2026-06-10 **Step:** 7.7 — Packaging & distribution (Phase 7 — Pilot, Harden, GA) **Related:** [guides/packaging-distribution.md](../guides/packaging-distribution.md), [packaging/](../../packaging/README.md), [3.7 SDK generation](ADR-0016-sdk-generation.md), [6.9 air-gap bundle](ADR-0041-airgap-bundle.md), [7.6 marketplace listings](ADR-0048-marketplace-listings.md), [planning/phases/phase-7-pilot-ga.md](../../planning/phases/phase-7-pilot-ga.md) +**Refined by:** [ADR-0053](ADR-0053-lockstep-component-publishing.md) — v1.0.1 makes the component publish real (release.yml builds + publishes the complete closure, version-stamped from the tag) ## Context diff --git a/docs/adr/ADR-0052-ga-cutover.md b/docs/adr/ADR-0052-ga-cutover.md index 6f327bd..6459b23 100644 --- a/docs/adr/ADR-0052-ga-cutover.md +++ b/docs/adr/ADR-0052-ga-cutover.md @@ -4,6 +4,7 @@ **Date:** 2026-06-10 **Step:** 7.10 — GA cutover (Phase 7 — Pilot, Harden, GA) **Related:** [release-notes/v1.0.0.md](../release-notes/v1.0.0.md), [ga/ga-readiness-checklist.md](https://github.com/officialCodeWork/AgentContextOS/blob/main/docs/ga/ga-readiness-checklist.md), [7.7 packaging](ADR-0049-packaging-distribution.md), [planning/phases/phase-7-pilot-ga.md](../../planning/phases/phase-7-pilot-ga.md) +**Refined by:** [ADR-0053](ADR-0053-lockstep-component-publishing.md) — components version *with* the platform (lockstep, tag-stamped), not "under it via release-please" ## Context diff --git a/docs/adr/ADR-0053-lockstep-component-publishing.md b/docs/adr/ADR-0053-lockstep-component-publishing.md new file mode 100644 index 0000000..cbe6ef6 --- /dev/null +++ b/docs/adr/ADR-0053-lockstep-component-publishing.md @@ -0,0 +1,109 @@ +# ADR-0053 — Lockstep component publishing: the release tag stamps one platform version onto every dist + +**Status:** Accepted +**Date:** 2026-06-10 +**Step:** v1.0.1 patch (post-GA) +**Related:** [7.7 packaging](ADR-0049-packaging-distribution.md), [7.10 GA cutover](ADR-0052-ga-cutover.md), [guides/packaging-distribution.md](../guides/packaging-distribution.md), [release-notes/v1.0.1.md](../release-notes/v1.0.1.md) + +## Context + +ADR-0049 made `rag-platform` the PyPI meta-distribution, pinning the workspace +component dists "published from the uv workspace on the same release tag" — but +nothing published them. `release.yml`'s PyPI job built only the meta and the +Python SDK, so every `rag-*==1.0.0` pin pointed at a distribution that would +never exist, and `pip install rag-platform` could not resolve. On inspection the +gap ran deeper than the missing build step: + +- The meta pinned **16 of the 31** workspace components — the gateway's other + transitive members (`rag-parsers`, `rag-query`, `rag-cache`, …) would have + floated unpinned even if publishing worked. +- One pin named a dist that does not exist (`ragctl`; the workspace dist is + **`rag-ragctl`**). +- The extras referenced extras `rag-backends` never declared + (`pgvector`/`qdrant`/`redis`/`s3`/`kms-aws` are *base* dependencies), so + `rag-platform[backends]` would have silently installed nothing extra. +- The meta wheel itself did not build: it is metadata-only, and hatchling + refuses a file-less wheel without `bypass-selection`. +- Workspace versions were unrelated (0.1.0–0.26.0 across pyprojects, plus three + *different* hard-coded gateway version strings), so even publishing as-is + could not satisfy `==1.0.0`. +- release-please was configured for **2 of 32** members, its manifest was frozen + at 0.2.0 while those pyprojects said 0.26.0/0.10.0, and its component tags + (`core-v*`) match no release workflow's `v*.*.*` trigger — it was not the + versioning mechanism in practice; hand-cut platform tags were. + +## Decision + +**1. One lockstep version, stamped from the tag.** The platform tag `vX.Y.Z` +(ADR-0052 §4) is the *only* version authority. `scripts/stamp_versions.py` +rewrites every version site to one value: each member's `[project] version`, +each literal `__version__` attribute, and the meta's own version + every +`rag-*==` pin. `release.yml` runs it with the tag-derived version before +building; npm (`npm version`) and Helm (`--version`/`--app-version` at package +time) stamp their artifacts natively in the same run. The in-repo versions are +the *baseline* (kept at the last platform release) — the CI stamp makes the tag +win regardless. + +**2. `release.yml` publishes the complete closure.** The PyPI job builds every +workspace member (`uv build --all-packages`) plus the meta — 33 dists per +release (31 components, the `agentcontextos` SDK, `rag-platform`) — and +publishes them all via OIDC Trusted Publishing. The meta's pins therefore +resolve against component dists published from the very same run. + +**3. The meta pins the complete component closure, exactly.** All 31 components +(every workspace dist except the client SDK), by real dist name, at `==X.Y.Z` — +nothing left to float through a transitive `>=`. Its extras now reference +extras `rag-backends` actually declares. + +**4. The invariants are CI gates, not conventions.** +`tests/packaging/test_meta_package.py` fails the build when any version site +drifts from lockstep (a hand-bumped single package cannot merge), when the +meta's pin set differs from the workspace dist set (a new package cannot ship +unpinned; a renamed one cannot leave a dangling pin), or when an extras pin +names a ghost extra. + +**5. release-please is retired.** Per-component versioning contradicts the +one-platform-version contract and its config was vestigial. Changelogs live in +`docs/release-notes/` (already the practice); the tag is cut by hand, as it was +for GA. This refines ADR-0052's parenthetical "components still version under +it via release-please": components version *with* it, in lockstep. + +## Consequences + +- `pip install rag-platform==X` resolves a fully-reproducible stack — verified + end-to-end by building all 33 dists and installing the meta from them + (imports + `ragctl` run at the stamped version). +- Cutting a release is: stamp locally (`task version:stamp -- X.Y.Z`), `uv lock`, + regenerate `dist/openapi.*` + the REST reference, commit, tag. CI re-stamps + from the tag, so a missed local step changes published artifacts, not their + correctness. +- PyPI Trusted Publishing must be registered for **all 33 dists** (pending + publishers on first release) — the GA checklist's external registry item now + says so explicitly. +- Three intended names are already owned by unrelated PyPI projects — + `rag-agent`, `rag-reranker`, `rag-retrieval` (verified 2026-06-10) — so those + dists must be renamed before the first publish; the GA checklist's registry + item records the verified-free candidates. Dist names are decoupled from + import roots, so a rename touches only the pyproject `name` + the meta pins. +- Adding a workspace package fails `tests/packaging` until it is pinned in the + meta (or consciously excluded via `META_EXCLUDED_DISTS`). +- `rag-gateway` keeps deriving `__version__` from dist metadata (one + declaration site); other components keep literal `__version__` attributes, + which the stamp rewrites and the gate keeps honest. + +## Alternatives considered + +- **Fix release-please instead (per-component versions, linked or independent).** + Rejected — ADR-0052 already rejected per-component SemVer as the user-facing + story; a 32-package bump-PR matrix adds release friction with zero consumers + who need independently-versioned components, and the platform tag would still + be the thing every other channel keys off. +- **Restructure `rag-platform` to vendor the code into one mega-dist.** + Rejected — it kills per-component installs (`pip install rag-core` for SPI + authors), contradicts ADR-0049's "components publish underneath the meta", + and forks the packaging story away from the Docker/air-gap builds that + consume the workspace directly. +- **Dynamic versioning from git (hatch-vcs / setuptools-scm).** Rejected — + every build then needs git history (air-gap and sdist rebuilds break), all 32 + build configs churn, and the version becomes invisible in review; one stdlib + script plus a test gate is smaller and auditable. diff --git a/docs/ga/ga-readiness-checklist.md b/docs/ga/ga-readiness-checklist.md index a4f2897..175ed57 100644 --- a/docs/ga/ga-readiness-checklist.md +++ b/docs/ga/ga-readiness-checklist.md @@ -30,7 +30,8 @@ how the platform handled the pentest (7.3) and design-partner sign-ups (7.4). - [x] **Packaging** — `rag-platform` PyPI meta, SDKs, GHCR images, Helm OCI, air-gap bundle (Step 7.7) - [x] **Signed + SBOM-attested** — cosign keyless + SPDX + OIDC/npm provenance (Step 7.7) -- [ ] **First publish to each registry** — **(external)** one-time trusted-publisher / GHCR setup, then `git push v1.0.0` +- [ ] **First publish to each registry** — **(external)** one-time trusted-publisher / GHCR setup, then push the release tag. PyPI Trusted Publishing must be registered (pending publishers) for **all 33 dists** `release.yml` now publishes — the 31 workspace components + `rag-platform` + `agentcontextos` (ADR-0053) — plus npm for `@agentcontextos/sdk` + - ⚠️ **Blocker — 3 PyPI name collisions (verified 2026-06-10):** `rag-agent`, `rag-reranker`, and `rag-retrieval` are already owned by unrelated third-party projects (active releases 2024–2026, so a PEP 541 reclaim is unrealistic). The meta's `==X.Y.Z` pins on those names can never resolve from PyPI, and pinning a name someone else owns is a dependency-confusion risk. **Rename the three dists before pushing the first release tag** — the publish is not atomic, so tagging first would publish ~30 dists, fail 3, and leave the meta unresolvable. The other 30 names were verified free. Verified-free candidates: `agentcontextos-agent` / `agentcontextos-reranker` / `agentcontextos-retrieval` (coherent brand-prefixed set), or `rag-rerank` + `rag-agent-runtime` (`rag-retriever` is taken). A rename is mechanical: `[project] name` in the three pyprojects + the three meta pins; import roots (`rag_agent`, `rag_reranker`, `rag_retrieval`) stay as-is (precedent: dist `rag-ragctl` → `import ragctl`); `tests/packaging/test_meta_package.py` enforces the pin set follows. ## Operations diff --git a/docs/guides/packaging-distribution.md b/docs/guides/packaging-distribution.md index 8a0839e..6521f3e 100644 --- a/docs/guides/packaging-distribution.md +++ b/docs/guides/packaging-distribution.md @@ -25,8 +25,9 @@ noop-wired app otherwise. See [gateway.md — config-driven serving](../reference/gateway.md#config-driven-serving). The [`rag-platform`](../../packaging/rag-platform/README.md) PyPI meta-package pins -the workspace component distributions, so `pip install rag-platform==X` resolves a -reproducible server stack. SDKs live under [`sdks/`](../../sdks). +the **complete** workspace component closure (all 31 component dists, exactly, at +the platform version), so `pip install rag-platform==X` resolves a reproducible +server stack with nothing left to float. SDKs live under [`sdks/`](../../sdks). ## One tag → every channel @@ -35,7 +36,7 @@ Pushing a `vX.Y.Z` tag fans out across three tag-triggered workflows: | Workflow | Publishes | |----------|-----------| | `docker.yml` | gateway image → GHCR (cosign keyless + SPDX SBOM) | -| `release.yml` | PyPI (`rag-platform` + `agentcontextos`, OIDC Trusted Publishing) · npm (`@agentcontextos/sdk`, provenance) · admin-ui image (cosign + SBOM) · Helm chart → OCI (cosign) | +| `release.yml` | PyPI (**every workspace component** + `rag-platform` + `agentcontextos` — 33 dists, OIDC Trusted Publishing) · npm (`@agentcontextos/sdk`, provenance) · admin-ui image (cosign + SBOM) · Helm chart → OCI (cosign) | | `release-airgap.yml` | signed offline bundle → GitHub Release asset | ```bash @@ -43,6 +44,32 @@ git tag v1.0.0 git push origin v1.0.0 # → all three workflows run ``` +## One platform version, stamped from the tag + +The tag is the version authority ([ADR-0053](../adr/ADR-0053-lockstep-component-publishing.md)): +every artifact a tag produces carries the same `X.Y.Z`. In `release.yml`, +`scripts/stamp_versions.py` rewrites every Python version site (each workspace +member's `[project] version` + literal `__version__`, the meta's version and +all of its `==` pins) before `uv build --all-packages` builds them; npm stamps +the TypeScript SDK (`npm version`) and Helm stamps the chart +(`--version`/`--app-version` at package time) in the same run. The in-repo +versions are the lockstep *baseline* (the last platform release) — gated by +`tests/packaging/test_meta_package.py`, so a hand-bumped single package cannot +merge. + +Cutting a release: + +```bash +task version:stamp -- 1.0.2 # stamp the baseline (or scripts/stamp_versions.py) +uv lock && uv sync --all-packages +task openapi:gen && task docs:api # the gateway version is embedded in dist/openapi.* +# commit, then: +git tag v1.0.2 && git push origin v1.0.2 +``` + +CI re-stamps from the tag, so the published artifacts are correct even if a +local step is missed — the baseline just lags until the next commit. + ## Signing + SBOM - **Container images** — cosign **keyless** (GitHub OIDC), plus an SPDX SBOM per image. diff --git a/docs/reference/gateway.md b/docs/reference/gateway.md index eed3281..db09ac2 100644 --- a/docs/reference/gateway.md +++ b/docs/reference/gateway.md @@ -152,6 +152,22 @@ Interactive docs: The spec validates against OpenAPI 3.1 as of FastAPI 0.115+. +## Versioning + +The gateway reports one version everywhere: `rag_gateway.__version__`, the +FastAPI `app.version` (surfaced as `info.version` in `/openapi.json`, the +committed `dist/openapi.*`, and the generated [REST reference](rest-api.md)), +and `GET /v1/info` all quote the installed `rag-gateway` package version. It +tracks the platform release (SemVer — [ADR-0052](../adr/ADR-0052-ga-cutover.md)). + +**Internals.** `rag_gateway._version` reads the version from the installed +distribution metadata (`importlib.metadata.version("rag-gateway")`), so +`apps/gateway/pyproject.toml` is the only place it is declared. To bump it: +edit `pyproject.toml`, run `uv sync`, then regenerate the drift-gated +artifacts (`task openapi:gen` + `task docs:api`). +`apps/gateway/tests/test_status.py::test_version_is_single_sourced` pins every +surface to the package metadata so they cannot drift apart again. + ## Authentication The gateway middleware (`apps/gateway/src/rag_gateway/middleware.py`) reads: diff --git a/docs/reference/rest-api.md b/docs/reference/rest-api.md index 048e490..0b8eea3 100644 --- a/docs/reference/rest-api.md +++ b/docs/reference/rest-api.md @@ -7,7 +7,7 @@ description: Generated from the committed OpenAPI 3.1 contract. > **Generated** from `dist/openapi.json` by `scripts/gen_api_reference.py` — do not edit by hand. Regenerate with `task docs:api` (or `python scripts/gen_api_reference.py`). The spec itself is drift-gated in CI. -**AgentContextOS Gateway** · version `0.10.0` · OpenAPI 3.1 +**AgentContextOS Gateway** · version `1.0.1` · OpenAPI 3.1 ## Endpoints diff --git a/docs/release-notes/v1.0.1.md b/docs/release-notes/v1.0.1.md index 215a7b7..4a92df8 100644 --- a/docs/release-notes/v1.0.1.md +++ b/docs/release-notes/v1.0.1.md @@ -44,12 +44,45 @@ which pointed at a non-existent `0.1.0`). prefix (`1.0.1`, floating `1.0`); docs previously showed `:v1.0.0`-style tags that the release pipeline never produces. +**One reported version.** The gateway's version had drifted three ways: +`rag_gateway.__version__` said 0.7.0, the OpenAPI document (`dist/openapi.*` +and the generated REST reference) said 0.10.0, and `GET /v1/info` said 0.9.0. +The version is now declared once — in the `rag-gateway` package metadata, +bumped to **1.0.1** to match the platform release — and every surface reads it +back via `importlib.metadata` (`rag_gateway._version`); a gateway test pins +all surfaces to the package version so they cannot drift apart again. The +`rag-platform` meta-distribution is likewise `1.0.1`, and its `rag-gateway` +pin now points at a version that exists. See +[gateway.md — versioning](../reference/gateway.md#versioning). + +**`pip install rag-platform` can actually resolve** +([ADR-0053](../adr/ADR-0053-lockstep-component-publishing.md)). The meta +pinned 16 component dists at `==1.0.0`, but the release workflow never built +or published any of them — and the pins couldn't have resolved anyway: one +named a dist that doesn't exist (`ragctl`; the real dist is `rag-ragctl`), 15 +transitive components were missing entirely (they'd have floated unpinned), +the extras referenced extras `rag-backends` never declared (so +`rag-platform[backends]` silently added nothing), the meta wheel itself didn't +build (metadata-only wheels need hatchling's `bypass-selection`), and the +workspace versions ranged 0.1.0–0.26.0. Now: every workspace dist carries +**one platform version** in lockstep; `release.yml` stamps the tag version +onto all of them (`scripts/stamp_versions.py`; `npm version` for the TS SDK; +`helm package --version/--app-version` for the chart, whose published version +now equals the platform version) and publishes the complete closure — **33 +dists** per tag — via Trusted Publishing; the meta pins all 31 components +exactly. `tests/packaging/` gates lockstep, closure-completeness, and +extras-validity in CI. The vestigial release-please config (it covered 2 of +32 members, its manifest was frozen at 0.2.0, and its tags matched no +workflow) is removed: the tag is the only version authority. Verified +end-to-end: all 33 dists build, and `pip install rag-platform==1.0.1` +resolves, installs, and runs against them. + ## Install ```bash docker pull ghcr.io/officialcodework/agentcontextos/rag-gateway:1.0.1 -helm install rag oci://ghcr.io/officialcodework/agentcontextos/charts/rag-platform --version 0.2.0 -pip install rag-platform # full self-hosted server stack + ragctl +helm install rag oci://ghcr.io/officialcodework/agentcontextos/charts/rag-platform --version 1.0.1 +pip install rag-platform==1.0.1 # full self-hosted server stack + ragctl ``` ## Upgrade notes diff --git a/packages/agent/pyproject.toml b/packages/agent/pyproject.toml index bc6f46b..f4c5c63 100644 --- a/packages/agent/pyproject.toml +++ b/packages/agent/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-agent" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — production agent runtime: state-machine iterative retrieval, tool use, budget controls, resumability, event streaming (Step 3.6)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/agent/src/rag_agent/__init__.py b/packages/agent/src/rag_agent/__init__.py index 6bd5b49..d958c9f 100644 --- a/packages/agent/src/rag_agent/__init__.py +++ b/packages/agent/src/rag_agent/__init__.py @@ -38,7 +38,7 @@ ToolSpec, ) -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "AgentAction", diff --git a/packages/backends/pyproject.toml b/packages/backends/pyproject.toml index 971b3ca..fe4f712 100644 --- a/packages/backends/pyproject.toml +++ b/packages/backends/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-backends" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — real storage backend plugins (pgvector, Qdrant, Redis, S3)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/breaker/pyproject.toml b/packages/breaker/pyproject.toml index a7e215c..480ce92 100644 --- a/packages/breaker/pyproject.toml +++ b/packages/breaker/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-breaker" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — per-backend circuit breakers: closed/open/half-open failure isolation" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/cache/pyproject.toml b/packages/cache/pyproject.toml index b82c7d3..1c9eb88 100644 --- a/packages/cache/pyproject.toml +++ b/packages/cache/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-cache" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — tiered semantic cache (L0 in-memory LRU / L1 exact / L2 similarity) for the retrieval + answer caches (Step 4.1)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/cache/src/rag_cache/__init__.py b/packages/cache/src/rag_cache/__init__.py index 48d4776..1449b72 100644 --- a/packages/cache/src/rag_cache/__init__.py +++ b/packages/cache/src/rag_cache/__init__.py @@ -29,7 +29,7 @@ ) from rag_cache.tiered import TieredAnswerCache, TieredRetrievalCache, TierStats -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "InMemoryAnswerCache", diff --git a/packages/chunker/pyproject.toml b/packages/chunker/pyproject.toml index 05af42f..bb5089f 100644 --- a/packages/chunker/pyproject.toml +++ b/packages/chunker/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-chunker" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — structure-aware chunking (heading sections, parent-child links, token budgets, sentence-boundary splitting)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/chunker/src/rag_chunker/__init__.py b/packages/chunker/src/rag_chunker/__init__.py index 9b60e83..bc94ab9 100644 --- a/packages/chunker/src/rag_chunker/__init__.py +++ b/packages/chunker/src/rag_chunker/__init__.py @@ -14,7 +14,7 @@ from rag_chunker.ocr_adapter import ocr_result_to_parsed_document from rag_chunker.tokens import TiktokenCounter, TokenCounter -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "HeadingAwareChunker", diff --git a/packages/compliance/pyproject.toml b/packages/compliance/pyproject.toml index 0bd707c..4d638b8 100644 --- a/packages/compliance/pyproject.toml +++ b/packages/compliance/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-compliance" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — compliance posture: data retention, GDPR erasure/residency, SOC 2 control mapping" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/config/pyproject.toml b/packages/config/pyproject.toml index 982083b..f78290e 100644 --- a/packages/config/pyproject.toml +++ b/packages/config/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-config" -version = "0.3.0" +version = "1.0.1" description = "AgentContextOS — rag.yaml schema & loader" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/config/src/rag_config/__init__.py b/packages/config/src/rag_config/__init__.py index d8bc47a..6f7533d 100644 --- a/packages/config/src/rag_config/__init__.py +++ b/packages/config/src/rag_config/__init__.py @@ -61,7 +61,7 @@ ) from rag_config.tenancy import TenantResolver -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ # loader diff --git a/packages/core/pyproject.toml b/packages/core/pyproject.toml index 435d9cb..bac5ea7 100644 --- a/packages/core/pyproject.toml +++ b/packages/core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-core" -version = "0.26.0" +version = "1.0.1" description = "AgentContextOS — core domain types, error hierarchy, and plugin SPIs" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/core/src/rag_core/__init__.py b/packages/core/src/rag_core/__init__.py index 9c85c87..68de185 100644 --- a/packages/core/src/rag_core/__init__.py +++ b/packages/core/src/rag_core/__init__.py @@ -224,7 +224,7 @@ WriteVolume, ) -__version__ = "0.27.0" +__version__ = "1.0.1" __all__ = [ # agent runtime wire types (Step 3.6) diff --git a/packages/drift/pyproject.toml b/packages/drift/pyproject.toml index f05008a..8c46d8c 100644 --- a/packages/drift/pyproject.toml +++ b/packages/drift/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-drift" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — drift monitors (PSI + statistic) over query / embedding / retrieval / feedback signals" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/embedders/pyproject.toml b/packages/embedders/pyproject.toml index 7d0aa7b..8630355 100644 --- a/packages/embedders/pyproject.toml +++ b/packages/embedders/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-embedders" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — embedder plugins (OpenAI, Cohere, BGE, E5) with batching, retry, and dimension normalization" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/embedders/src/rag_embedders/__init__.py b/packages/embedders/src/rag_embedders/__init__.py index b0c516c..c0f6024 100644 --- a/packages/embedders/src/rag_embedders/__init__.py +++ b/packages/embedders/src/rag_embedders/__init__.py @@ -24,7 +24,7 @@ e5_large_v2, ) -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "BatchingEmbedder", diff --git a/packages/enricher/pyproject.toml b/packages/enricher/pyproject.toml index 72388bf..2655c1a 100644 --- a/packages/enricher/pyproject.toml +++ b/packages/enricher/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-enricher" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — metadata enrichment (language, doc type, dates, author, section path, reading level)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/enricher/src/rag_enricher/__init__.py b/packages/enricher/src/rag_enricher/__init__.py index 9c769d2..df07573 100644 --- a/packages/enricher/src/rag_enricher/__init__.py +++ b/packages/enricher/src/rag_enricher/__init__.py @@ -16,7 +16,7 @@ from rag_enricher.language import LangdetectDetector, LanguageDetector from rag_enricher.section_path import section_path -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "DefaultEnricher", diff --git a/packages/feedback/pyproject.toml b/packages/feedback/pyproject.toml index 3e9930d..e34cfb4 100644 --- a/packages/feedback/pyproject.toml +++ b/packages/feedback/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-feedback" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — online feedback & implicit signals (PII-redacted) with per-tenant aggregation" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/graphrag/pyproject.toml b/packages/graphrag/pyproject.toml index d5125a1..f0fcf9b 100644 --- a/packages/graphrag/pyproject.toml +++ b/packages/graphrag/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-graphrag" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — GraphRAG: community detection, sub-graph summarization, graph-aware retrieval (Step 2.9)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/graphrag/src/rag_graphrag/__init__.py b/packages/graphrag/src/rag_graphrag/__init__.py index b216a1d..f851169 100644 --- a/packages/graphrag/src/rag_graphrag/__init__.py +++ b/packages/graphrag/src/rag_graphrag/__init__.py @@ -30,7 +30,7 @@ from rag_graphrag.store import CommunityStore, InMemoryCommunityStore from rag_graphrag.summarizer import CommunitySummarizer, SummariserConfig -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "CommunityDetector", diff --git a/packages/guard/pyproject.toml b/packages/guard/pyproject.toml index 3a53b43..86d0822 100644 --- a/packages/guard/pyproject.toml +++ b/packages/guard/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-guard" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — hallucination guard: per-claim NLI faithfulness scoring of generated answers" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ingest/pyproject.toml b/packages/ingest/pyproject.toml index ac98987..cc708c4 100644 --- a/packages/ingest/pyproject.toml +++ b/packages/ingest/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-ingest" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — end-to-end ingest pipeline orchestrator (parse → chunk → enrich → PII → embed → index)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ingest/src/rag_ingest/__init__.py b/packages/ingest/src/rag_ingest/__init__.py index 91e7f4a..c9e3b92 100644 --- a/packages/ingest/src/rag_ingest/__init__.py +++ b/packages/ingest/src/rag_ingest/__init__.py @@ -9,6 +9,6 @@ from rag_ingest.pipeline import IngestPipeline, ParserSelector -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = ["IngestPipeline", "ParserSelector"] diff --git a/packages/injection/pyproject.toml b/packages/injection/pyproject.toml index 1c968b8..63d1e63 100644 --- a/packages/injection/pyproject.toml +++ b/packages/injection/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-injection" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — prompt-injection guard: detect + quarantine adversarial instructions in retrieved context before the LLM" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/observability/pyproject.toml b/packages/observability/pyproject.toml index ee9e73f..f6f9168 100644 --- a/packages/observability/pyproject.toml +++ b/packages/observability/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-observability" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — structured logging, events, and context propagation" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ocr/pyproject.toml b/packages/ocr/pyproject.toml index 6e926d1..a1d8d24 100644 --- a/packages/ocr/pyproject.toml +++ b/packages/ocr/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-ocr" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — OCR backends (Tesseract, PaddleOCR) with region-aware results" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ocr/src/rag_ocr/__init__.py b/packages/ocr/src/rag_ocr/__init__.py index 0f16f60..6650a17 100644 --- a/packages/ocr/src/rag_ocr/__init__.py +++ b/packages/ocr/src/rag_ocr/__init__.py @@ -3,6 +3,6 @@ from rag_ocr.paddle import PaddleOCRBackend from rag_ocr.tesseract import TesseractOCR -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = ["PaddleOCRBackend", "TesseractOCR"] diff --git a/packages/packer/pyproject.toml b/packages/packer/pyproject.toml index 8cdb8e5..864f434 100644 --- a/packages/packer/pyproject.toml +++ b/packages/packer/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-packer" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — context packer: dedup, reorder, token budget, conflict detection (Step 2.8)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/packer/src/rag_packer/__init__.py b/packages/packer/src/rag_packer/__init__.py index 0bf17c0..937abe5 100644 --- a/packages/packer/src/rag_packer/__init__.py +++ b/packages/packer/src/rag_packer/__init__.py @@ -32,7 +32,7 @@ ) from rag_packer.types import OrderStrategy, PackerConfig -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "ContextPacker", diff --git a/packages/parsers/pyproject.toml b/packages/parsers/pyproject.toml index c71f7dc..ee6cd99 100644 --- a/packages/parsers/pyproject.toml +++ b/packages/parsers/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-parsers" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — document parsers (PDF, DOCX, PPTX, XLSX, HTML, Markdown, plain text, JSON, CSV, YAML) with MIME detection" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/parsers/src/rag_parsers/__init__.py b/packages/parsers/src/rag_parsers/__init__.py index 2aead78..3284d21 100644 --- a/packages/parsers/src/rag_parsers/__init__.py +++ b/packages/parsers/src/rag_parsers/__init__.py @@ -23,7 +23,7 @@ from rag_parsers.xlsx import XlsxParser from rag_parsers.yaml_parser import YamlParser -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "CsvParser", diff --git a/packages/pii/pyproject.toml b/packages/pii/pyproject.toml index 9e75525..d5ed350 100644 --- a/packages/pii/pyproject.toml +++ b/packages/pii/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-pii" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — PII detection (regex + Presidio), per-tenant block/redact/mask policy enforcement" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/pii/src/rag_pii/__init__.py b/packages/pii/src/rag_pii/__init__.py index 98b55a4..ee15494 100644 --- a/packages/pii/src/rag_pii/__init__.py +++ b/packages/pii/src/rag_pii/__init__.py @@ -21,7 +21,7 @@ from rag_pii.regex_detector import RegexPIIDetector from rag_pii.rewriters import mask_spans, redact_spans -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "PiiPolicyEngine", diff --git a/packages/policy/pyproject.toml b/packages/policy/pyproject.toml index dd250d7..b6f5087 100644 --- a/packages/policy/pyproject.toml +++ b/packages/policy/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-policy" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — central Policy Decision Point (PolicyEngine, PolicyWriter)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/policy/src/rag_policy/__init__.py b/packages/policy/src/rag_policy/__init__.py index de4148e..4a4367b 100644 --- a/packages/policy/src/rag_policy/__init__.py +++ b/packages/policy/src/rag_policy/__init__.py @@ -33,7 +33,7 @@ ) from rag_policy.writer import PolicyWriter -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ # engine diff --git a/packages/provenance/pyproject.toml b/packages/provenance/pyproject.toml index 0a9db71..844ec81 100644 --- a/packages/provenance/pyproject.toml +++ b/packages/provenance/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-provenance" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — HMAC-signed per-query provenance records & tamper-evident verification" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/query/pyproject.toml b/packages/query/pyproject.toml index 7bfef78..c72a3bd 100644 --- a/packages/query/pyproject.toml +++ b/packages/query/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-query" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — query understanding: rewriter, decomposer, HyDE, glossary expansion" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/query/src/rag_query/__init__.py b/packages/query/src/rag_query/__init__.py index 4f5cdf2..9b9dc4f 100644 --- a/packages/query/src/rag_query/__init__.py +++ b/packages/query/src/rag_query/__init__.py @@ -45,7 +45,7 @@ ) from rag_query.types import UnderstoodQuery -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "GlossaryExpander", diff --git a/packages/quota/pyproject.toml b/packages/quota/pyproject.toml index dcbe334..e011010 100644 --- a/packages/quota/pyproject.toml +++ b/packages/quota/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-quota" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — per-tenant quotas & rate limiting: sliding-window enforcement behind the PolicyEngine PDP" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ragctl/pyproject.toml b/packages/ragctl/pyproject.toml index 4c84093..a51d46f 100644 --- a/packages/ragctl/pyproject.toml +++ b/packages/ragctl/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-ragctl" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — ragctl control-plane CLI" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/ragctl/src/ragctl/__init__.py b/packages/ragctl/src/ragctl/__init__.py index b9e98d4..6126561 100644 --- a/packages/ragctl/src/ragctl/__init__.py +++ b/packages/ragctl/src/ragctl/__init__.py @@ -6,4 +6,4 @@ __all__ = ["__version__", "app", "main"] -__version__ = "0.1.0" +__version__ = "1.0.1" diff --git a/packages/reranker/pyproject.toml b/packages/reranker/pyproject.toml index 6830fbb..99c3a99 100644 --- a/packages/reranker/pyproject.toml +++ b/packages/reranker/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-reranker" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — two-stage cross-encoder reranker + MMR diversity (ADR-0006, Step 2.7)" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/reranker/src/rag_reranker/__init__.py b/packages/reranker/src/rag_reranker/__init__.py index 3c54883..6322148 100644 --- a/packages/reranker/src/rag_reranker/__init__.py +++ b/packages/reranker/src/rag_reranker/__init__.py @@ -22,7 +22,7 @@ from rag_reranker.pipeline import RerankPipeline from rag_reranker.types import Hydrator, MMRConfig -__version__ = "0.1.0" +__version__ = "1.0.1" __all__ = [ "Hydrator", diff --git a/packages/retrieval/pyproject.toml b/packages/retrieval/pyproject.toml index ea36087..3e32d2e 100644 --- a/packages/retrieval/pyproject.toml +++ b/packages/retrieval/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-retrieval" -version = "0.5.0" +version = "1.0.1" description = "AgentContextOS — hybrid retrieval orchestration + agent-loop validation spike" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/retrieval/src/rag_retrieval/__init__.py b/packages/retrieval/src/rag_retrieval/__init__.py index 48c9289..f11b6b0 100644 --- a/packages/retrieval/src/rag_retrieval/__init__.py +++ b/packages/retrieval/src/rag_retrieval/__init__.py @@ -77,7 +77,7 @@ from rag_retrieval.hybrid import HybridRetriever, HybridWeights from rag_retrieval.router import RetrievalRouter, RouterConfig, SupportsRoute -__version__ = "0.5.0" +__version__ = "1.0.1" __all__ = [ "AgentLoopConfig", diff --git a/packages/sso/pyproject.toml b/packages/sso/pyproject.toml index 3c5d3a9..fb21630 100644 --- a/packages/sso/pyproject.toml +++ b/packages/sso/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-sso" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — SSO (OIDC/SAML) identity federation + SCIM 2.0 directory provisioning" readme = "README.md" requires-python = ">=3.12" diff --git a/packages/webhooks/pyproject.toml b/packages/webhooks/pyproject.toml index 82d5a9d..c1d8942 100644 --- a/packages/webhooks/pyproject.toml +++ b/packages/webhooks/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "rag-webhooks" -version = "0.1.0" +version = "1.0.1" description = "AgentContextOS — outbound webhook delivery: HMAC signing, retries, fan-out dispatcher (Step 3.9)" readme = "README.md" requires-python = ">=3.12" diff --git a/packaging/README.md b/packaging/README.md index 342ff2c..690a413 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -8,7 +8,7 @@ artifacts signed + SBOM-attested.** | Channel | One-command install | Published by | Signed / SBOM | |---------|--------------------|--------------|---------------| -| **PyPI** (server) | `pip install rag-platform` | `release.yml` (PyPI Trusted Publishing, OIDC) | sdist/wheel via OIDC provenance | +| **PyPI** (server) | `pip install rag-platform` | `release.yml` (every workspace component + the meta, PyPI Trusted Publishing, OIDC) | sdist/wheel via OIDC provenance | | **PyPI** (SDK) | `pip install agentcontextos` | `release.yml` | OIDC provenance | | **npm** (SDK) | `npm i @agentcontextos/sdk` | `release.yml` (npm provenance) | npm provenance | | **Container** (gateway) | `docker pull ghcr.io/officialcodework/agentcontextos/rag-gateway:vX` | `docker.yml` | cosign (keyless) + SPDX SBOM | @@ -24,16 +24,23 @@ published by their language toolchains (deferred to the release-engineering pass ``` git tag v1.0.0 && git push --tags ├── docker.yml → gateway image (build · push · cosign · SBOM) - ├── release.yml → PyPI · npm · admin-ui image · Helm OCI chart + ├── release.yml → PyPI (31 components + meta + SDK) · npm · admin-ui image · Helm OCI chart └── release-airgap.yml → signed offline bundle → GitHub Release asset ``` -All three are tag-triggered, so a single tag fans out to every channel. See -[docs/guides/packaging-distribution.md](../docs/guides/packaging-distribution.md) -and [ADR-0049](../docs/adr/ADR-0049-packaging-distribution.md). +All three are tag-triggered, so a single tag fans out to every channel — and the +tag is the **version authority**: `release.yml` stamps `X.Y.Z` onto every dist +(`scripts/stamp_versions.py` for Python, `npm version` for the TS SDK, +`helm package --version/--app-version` for the chart) before building, so every +artifact a tag produces carries the same platform version. See +[docs/guides/packaging-distribution.md](../docs/guides/packaging-distribution.md), +[ADR-0049](../docs/adr/ADR-0049-packaging-distribution.md), and +[ADR-0053](../docs/adr/ADR-0053-lockstep-component-publishing.md). ## The meta-package [`rag-platform/`](rag-platform/) is the PyPI meta-distribution — it pins the -workspace component distributions so `pip install rag-platform==X` resolves a -reproducible server stack. +complete workspace component closure (all 31 component dists, exactly, at the +platform version) so `pip install rag-platform==X` resolves a reproducible +server stack. The pin set is gated against the workspace by +`tests/packaging/test_meta_package.py`. diff --git a/packaging/rag-platform/README.md b/packaging/rag-platform/README.md index b10bd38..3bd0d34 100644 --- a/packaging/rag-platform/README.md +++ b/packaging/rag-platform/README.md @@ -8,8 +8,12 @@ pip install rag-platform # full self-hosted server stack + ragctl pip install "rag-platform[all]" # + optional backend drivers + cloud KMS ``` -This package pins the component distributions published from the uv workspace on -the same release tag (the gateway, every governance / retrieval / reliability -package, and the `ragctl` CLI). See +This package pins the **complete** workspace component closure — all 31 +component distributions (the gateway, every pipeline / governance / reliability +package, and the `ragctl` CLI), exactly, at the one platform version. Every +pinned dist is built and published from the same release tag, version-stamped +from that tag (`scripts/stamp_versions.py`), so `pip install rag-platform==X` +resolves a fully-reproducible stack. See [docs/guides/packaging-distribution.md](https://github.com/officialCodeWork/AgentContextOS/blob/main/docs/guides/packaging-distribution.md) -for every distribution channel (PyPI, npm, container images, Helm OCI, air-gap). +for every distribution channel (PyPI, npm, container images, Helm OCI, air-gap) +and ADR-0053 for the lockstep-versioning decision. diff --git a/packaging/rag-platform/pyproject.toml b/packaging/rag-platform/pyproject.toml index 3bb021c..34fea47 100644 --- a/packaging/rag-platform/pyproject.toml +++ b/packaging/rag-platform/pyproject.toml @@ -2,15 +2,19 @@ # # `pip install rag-platform` installs the full self-hosted server stack (the # gateway + every governance / retrieval / reliability package + ragctl). It -# pins the component distributions (published from the uv workspace on the same -# release tag); optional backends + cloud KMS providers are extras. +# pins the COMPLETE workspace component closure at the one platform version +# (ADR-0053): every dist below is built from the uv workspace and published on +# the same release tag, version-stamped from that tag by +# scripts/stamp_versions.py. tests/packaging/test_meta_package.py gates this +# pin set against the workspace, so a component cannot ship unpinned, under a +# wrong name, or at a drifted version. [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "rag-platform" -version = "1.0.0" +version = "1.0.1" description = "AgentContextOS — production-grade, multi-tenant RAG platform (meta-distribution)." readme = "README.md" requires-python = ">=3.12" @@ -24,34 +28,67 @@ classifiers = [ "Topic :: Scientific/Engineering :: Artificial Intelligence", ] -# Core server stack — the gateway pulls most of these transitively, but they are -# pinned explicitly so `rag-platform==X` resolves a fully-reproducible stack. +# The complete component closure, pinned exactly, so `rag-platform==X` +# resolves a fully-reproducible stack — nothing is left to float through a +# transitive `>=` constraint. dependencies = [ - "rag-core==1.0.0", - "rag-config==1.0.0", - "rag-observability==1.0.0", - "rag-policy==1.0.0", - "rag-backends==1.0.0", - "rag-retrieval==1.0.0", - "rag-ingest==1.0.0", - "rag-guard==1.0.0", - "rag-breaker==1.0.0", - "rag-quota==1.0.0", - "rag-provenance==1.0.0", - "rag-feedback==1.0.0", - "rag-drift==1.0.0", - "rag-injection==1.0.0", - "rag-gateway==1.0.0", - "ragctl==1.0.0", + # Foundations + "rag-core==1.0.1", + "rag-config==1.0.1", + "rag-observability==1.0.1", + "rag-policy==1.0.1", + "rag-backends==1.0.1", + # Ingest pipeline + "rag-parsers==1.0.1", + "rag-ocr==1.0.1", + "rag-chunker==1.0.1", + "rag-enricher==1.0.1", + "rag-pii==1.0.1", + "rag-embedders==1.0.1", + "rag-ingest==1.0.1", + # Query + retrieval + "rag-retrieval==1.0.1", + "rag-query==1.0.1", + "rag-reranker==1.0.1", + "rag-packer==1.0.1", + "rag-graphrag==1.0.1", + "rag-cache==1.0.1", + "rag-agent==1.0.1", + # Governance + reliability + "rag-guard==1.0.1", + "rag-breaker==1.0.1", + "rag-quota==1.0.1", + "rag-provenance==1.0.1", + "rag-feedback==1.0.1", + "rag-drift==1.0.1", + "rag-injection==1.0.1", + "rag-webhooks==1.0.1", + "rag-sso==1.0.1", + "rag-compliance==1.0.1", + # Service + operator CLI + "rag-gateway==1.0.1", + "rag-ragctl==1.0.1", ] [project.optional-dependencies] -# Optional backend drivers + cloud KMS providers (extras, not in the base install). -backends = ["rag-backends[pgvector,qdrant,redis,s3]==1.0.0"] -kms = ["rag-backends[kms-aws,kms-gcp,kms-azure,kms-vault]==1.0.0"] +# The default backend drivers (Postgres/pgvector, Qdrant, Redis, S3 — plus the +# AWS KMS client) are base rag-backends dependencies and ship with the plain +# install. These extras add the remaining optional driver families; further +# per-component extras (e.g. rag-sso[oidc], rag-ocr[tesseract]) are installed +# by naming the component directly alongside the meta. +backends = [ + "rag-backends[gcs,azure,postgres-cdc,weaviate,pinecone,elasticsearch,tantivy,memgraph,networkx]==1.0.1", +] +kms = ["rag-backends[kms-gcp,kms-azure,kms-vault]==1.0.1"] all = ["rag-platform[backends,kms]"] [project.urls] Homepage = "https://github.com/officialCodeWork/AgentContextOS" Documentation = "https://docs.agentcontextos.io" Source = "https://github.com/officialCodeWork/AgentContextOS" + +# Metadata-only distribution: there is no importable rag_platform package — +# the wheel carries nothing but the pins above. Without the bypass, hatchling +# refuses to build a wheel with no files. +[tool.hatch.build.targets.wheel] +bypass-selection = true diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index 54bab27..0000000 --- a/release-please-config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "packages": { - "packages/core": { - "release-type": "python", - "component": "core" - }, - "apps/gateway": { - "release-type": "python", - "component": "gateway" - } - } -} diff --git a/scripts/stamp_versions.py b/scripts/stamp_versions.py new file mode 100644 index 0000000..99fe1d0 --- /dev/null +++ b/scripts/stamp_versions.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python3 +"""Stamp the one platform version across every publishable distribution. + +AgentContextOS publishes ONE platform version (ADR-0052 / ADR-0053): a release +tag ``vX.Y.Z`` is the version authority, and every distribution built from +this repo on that tag — all uv-workspace component dists, the Python SDK, and +the ``rag-platform`` meta-distribution — is published as ``X.Y.Z``. This +script is the single mechanism that makes that true: + + python scripts/stamp_versions.py 1.0.2 # rewrite every version site + python scripts/stamp_versions.py --check # verify lockstep (read-only) + +It rewrites, for every workspace member (``[tool.uv.workspace] members`` in +the root ``pyproject.toml``): + +* the ``[project] version`` in ``/pyproject.toml`` +* the ``__version__ = "..."`` attribute in the member's top-level package + ``__init__.py``, when the package declares one literally (``rag-gateway`` + derives its ``__version__`` from dist metadata and is left alone) + +and for ``packaging/rag-platform`` (deliberately *not* a workspace member): + +* the ``[project] version`` +* every exact ``rag-*==X.Y.Z`` pin, including extras pins — the meta pins the + complete component closure, gated by ``tests/packaging/test_meta_package.py`` + +The TypeScript SDK is stamped by npm itself in ``release.yml`` +(``npm version``); the Helm chart is stamped by ``helm package``'s +``--version`` / ``--app-version`` flags there too. + +CI: ``release.yml`` runs this with the tag-derived version before +``uv build``; the packaging test gate runs the ``--check`` logic so a +hand-bumped single package can never merge. +""" + +from __future__ import annotations + +import argparse +import re +import sys +import tomllib +from dataclasses import dataclass +from pathlib import Path + +# One [project] version per pyproject; anchored so e.g. requires-python or +# mypy's python_version can never match. +_PYPROJECT_VERSION_RE = re.compile(r'(?m)^version = "(?P[^"]+)"$') +_INIT_VERSION_RE = re.compile(r'(?m)^__version__ = "(?P[^"]+)"$') +# Exact pins in the meta-distribution, with or without extras: +# "rag-core==1.0.1" "rag-backends[kms-gcp,kms-vault]==1.0.1" +_META_PIN_RE = re.compile(r'"(?Prag-[a-z0-9-]+)(?P\[[^]]*])?==(?P[^"]+)"') +# The PEP 440 subset a platform version may use (tag-derived; SemVer-shaped +# release segment plus optional pre/post/dev suffix). +_PLATFORM_VERSION_RE = re.compile(r"^\d+\.\d+\.\d+((a|b|rc)\d+)?(\.post\d+)?(\.dev\d+)?$") + +_META_DIR = Path("packaging") / "rag-platform" +# Workspace members published at the platform version but *not* pinned by the +# rag-platform meta (it is the server stack; the client SDK ships separately). +META_EXCLUDED_DISTS = frozenset({"agentcontextos"}) + + +@dataclass(frozen=True) +class VersionSite: + """One file location that carries the platform version.""" + + path: Path + kind: str # "pyproject" | "init" | "meta-pin" + detail: str # dist name (pyproject/meta-pin) or import root (init) + version: str + + +def workspace_members(root: Path) -> list[Path]: + """Member directories from the root pyproject, in declaration order.""" + with (root / "pyproject.toml").open("rb") as fh: + data = tomllib.load(fh) + members: list[str] = data["tool"]["uv"]["workspace"]["members"] + missing = [m for m in members if not (root / m / "pyproject.toml").is_file()] + if missing: + raise SystemExit(f"workspace members without a pyproject.toml: {missing}") + return [root / m for m in members] + + +def dist_name(member: Path) -> str: + """The [project] name of a member — the dist name published to PyPI.""" + with (member / "pyproject.toml").open("rb") as fh: + return str(tomllib.load(fh)["project"]["name"]) + + +def workspace_dists(root: Path) -> dict[str, Path]: + """Every workspace dist name → its member directory.""" + return {dist_name(m): m for m in workspace_members(root)} + + +def meta_pins(root: Path) -> dict[str, str]: + """Every exact rag-* pin in the meta-distribution: dist name → version.""" + text = (root / _META_DIR / "pyproject.toml").read_text(encoding="utf-8") + return {m["name"]: m["version"] for m in _META_PIN_RE.finditer(text)} + + +def _member_init_files(member: Path) -> list[Path]: + """Top-level package __init__.py files under /src/.""" + src = member / "src" + if not src.is_dir(): + return [] + return sorted(init for pkg in src.iterdir() if (init := pkg / "__init__.py").is_file()) + + +def collect_sites(root: Path) -> list[VersionSite]: + """Every location that must agree on the one platform version.""" + sites: list[VersionSite] = [] + for member in workspace_members(root): + pyproject = member / "pyproject.toml" + text = pyproject.read_text(encoding="utf-8") + matches = _PYPROJECT_VERSION_RE.findall(text) + if len(matches) != 1: + raise SystemExit( + f"{pyproject}: expected exactly one [project] version line, found {len(matches)}" + ) + name = dist_name(member) + sites.append(VersionSite(pyproject, "pyproject", name, matches[0])) + for init in _member_init_files(member): + init_matches = _INIT_VERSION_RE.findall(init.read_text(encoding="utf-8")) + if len(init_matches) > 1: + raise SystemExit(f"{init}: multiple __version__ assignments") + if init_matches: + sites.append(VersionSite(init, "init", init.parent.name, init_matches[0])) + + meta = root / _META_DIR / "pyproject.toml" + meta_text = meta.read_text(encoding="utf-8") + meta_versions = _PYPROJECT_VERSION_RE.findall(meta_text) + if len(meta_versions) != 1: + raise SystemExit(f"{meta}: expected exactly one [project] version line") + sites.append(VersionSite(meta, "pyproject", "rag-platform", meta_versions[0])) + for pin in _META_PIN_RE.finditer(meta_text): + sites.append(VersionSite(meta, "meta-pin", pin["name"], pin["version"])) + return sites + + +def _stamp_text(text: str, version: str) -> str: + """Rewrite every version site in one file's text.""" + text = _PYPROJECT_VERSION_RE.sub(f'version = "{version}"', text) + text = _INIT_VERSION_RE.sub(f'__version__ = "{version}"', text) + return _META_PIN_RE.sub(lambda m: f'"{m["name"]}{m["extras"] or ""}=={version}"', text) + + +def stamp(root: Path, version: str) -> list[Path]: + """Stamp every site to ``version``; returns the files actually changed.""" + if not _PLATFORM_VERSION_RE.match(version): + raise SystemExit( + f"{version!r} is not a valid platform version " + "(expected X.Y.Z with an optional PEP 440 pre/post/dev suffix)" + ) + changed: list[Path] = [] + for path in sorted({site.path for site in collect_sites(root)}): + before = path.read_text(encoding="utf-8") + after = _stamp_text(before, version) + if after != before: + path.write_text(after, encoding="utf-8") + changed.append(path) + return changed + + +def check(root: Path) -> int: + """Verify every site agrees on one valid platform version.""" + sites = collect_sites(root) + versions = {site.version for site in sites} + if len(versions) == 1: + version = versions.pop() + if not _PLATFORM_VERSION_RE.match(version): + print(f"FAIL: shared version {version!r} is not a valid platform version") + return 1 + print(f"OK: {len(sites)} version sites all at {version}") + return 0 + print(f"FAIL: {len(versions)} distinct versions across {len(sites)} sites:") + for site in sites: + print(f" {site.version:<14} {site.kind:<9} {site.detail:<22} {site.path}") + print("Run: python scripts/stamp_versions.py ") + return 1 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("version", nargs="?", help="platform version to stamp, e.g. 1.0.2") + group.add_argument("--check", action="store_true", help="verify lockstep without writing") + parser.add_argument( + "--root", + type=Path, + default=Path(__file__).resolve().parents[1], + help="repo root (default: this script's repository)", + ) + args = parser.parse_args(argv) + + if args.check: + return check(args.root) + changed = stamp(args.root, args.version) + for path in changed: + print(f"stamped {path}") + print(f"{len(changed)} file(s) updated to {args.version}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index a7b1aeb..8411582 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "agentcontextos" -version = "0.1.0" +version = "1.0.1" description = "Official Python SDK for the AgentContextOS RAG gateway" readme = "README.md" requires-python = ">=3.12" diff --git a/sdks/typescript/package.json b/sdks/typescript/package.json index 745ae91..d41696e 100644 --- a/sdks/typescript/package.json +++ b/sdks/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@agentcontextos/sdk", - "version": "0.1.0", + "version": "1.0.1", "description": "Official TypeScript SDK for the AgentContextOS RAG gateway", "license": "Apache-2.0", "type": "module", @@ -13,11 +13,20 @@ "import": "./dist/index.js" } }, - "files": ["dist", "README.md"], + "files": [ + "dist", + "README.md" + ], "engines": { "node": ">=18" }, - "keywords": ["rag", "retrieval", "agent", "llm", "agentcontextos"], + "keywords": [ + "rag", + "retrieval", + "agent", + "llm", + "agentcontextos" + ], "scripts": { "build": "tsc -p tsconfig.build.json", "typecheck": "tsc -p tsconfig.json --noEmit", diff --git a/tests/packaging/test_meta_package.py b/tests/packaging/test_meta_package.py new file mode 100644 index 0000000..61ec314 --- /dev/null +++ b/tests/packaging/test_meta_package.py @@ -0,0 +1,101 @@ +"""Packaging gates — one platform version, lockstep-published (ADR-0053). + +``pip install rag-platform==X`` only resolves if every component the meta pins +is published at exactly ``X``. release.yml guarantees the publish side by +stamping the tag version onto every dist before building; these tests make the +in-repo invariants that mechanism relies on unbreakable: + +* every version site in the workspace agrees on one valid platform version + (a hand-bumped single package cannot merge), +* the rag-platform meta pins the *complete* workspace component closure by the + components' real dist names (a new package cannot ship unpinned; a renamed + one cannot leave a dangling pin), +* every extras pin in the meta references extras the component actually + declares (no ghost extras that pip would silently ignore). +""" + +from __future__ import annotations + +import importlib.util +import shutil +import sys +import tomllib +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] + +_spec = importlib.util.spec_from_file_location( + "stamp_versions", ROOT / "scripts" / "stamp_versions.py" +) +assert _spec is not None and _spec.loader is not None +stamp_versions = importlib.util.module_from_spec(_spec) +# Registered before exec so the @dataclass decorator can resolve the module's +# (string) annotations through sys.modules. +sys.modules["stamp_versions"] = stamp_versions +_spec.loader.exec_module(stamp_versions) + + +def test_one_platform_version_everywhere() -> None: + """Every pyproject version, __version__ attr, and meta pin agrees.""" + sites = stamp_versions.collect_sites(ROOT) + versions = {site.version for site in sites} + assert len(versions) == 1, ( + f"version drift across {len(sites)} sites: {sorted(versions)} — " + "run `python scripts/stamp_versions.py ` to re-stamp" + ) + version = versions.pop() + assert stamp_versions._PLATFORM_VERSION_RE.match(version), ( + f"{version!r} is not a valid platform version" + ) + + +def test_meta_pins_the_complete_component_closure() -> None: + """The meta pins exactly the workspace component dists, by real name. + + A failure here means a workspace package was added, removed, or renamed: + update packaging/rag-platform/pyproject.toml (or, for a dist that is not + part of the server stack, META_EXCLUDED_DISTS in scripts/stamp_versions.py). + """ + components = set(stamp_versions.workspace_dists(ROOT)) - stamp_versions.META_EXCLUDED_DISTS + pinned = set(stamp_versions.meta_pins(ROOT)) + assert pinned == components, ( + f"meta pins out of sync with the workspace — " + f"missing from meta: {sorted(components - pinned)}; " + f"pinned but not a workspace dist: {sorted(pinned - components)}" + ) + + +def test_meta_extras_reference_real_extras() -> None: + """Every `name[extra,...]==X` pin names extras the component declares.""" + meta_text = (ROOT / "packaging" / "rag-platform" / "pyproject.toml").read_text(encoding="utf-8") + dists = stamp_versions.workspace_dists(ROOT) + checked = 0 + for pin in stamp_versions._META_PIN_RE.finditer(meta_text): + if not pin["extras"]: + continue + member = dists[pin["name"]] + with (member / "pyproject.toml").open("rb") as fh: + declared = set(tomllib.load(fh)["project"].get("optional-dependencies", {})) + requested = {e.strip() for e in pin["extras"].strip("[]").split(",")} + assert requested <= declared, ( + f"{pin['name']}: meta requests extras {sorted(requested - declared)} " + f"that the component does not declare (it has {sorted(declared)})" + ) + checked += 1 + assert checked, "expected at least one extras pin in the meta" + + +def test_stamp_is_total_and_idempotent(tmp_path: Path) -> None: + """Stamping a copy of the real tree updates every site, then no-ops.""" + for site in stamp_versions.collect_sites(ROOT): + rel = site.path.relative_to(ROOT) + target = tmp_path / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(site.path, target) + shutil.copyfile(ROOT / "pyproject.toml", tmp_path / "pyproject.toml") + + changed = stamp_versions.stamp(tmp_path, "9.9.9rc1") + assert changed, "stamp touched nothing" + assert {s.version for s in stamp_versions.collect_sites(tmp_path)} == {"9.9.9rc1"} + assert stamp_versions.stamp(tmp_path, "9.9.9rc1") == [], "stamp is not idempotent" + assert stamp_versions.check(tmp_path) == 0 diff --git a/uv.lock b/uv.lock index f00d48e..e921160 100644 --- a/uv.lock +++ b/uv.lock @@ -71,7 +71,7 @@ dev = [ [[package]] name = "agentcontextos" -version = "0.1.0" +version = "1.0.1" source = { editable = "sdks/python" } dependencies = [ { name = "httpx" }, @@ -7119,7 +7119,7 @@ wheels = [ [[package]] name = "rag-agent" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/agent" } dependencies = [ { name = "rag-core" }, @@ -7143,7 +7143,7 @@ provides-extras = ["dev"] [[package]] name = "rag-backends" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/backends" } dependencies = [ { name = "aioboto3" }, @@ -7245,7 +7245,7 @@ provides-extras = ["gcs", "azure", "postgres-cdc", "weaviate", "pinecone", "elas [[package]] name = "rag-breaker" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/breaker" } dependencies = [ { name = "rag-core" }, @@ -7271,7 +7271,7 @@ provides-extras = ["dev"] [[package]] name = "rag-cache" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/cache" } dependencies = [ { name = "rag-core" }, @@ -7297,7 +7297,7 @@ provides-extras = ["dev"] [[package]] name = "rag-chunker" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/chunker" } dependencies = [ { name = "rag-core" }, @@ -7323,7 +7323,7 @@ provides-extras = ["dev"] [[package]] name = "rag-compliance" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/compliance" } dependencies = [ { name = "rag-core" }, @@ -7349,7 +7349,7 @@ provides-extras = ["dev"] [[package]] name = "rag-config" -version = "0.3.0" +version = "1.0.1" source = { editable = "packages/config" } dependencies = [ { name = "pydantic" }, @@ -7381,7 +7381,7 @@ provides-extras = ["eval"] [[package]] name = "rag-core" -version = "0.26.0" +version = "1.0.1" source = { editable = "packages/core" } dependencies = [ { name = "opentelemetry-api" }, @@ -7398,7 +7398,7 @@ requires-dist = [ [[package]] name = "rag-drift" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/drift" } dependencies = [ { name = "rag-core" }, @@ -7424,7 +7424,7 @@ provides-extras = ["dev"] [[package]] name = "rag-embedders" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/embedders" } dependencies = [ { name = "rag-core" }, @@ -7463,7 +7463,7 @@ provides-extras = ["openai", "cohere", "sentence-transformers", "dev"] [[package]] name = "rag-enricher" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/enricher" } dependencies = [ { name = "langdetect" }, @@ -7491,7 +7491,7 @@ provides-extras = ["dev"] [[package]] name = "rag-feedback" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/feedback" } dependencies = [ { name = "rag-core" }, @@ -7517,7 +7517,7 @@ provides-extras = ["dev"] [[package]] name = "rag-gateway" -version = "0.10.0" +version = "1.0.1" source = { editable = "apps/gateway" } dependencies = [ { name = "fastapi" }, @@ -7608,7 +7608,7 @@ provides-extras = ["backends"] [[package]] name = "rag-graphrag" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/graphrag" } dependencies = [ { name = "networkx" }, @@ -7640,7 +7640,7 @@ provides-extras = ["leiden", "dev"] [[package]] name = "rag-guard" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/guard" } dependencies = [ { name = "rag-core" }, @@ -7666,7 +7666,7 @@ provides-extras = ["dev"] [[package]] name = "rag-ingest" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/ingest" } dependencies = [ { name = "rag-core" }, @@ -7690,7 +7690,7 @@ provides-extras = ["dev"] [[package]] name = "rag-injection" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/injection" } dependencies = [ { name = "rag-core" }, @@ -7716,7 +7716,7 @@ provides-extras = ["dev"] [[package]] name = "rag-observability" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/observability" } dependencies = [ { name = "opentelemetry-api" }, @@ -7733,7 +7733,7 @@ requires-dist = [ [[package]] name = "rag-ocr" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/ocr" } dependencies = [ { name = "pillow" }, @@ -7772,7 +7772,7 @@ provides-extras = ["tesseract", "paddle", "dev"] [[package]] name = "rag-packer" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/packer" } dependencies = [ { name = "rag-chunker" }, @@ -7798,7 +7798,7 @@ provides-extras = ["dev"] [[package]] name = "rag-parsers" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/parsers" } dependencies = [ { name = "beautifulsoup4" }, @@ -7838,7 +7838,7 @@ provides-extras = ["dev"] [[package]] name = "rag-pii" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/pii" } dependencies = [ { name = "rag-core" }, @@ -7874,7 +7874,7 @@ provides-extras = ["presidio", "dev"] [[package]] name = "rag-policy" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/policy" } dependencies = [ { name = "pydantic" }, @@ -7891,7 +7891,7 @@ requires-dist = [ [[package]] name = "rag-provenance" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/provenance" } dependencies = [ { name = "rag-core" }, @@ -7917,7 +7917,7 @@ provides-extras = ["dev"] [[package]] name = "rag-query" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/query" } dependencies = [ { name = "rag-core" }, @@ -7941,7 +7941,7 @@ provides-extras = ["dev"] [[package]] name = "rag-quota" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/quota" } dependencies = [ { name = "rag-core" }, @@ -7969,7 +7969,7 @@ provides-extras = ["dev"] [[package]] name = "rag-ragctl" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/ragctl" } dependencies = [ { name = "httpx" }, @@ -8038,7 +8038,7 @@ requires-dist = [ [[package]] name = "rag-reranker" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/reranker" } dependencies = [ { name = "rag-core" }, @@ -8074,7 +8074,7 @@ provides-extras = ["sentence-transformers", "cohere", "jina", "dev"] [[package]] name = "rag-retrieval" -version = "0.5.0" +version = "1.0.1" source = { editable = "packages/retrieval" } dependencies = [ { name = "rag-core" }, @@ -8098,7 +8098,7 @@ provides-extras = ["dev"] [[package]] name = "rag-sso" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/sso" } dependencies = [ { name = "defusedxml" }, @@ -8134,7 +8134,7 @@ provides-extras = ["oidc", "saml", "dev"] [[package]] name = "rag-webhooks" -version = "0.1.0" +version = "1.0.1" source = { editable = "packages/webhooks" } dependencies = [ { name = "httpx" },