From 68d35a410fa4dcd67b91a43fcd1041980f569fc1 Mon Sep 17 00:00:00 2001 From: Deep Kumar Singh Kushwah Date: Wed, 10 Jun 2026 02:49:48 +0530 Subject: [PATCH] docs(marketplace): AWS/Azure/GCP listing artifacts + canonical pricing model (Step 7.6) Ship the cloud-marketplace listing artifacts under marketplace/. Approval + procurement integration stay an external per-cloud process (like the 7.3 pentest); the repo carries the submission inputs. - marketplace/pricing.yaml: canonical tiers + usage-metered dimensions whose ids match the Step 7.9 metering signals (so prices reconcile with metering). - marketplace/listing-content.md: shared title / features / SLA / support / terms. - marketplace/{aws,azure,gcp}/README.md: per-cloud SaaS + self-hosted specs, mapping the model to each cloud's billing primitives and reusing the Helm chart + air-gap bundle + GHCR/OCI artifacts. Submission checklists included. - docs/guides/marketplace-listings.md + ADR-0048. Verified: pricing.yaml parses; 233-link relative check. Pure docs/manifests. Co-Authored-By: Claude Opus 4.8 (1M context) --- TRACKER.md | 17 +++++-- docs/README.md | 2 + docs/adr/ADR-0048-marketplace-listings.md | 59 +++++++++++++++++++++ docs/guides/marketplace-listings.md | 52 +++++++++++++++++++ marketplace/README.md | 40 +++++++++++++++ marketplace/aws/README.md | 46 +++++++++++++++++ marketplace/azure/README.md | 48 ++++++++++++++++++ marketplace/gcp/README.md | 47 +++++++++++++++++ marketplace/listing-content.md | 62 +++++++++++++++++++++++ marketplace/pricing.yaml | 52 +++++++++++++++++++ 10 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 docs/adr/ADR-0048-marketplace-listings.md create mode 100644 docs/guides/marketplace-listings.md create mode 100644 marketplace/README.md create mode 100644 marketplace/aws/README.md create mode 100644 marketplace/azure/README.md create mode 100644 marketplace/gcp/README.md create mode 100644 marketplace/listing-content.md create mode 100644 marketplace/pricing.yaml diff --git a/TRACKER.md b/TRACKER.md index 231abeb..00b44b7 100644 --- a/TRACKER.md +++ b/TRACKER.md @@ -14,12 +14,13 @@ | | | |---|---| | **Last updated** | 2026-06-10 | -| **Current phase** | Phase 7 — Pilot, Harden, GA (**5 / 10 steps**) — Phases 0–6 ✅ complete | -| **Overall** | **79 / 84 steps** — Phases 0–6 complete | -| **Next action** | **Step 7.6 — Marketplace listings**: AWS / Azure / GCP Marketplace listings (SaaS offer + self-hosted AMI/Helm); each with pricing, SLA, support tiers, terms, integration guide; documented procurement path. | +| **Current phase** | Phase 7 — Pilot, Harden, GA (**6 / 10 steps**) — Phases 0–6 ✅ complete | +| **Overall** | **80 / 84 steps** — Phases 0–6 complete | +| **Next action** | **Step 7.7 — Packaging & distribution**: PyPI `rag-platform`, npm `@ragplatform/sdk`, GHCR images (cosign + SBOM), Helm OCI repo, air-gap bundle per release; one-command install per channel; release workflow. | **Recently shipped** +- **7.6** ✅ Marketplace listings — listing artifacts for AWS / Azure / GCP under a new `marketplace/` (approval + procurement stay an external per-cloud process, like the 7.3 pentest). **One canonical `pricing.yaml`** (tiers + usage-metered dimensions whose ids match the Step 7.9 metering signals) + **one shared `listing-content.md`** mapped to all three clouds, so listings can't drift and prices reconcile with metering. Each per-cloud spec maps the model to that cloud's billing primitives and **reuses existing delivery** (Helm / AMI / air-gap bundle / GHCR — no new packaging); per-cloud submission checklists + a procurement acceptance test in the guide. [ADR-0048](docs/adr/ADR-0048-marketplace-listings.md) [#179](https://github.com/officialCodeWork/AgentContextOS/pull/179) - **7.5** ✅ Documentation site — a **Docusaurus 3** app (`website/`) that serves the repo `docs/` tree **in place** (single source of truth; `markdown.format: 'detect'` renders hand-written `.md` as CommonMark). The **REST API reference** (`docs/reference/rest-api.md`) is **generated + drift-gated** from `dist/openapi.json` by `scripts/gen_api_reference.py` (`task docs:api`) — never hand-edited. Doc honesty is a `tests/docs/` suite (every `ragctl` / `/v1/` reference in a quickstart must be real) + `lychee` offline link-check + `codespell`, wired into a new `docs` CI workflow. Deferred: Algolia search, versioned docs, the deploy workflow. [ADR-0047](docs/adr/ADR-0047-documentation-site.md) [#178](https://github.com/officialCodeWork/AgentContextOS/pull/178) - **7.4** ✅ Design-partner pilots — the pilot program shipped as a **repo-backed machine** (signing the referenceable partners is the external GTM deliverable, like the 7.3 pentest): an operator runbook + five fill-in templates (`docs/pilots/`), a **customer-support/KB kit** (`docs/pilots/customer-support/` — sample corpus with synthetic PII + a planted injection probe; domain-calibrated criteria), and **`ragctl pilot`** (`onboard` renders the per-tenant config + checklist; `report` assembles a weekly-KPI dashboard + **PASS/FAIL** verdict from the platform's own feedback / drift / cost signal components — the same ones behind `GET /v1/status/*`). KPIs are **pulled, not self-reported**. A worked case study runs it end-to-end on the kit with real `ragctl pilot report` output (satisfaction **+0.733**, **0/5** drift, cost **ok** → **PASS**) + the PII-redaction + injection-blocked security demo. No `dist`/SPI/config change. [#174](https://github.com/officialCodeWork/AgentContextOS/pull/174) - **7.3** ✅ Red-team / security — turns the governance stack into an **adversarial probe gate** across four classes (prompt injection / PII egress / ACL bypass / tenant escape) under a `redteam` marker + a first-class **`redteam-gate`** CI job (`task redteam`). Closes the verified injection gap: new **`rag-injection`** package — a pluggable `InjectionDetector` (dependency-free `HeuristicInjectionDetector`, regexes anchored on attack *grammar* so benign prose isn't flagged) + `PromptInjectionGuard.inspect` that drops hijack chunks **before the LLM**, paired with `INJECTION_RESISTANT_SYSTEM_PROMPT` + `build_user_message` so untrusted context is **fenced data in the user turn, never a system-trust position** (fixes the OpenAI-chat surface that put context in a `system` message); wired on `/v1/query` + `/v1/chat/completions` + MCP; off by default (`cfg.injection`); PII-free `injection.blocked` event. Deterministic gate: a ≥ 500 known + ≥ 500 generated corpus (`eval/redteam_v0/`) hits **96.6 % block** (≥ 95 % bar) at **0 false positives**, plus the no-system-position invariant end-to-end — building the corpus *hardened the detector* (~20 missed phrasings). New PII-egress probe over `PiiPolicyEngine` (zero leakage, second-detector verified); `pip-audit` is the CVE gate; the external pentest is a documented process item. Injection types stay internal (no attacker signal, `dist/schemas`/`openapi` untouched). [#166](https://github.com/officialCodeWork/AgentContextOS/pull/166) @@ -808,7 +809,7 @@ New ground — the only prior crypto was HMAC signing. The V1 plan calls for en | 7.3 | Red-team | ✅ | [#166](https://github.com/officialCodeWork/AgentContextOS/pull/166) — adversarial probe gate (injection / PII / ACL / tenant-escape) under a `redteam` marker + `redteam-gate` CI job; new **`rag-injection`** guard (≥ 95 % block, no untrusted chunk in a system-trust position) wired on every answer surface; PII-egress probe; `task redteam` | | 7.4 | Design partner onboarding | ✅ | [#174](https://github.com/officialCodeWork/AgentContextOS/pull/174) — repo-backed pilot program: operator runbook + 5 templates (`docs/pilots/`) + ADR-0046; **customer-support/KB kit** (corpus w/ PII + planted injection probe; domain criteria); **`ragctl pilot`** `onboard` + `report` (weekly KPIs + PASS/FAIL verdict from feedback/drift/cost signal components, KPIs pulled not self-reported); worked case study (real `pilot report` → PASS). Signing partners = external GTM item | | 7.5 | Documentation site | ✅ | [#178](https://github.com/officialCodeWork/AgentContextOS/pull/178) — Docusaurus app (`website/`) serving `docs/` in place; **generated + drift-gated REST API reference** from `dist/openapi.json`; `tests/docs/` quickstart-honesty suite + `lychee`/`codespell`; `docs` CI workflow; `task docs:api`/`docs:build` | -| 7.6 | Marketplace listings | ⏳ | AWS / Azure / GCP Marketplace AMI / Helm listings | +| 7.6 | Marketplace listings | ✅ | [#179](https://github.com/officialCodeWork/AgentContextOS/pull/179) — `marketplace/` listing artifacts (AWS/Azure/GCP); one canonical `pricing.yaml` (dims = 7.9 metering signals) + shared listing copy mapped to all three; reuse Helm/AMI/airgap/GHCR delivery; submission checklists + procurement test; approval = external process | | 7.7 | Packaging & distribution | ⏳ | PyPI publish (`rag-platform`), npm publish (`@ragplatform/sdk`), Docker Hub images | | 7.8 | Support & SLA | ⏳ | Support tiers defined; SLA dashboards; PagerDuty integration; runbooks | | 7.9 | Billing integration | ⏳ | Stripe metered billing; usage export API; invoice generation | @@ -858,6 +859,13 @@ New ground — the only prior crypto was HMAC signing. The V1 plan calls for en - **New `docs` CI workflow** (`.github/workflows/docs.yml`): API-reference drift · quickstart doc-tests · `codespell` · `lychee --offline` link-check · full `npm run build`. `task docs:dev` / `docs:build` run/build locally. - **Scope:** the site scaffold + generated reference + doc-tests + CI + `task` targets. **No code / `dist` change** beyond the new generated reference file. **Deferred:** Algolia DocSearch, versioned docs aligned to releases, the deploy workflow + custom domain, gRPC/MCP reference auto-generation, executable (vs existence-checked) snippets. Verified locally (the npm site build is a CI step; the Python generator + the 3 doc-tests run green). [ADR-0047](docs/adr/ADR-0047-documentation-site.md), [guides/documentation-site.md](docs/guides/documentation-site.md). +### 7.6 — Marketplace listings ✅ [#179](https://github.com/officialCodeWork/AgentContextOS/pull/179) + +- Listing artifacts for the three clouds under a new `marketplace/`. As with the 7.3 pentest + 7.4 partners, **approval + procurement integration are an external per-cloud process** — the repo ships the submission *inputs*, not a faked "live" status. +- **One pricing model, three listings.** `marketplace/pricing.yaml` is canonical (Community / Pro / Business / Enterprise tiers + usage-metered dimensions); its dimension ids match the **Step 7.9** metering signals one-to-one, so prices reconcile with metered usage and a price change is a one-file edit. `marketplace/listing-content.md` is the shared copy (title / features / SLA / support / terms) the per-cloud files reference — listings can't drift from each other. +- **Reuse existing delivery — no new packaging.** AWS (SaaS + AMI), Azure (SaaS + managed app), GCP (SaaS + K8s app) each map the model to that cloud's billing primitives and deploy via the existing Helm chart (`infra/`) + air-gap bundle (6.9) + GHCR/OCI artifacts (7.7). The per-cloud Marketplace wrappers (packer AMI, Azure ARM, GCP `schema.yaml`) are thin shells, skeletoned. +- **Scope:** `marketplace/` (canonical pricing + shared copy + three per-cloud specs + checklists) + the process guide. No code / `dist` change. **Deferred:** the Marketplace wrapper artifacts, the procurement/metering API integrations, and the actual submissions/approvals (external). Pure docs/manifests, link-checked. [ADR-0048](docs/adr/ADR-0048-marketplace-listings.md), [guides/marketplace-listings.md](docs/guides/marketplace-listings.md). + --- ## PR & Branch History @@ -1010,6 +1018,7 @@ Complete log of every PR. Routine Dependabot bumps are grouped; everything else | [#176](https://github.com/officialCodeWork/AgentContextOS/pull/176) | 2026-06-10 | fix(gateway): scope answers to the question's subject on both answer prompts | | [#177](https://github.com/officialCodeWork/AgentContextOS/pull/177) | 2026-06-10 | feat(admin-ui): wire dashboard + audit page to live data; clearer trace help | | [#178](https://github.com/officialCodeWork/AgentContextOS/pull/178) | 2026-06-10 | feat(docs): Docusaurus documentation site + generated API reference + doc-tests (Step 7.5) | +| [#179](https://github.com/officialCodeWork/AgentContextOS/pull/179) | 2026-06-10 | docs(marketplace): AWS/Azure/GCP listing artifacts + canonical pricing model (Step 7.6) | | #78–#80, #116–#118 | Open | Dependabot bumps — awaiting merge | | #81 | Closed | Dependabot bump — superseded | diff --git a/docs/README.md b/docs/README.md index b9e46a6..f90e64a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -133,6 +133,7 @@ | [red-team.md](guides/red-team.md) | Red-team / security runbook (Step 7.3): the four probe classes (prompt injection / PII egress / ACL bypass / tenant escape) + suites; running the gate (`task redteam`, the `redteam-gate` CI job, `pip-audit` for CVEs); the prompt-injection defense (filtering via `PromptInjectionGuard` + structural trust isolation via the hardened prompt); the corpus + acceptance (≥ 95 % block, ≤ 5 % false positives, no untrusted chunk in a system-trust position); enabling `cfg.injection`; the external-pentest process item | | [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 | | [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 | | [mcp-quickstart.md](guides/mcp-quickstart.md) | MCP quickstart (Step 3.3): 5-minute walkthrough — `ragctl mcp-query`, running the stdio server, mounting `@ragplatform/mcp` in Claude Desktop, the three tools, error shape | @@ -199,6 +200,7 @@ broken, and what to fix before committing to the next phase. | [ADR-0045-red-team-security.md](adr/ADR-0045-red-team-security.md) | Decision (Step 7.3, Phase-7 hardening): turn the governance stack into an **adversarial probe gate** (injection / PII / ACL / tenant-escape) + close the injection gap. New **`rag-injection`** package: a pluggable `InjectionDetector` (dependency-free `HeuristicInjectionDetector`, attack-grammar regexes) + `PromptInjectionGuard.inspect` that drops hijack chunks, paired with the `INJECTION_RESISTANT_SYSTEM_PROMPT` so untrusted context is **fenced data in the user turn, never a system-trust position** (fixes the OpenAI-chat surface that injected context as a `system` turn); wired on `/v1/query` + `/v1/chat/completions` + MCP; off by default (`cfg.injection`). Deterministic CI gate: a ≥ 500 known + ≥ 500 generated corpus (`eval/redteam_v0/`) at **≥ 95 % block** + a **false-positive bound** + the no-system-position invariant end-to-end; building it *hardened the detector*. PII-egress probe over `PiiPolicyEngine` (zero leakage, second-detector verified); `redteam` marker + `redteam-gate` CI job; `pip-audit` is the CVE gate. Injection types are internal (no attacker signal, `dist` untouched). Deferred/process: the external pentest, a real ML classifier behind the seam; rejected a core SPI, surfacing the verdict, tuning to a circular 100 % | | [ADR-0046-design-partner-pilots.md](adr/ADR-0046-design-partner-pilots.md) | Decision (Step 7.4): ship the pilot **machine** in-repo (runbook + templates + per-vertical kits + a `ragctl pilot` KPI reader) while the partner **relationships** stay an external GTM deliverable (like the 7.3 pentest); each success criterion (quality / latency / integration / security) maps to a platform signal (eval / feedback / drift / cost / metrics / compliance) so KPIs are **pulled, not self-reported**; sliced 7.4a–d, leading with customer-support/KB, the framework vertical-extensible; no new package / core type / governed SPI call / `dist` change — the report reads existing status endpoints; rejected a pure-external motion, self-reported KPIs, a `rag-pilot` package, one generic kit | | [ADR-0047-documentation-site.md](adr/ADR-0047-documentation-site.md) | Decision (Step 7.5): publish docs via **Docusaurus** sourcing the repo `docs/` tree **in place** (single source of truth, no copy); `markdown.format: 'detect'` so hand-written `.md` renders as CommonMark; the **REST API reference is generated + drift-gated** from `dist/openapi.json` (a committed file, not a build-time plugin); doc honesty is a `tests/docs/` suite (every `ragctl` / `/v1/` reference is real) + `lychee` + `codespell`; rejected MkDocs, copying `docs/`, an OpenAPI plugin | +| [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 | | [ADR-0041-airgap-bundle.md](adr/ADR-0041-airgap-bundle.md) | Decision (Step 6.9): ship the platform as one signed, self-contained offline bundle (all runtime images + Helm chart + config + installer). Integrity reuses the WORM-export pattern (6.6b): a standard `SHA256SUMS` whose hash is pinned as `manifest.content_hash` is the **hard gate** — verifiable with nothing but `sha256sum`, no network/cosign — and a cosign signature **over `SHA256SUMS`** adds authenticity; the *same* `SHA256SUMS` drives the Python verifier and the standalone shell installer so they can't diverge. The shell/pwsh `install.{sh,ps1}` (shipped inside the bundle) need only docker+helm (air-gap hosts lack uv/the workspace); `ragctl airgap` holds the typed/tested build+verify logic (pure core separated from a stubbable docker/helm/cosign subprocess seam; `--dry-run` = a verifiable bundle minus image blobs, so the path is testable with no Docker). Digest-pinned manifest-driven image set (`infra/airgap/images.txt` + the chart-derived gateway image); key-based cosign is the air-gap recommendation (keyless needs Rekor + an identity policy), keyless is the connected-release path (`release-airgap.yml` on tags). Deferred: ctr/podman load, registry re-tag/push, multi-arch selection, bundling backend charts, TUF-rooted offline keyless verify; rejected `oras`/OCI (no registry to pull from in an air-gap), a second HMAC scheme (cosign already the signer), a pure-shell build (would escape mypy/tests) | | [ADR-0040-sso-scim.md](adr/ADR-0040-sso-scim.md) | Decision (Step 6.8): enterprise identity in two surfaces. **Federation** — `FederatedAuth` *is* an `Auth` SPI backend (the `authenticate(token, tenant_id) → Principal` seam already runs at the boundary, so wiring it is the whole integration — no middleware change); group claims → `acl_labels` so Step 6.3 push-down + 6.5 PII egress govern federated users unchanged (`authorize` stays a coarse allow — federation establishes *who*, the PDP decides *what*). Dependency-free defaults (stdlib HS256 JWT with full `exp`/`nbf`/`iss`/`aud` + constant-time compare; `defusedxml` SAML validating Issuer/Conditions/Audience) with asymmetric OIDC (PyJWT, `[oidc]`) + SAML XML-DSig (signxml, `[saml]`, injected verifier → fail-closed) behind extras; **algorithm-allowlist** designs out `alg:none`/RS↔HS confusion. Per-tenant IdP on `tenants[].sso` (reuses Step 6.1 config; no provider → bearer rejected, header-identity still works). **Provisioning** — SCIM 2.0 is a separate surface with its own per-tenant bearer token (`cfg.scim.tokens`, not a user JWT), a tenant-scoped `ScimStore` SPI (`NoopScimStore`) + `ScimService`, SCIM-shaped errors, disabled→404; no new governed SPI call (linter passes). PII-free `sso.*`/`scim.*` events (hashed subject, never email/userName). Deferred: JWKS rotation, SP-initiated SAML + metadata, SCIM bulk/`/Me`/ETag, directory-backed deprovisioning, admin-console card; rejected Authlib/python3-saml (heavy lxml/xmlsec on the default install), a dedicated SSO middleware, SCIM token on `TenantConfig` | diff --git a/docs/adr/ADR-0048-marketplace-listings.md b/docs/adr/ADR-0048-marketplace-listings.md new file mode 100644 index 0000000..535a701 --- /dev/null +++ b/docs/adr/ADR-0048-marketplace-listings.md @@ -0,0 +1,59 @@ +# ADR-0048 — Marketplace listings: one canonical pricing model, reuse existing delivery + +**Status:** Accepted +**Date:** 2026-06-10 +**Step:** 7.6 — Marketplace listings (Phase 7 — Pilot, Harden, GA) +**Related:** [guides/marketplace-listings.md](../guides/marketplace-listings.md), [marketplace/](../../marketplace/README.md), [6.9 air-gap bundle](ADR-0041-airgap-bundle.md), [7.7 packaging](#), [7.9 billing & metering](#), [planning/phases/phase-7-pilot-ga.md](../../planning/phases/phase-7-pilot-ga.md) + +## Context + +Step 7.6 calls for AWS / Azure / GCP marketplace listings, each with pricing, SLA, +support tiers, terms, and an integration guide, plus a verified procurement path. +Marketplace **approval and procurement integration are external** (per-cloud vendor +onboarding + review), the same way the Step 7.3 pentest and Step 7.4 partner +sign-ups are external. The question is what to version-control so the three +listings stay consistent and a price change isn't a three-place edit. + +## Decision + +**1. One canonical pricing model.** `marketplace/pricing.yaml` is the single source +of truth (tiers + usage-metered dimensions); each cloud README maps it to that +cloud's billing primitives. The `metered_dimensions` ids match the **Step 7.9** +metering signals one-to-one, so listing prices reconcile with metered usage and a +pricing change is a one-file edit ("pricing changes deployable via config", the +7.9 acceptance bar, applied to listings too). + +**2. One shared listing copy.** `marketplace/listing-content.md` holds the title / +description / features / SLA / support / terms; per-cloud files reference it rather +than restating it, so the listings can't drift from each other. + +**3. Reuse existing delivery — no new packaging.** Self-hosted is the Helm chart +(`infra/`) + the air-gapped bundle (6.9); images/charts are the GHCR + OCI artifacts +(7.7); metering is the 7.9 usage export. The per-cloud Marketplace wrappers (AWS +AMI/packer, Azure managed-app ARM, GCP K8s-app `schema.yaml`) are thin shells over +those, skeletoned here. + +**4. Approval + procurement are documented process, not code.** The submission +checklists + the E2E procurement test live in the guide; the repo carries the +inputs, not a fake "approved" status. + +## Consequences + +- New `marketplace/` (canonical pricing + shared copy + three per-cloud specs), + a process guide, and this ADR. +- Pricing/SLA/support stay consistent across clouds and reconcile with metering by + construction. +- **Deferred:** the per-cloud Marketplace wrapper artifacts (packer AMI template, + Azure `mainTemplate.json` + `createUiDefinition.json`, GCP `schema.yaml` + + deployer), the procurement/metering API integrations, and the actual listing + submissions + approvals (external). + +## Alternatives considered + +- **Per-cloud independent pricing/copy.** Rejected — three sources drift; a price + change becomes a three-place edit that won't reconcile with metering. +- **Custom packaging per marketplace.** Rejected — the Helm chart + air-gap bundle + + GHCR images already cover every delivery mode; the marketplace artifacts are + thin wrappers over them. +- **Encode a "listing live" status in the repo.** Rejected — approval is external; + the repo ships submission inputs, and the guide tracks the live status. diff --git a/docs/guides/marketplace-listings.md b/docs/guides/marketplace-listings.md new file mode 100644 index 0000000..c13ae87 --- /dev/null +++ b/docs/guides/marketplace-listings.md @@ -0,0 +1,52 @@ +# Guide: cloud marketplace listings (Step 7.6) + +How AgentContextOS is listed on the AWS, Azure, and GCP marketplaces, and how to +submit / update a listing. + +## What's in the repo vs external + +Getting a listing **approved and live** is an external, per-cloud process (vendor +onboarding, security review, procurement integration, marketplace approval). The +repo ships everything that goes into those submissions so they're repeatable and +consistent: + +| In the repo ([`marketplace/`](../../marketplace/README.md)) | External | +|---|---| +| Canonical pricing (`pricing.yaml`) | Vendor/seller onboarding (tax, banking) | +| Shared listing copy (`listing-content.md`) | Marketplace review + approval | +| Per-cloud listing specs + submission checklists | The procurement/metering API integration build | +| Technical delivery (reuses Helm / AMI / airgap / GHCR) | Listing goes live | + +## One pricing model + +[`marketplace/pricing.yaml`](../../marketplace/pricing.yaml) is the single source +of truth. Its `metered_dimensions` match the **Step 7.9** metering signals exactly, +so listing prices reconcile with metered usage and a price change propagates to +every cloud from one edit. Each cloud README maps the tiers + dimensions to that +cloud's billing primitives. + +## Per-cloud submission + +| Cloud | Spec + checklist | +|-------|------------------| +| AWS Marketplace (SaaS + AMI) | [marketplace/aws/](../../marketplace/aws/README.md) | +| Azure Marketplace (SaaS + managed app) | [marketplace/azure/](../../marketplace/azure/README.md) | +| GCP Marketplace (SaaS + K8s app) | [marketplace/gcp/](../../marketplace/gcp/README.md) | + +Technical delivery reuses existing deliverables — no new packaging: + +- **Self-hosted:** the Helm chart (`infra/`) + the air-gapped bundle (Step 6.9). +- **Images/charts:** the GHCR images + OCI Helm repo (Step 7.7). +- **Metering:** the Step 7.9 usage export feeds each cloud's metering API. + +## Procurement test (acceptance) + +Each listing's acceptance is a **verified procurement path**: from a sandbox buyer +account, subscribe → land on the SaaS page → a tenant is provisioned → drive a +query → confirm a metered usage event is reported and reconciles with the Step 7.9 +usage export. Run this per cloud before flipping the listing to public. + +## See also + +- [marketplace/](../../marketplace/README.md) — the listing artifacts +- [ADR-0048](../adr/ADR-0048-marketplace-listings.md) — the marketplace-listings decision diff --git a/marketplace/README.md b/marketplace/README.md new file mode 100644 index 0000000..be885a4 --- /dev/null +++ b/marketplace/README.md @@ -0,0 +1,40 @@ +# marketplace — cloud marketplace listings (Step 7.6) + +Listing artifacts for the three cloud marketplaces. Like the Step 7.3 external +pentest and the Step 7.4 design partners, **getting a listing approved and live is +an external process** (each marketplace has its own vendor onboarding + review). +This directory ships everything that goes *into* those submissions so they're +repeatable, consistent across clouds, and version-controlled. + +## Layout + +``` +marketplace/ +├── pricing.yaml ← canonical pricing (single source of truth → all 3 clouds) +├── listing-content.md ← shared listing copy: overview, features, SLA, support, terms +├── aws/README.md ← AWS Marketplace SaaS contract + self-hosted AMI +├── azure/README.md ← Azure Marketplace SaaS offer + managed application +└── gcp/README.md ← GCP Marketplace listing (Kubernetes app via Helm) +``` + +## One pricing model, three listings + +[`pricing.yaml`](pricing.yaml) is canonical. Each cloud's listing maps its SKUs to +those tiers + metered dimensions, and the dimensions match the **Step 7.9 metering +signals** exactly — so listing prices reconcile with metered usage and a price +change is a single-file edit. + +| Cloud | Offer type | Self-hosted delivery | Listing | +|-------|-----------|----------------------|---------| +| AWS | SaaS contract + metering | AMI (built from the Helm/airgap bundle) | [aws/](aws/README.md) | +| Azure | SaaS offer + managed application | Managed app (Helm under the hood) | [azure/](azure/README.md) | +| GCP | SaaS + Kubernetes app | Helm chart (OCI) | [gcp/](gcp/README.md) | + +All three reuse the existing deliverables: the Helm chart (`infra/`), the +air-gapped bundle (Step 6.9), and the GHCR images (Step 7.7). + +## Process + +Submission, approval, and the end-to-end procurement test are documented in +[docs/guides/marketplace-listings.md](../docs/guides/marketplace-listings.md). The +decision record is [ADR-0048](../docs/adr/ADR-0048-marketplace-listings.md). diff --git a/marketplace/aws/README.md b/marketplace/aws/README.md new file mode 100644 index 0000000..3d47f98 --- /dev/null +++ b/marketplace/aws/README.md @@ -0,0 +1,46 @@ +# AWS Marketplace listing + +**Offer types:** SaaS contract with metered usage (hosted) + an AMI for +self-hosted/BYOL. + +## Listing fields + +- Title / description / features / SLA / support / terms: [../listing-content.md](../listing-content.md) +- Pricing: [../pricing.yaml](../pricing.yaml) → AWS metering dimensions + +## SaaS (hosted) — metering + +Map each [`pricing.yaml`](../pricing.yaml) `metered_dimensions` entry to an AWS +Marketplace **metering dimension**; the gateway reports hourly usage via the Step 7.9 usage export +(`docs/reference/billing.md`) → the AWS Marketplace Metering Service +(`BatchMeterUsage`). Tier base fees are contract dimensions. + +| pricing.yaml dimension | AWS dimension | Unit | +|------------------------|---------------|------| +| queries | `Queries` | 1k queries | +| docs_ingested | `DocsIngested` | 1k documents | +| storage_gb | `StorageGB` | GB-month | +| reranker_calls | `RerankerCalls` | 1k calls | +| llm_tokens | `LlmTokens` | 1M tokens | + +## Self-hosted AMI / BYOL + +The AMI is built from the existing deliverables — no new packaging: + +1. Base: Amazon Linux 2023 + k3s (or EKS-ready). +2. Install the Helm chart (`infra/`) or load the air-gapped bundle (Step 6.9). +3. Pull GHCR images (Step 7.7), or use the air-gap bundle for no-egress installs. + +A `packer/` template wiring those steps is the build artifact (deferred to the +release-engineering pass; the install path itself is already shipped + tested). + +## Submission checklist + +- [ ] Seller registration + tax/banking onboarding (AWS Marketplace Management Portal) +- [ ] SaaS product created; dimensions match the table above +- [ ] SaaS integration: metering + entitlement (subscription SNS) wired to the gateway +- [ ] AMI scanned + published; usage instructions reference the Helm/airgap guides +- [ ] Pricing + EULA (standard or custom) submitted +- [ ] E2E procurement test from a sandbox buyer account (see the guide) + +See [docs/guides/marketplace-listings.md](../../docs/guides/marketplace-listings.md). diff --git a/marketplace/azure/README.md b/marketplace/azure/README.md new file mode 100644 index 0000000..a71cd90 --- /dev/null +++ b/marketplace/azure/README.md @@ -0,0 +1,48 @@ +# Azure Marketplace listing + +**Offer types:** SaaS offer (hosted, transactable) + Azure Managed Application +(deployed into the customer's subscription). + +## Listing fields + +- Title / description / features / SLA / support / terms: [../listing-content.md](../listing-content.md) +- Pricing: [../pricing.yaml](../pricing.yaml) → Azure plans + metered billing + +## SaaS offer — plans + metering + +Each `pricing.yaml` tier becomes an Azure **plan** (`pro` / `business` / +`enterprise`); usage above inclusions is reported through the Azure Marketplace +**metered billing API** (`usageEvent`) from the Step 7.9 usage export. The SaaS +landing page authenticates the buyer's purchase token and provisions a tenant. + +| pricing.yaml dimension | Azure meter id | Unit | +|------------------------|----------------|------| +| queries | `queries` | 1k queries | +| docs_ingested | `docs_ingested` | 1k documents | +| storage_gb | `storage_gb` | GB-month | +| reranker_calls | `reranker_calls` | 1k calls | +| llm_tokens | `llm_tokens` | 1M tokens | + +## Managed application + +Deployed into the customer subscription, backed by the existing Helm chart: + +- `mainTemplate.json` — an AKS cluster (or existing-cluster reference) + a Helm + extension that installs `infra/` chart with the customer's `rag.yaml`. +- `createUiDefinition.json` — the portal form (tier, region, BYOK key vault, tenant + config) that feeds `mainTemplate` parameters. + +These ARM artifacts are the build deliverable (skeletoned; the underlying Helm +install is already shipped + tested). Authoring them is the marketplace-engineering +task tracked in the guide. + +## Submission checklist + +- [ ] Partner Center account + Commercial Marketplace program enrolled +- [ ] SaaS offer created; plans match `pricing.yaml`; metered dimensions registered +- [ ] SaaS fulfillment + metering APIs wired to the gateway (landing page + webhook) +- [ ] Managed-app package (`mainTemplate` + `createUiDefinition`) validated with ARM-TTK +- [ ] Plan listing, SLA, support, legal terms submitted +- [ ] Preview audience → E2E procurement test → publish + +See [docs/guides/marketplace-listings.md](../../docs/guides/marketplace-listings.md). diff --git a/marketplace/gcp/README.md b/marketplace/gcp/README.md new file mode 100644 index 0000000..027ff45 --- /dev/null +++ b/marketplace/gcp/README.md @@ -0,0 +1,47 @@ +# GCP Marketplace listing + +**Offer types:** SaaS product (hosted, via the Producer Portal + Cloud Commerce +Procurement API) + a Kubernetes application (deployed via the existing Helm chart). + +## Listing fields + +- Title / description / features / SLA / support / terms: [../listing-content.md](../listing-content.md) +- Pricing: [../pricing.yaml](../pricing.yaml) → GCP service + usage reporting + +## SaaS — entitlements + metering + +The buyer purchases through GCP; the **Cloud Commerce Procurement API** signals +entitlement creation (Pub/Sub) → the gateway provisions a tenant. Usage above tier +inclusions is reported via the **Service Control API** from the Step 7.9 usage +export. + +| pricing.yaml dimension | GCP metric | Unit | +|------------------------|-----------|------| +| queries | `queries` | 1k queries | +| docs_ingested | `docs_ingested` | 1k documents | +| storage_gb | `storage_gb` | GB-month | +| reranker_calls | `reranker_calls` | 1k calls | +| llm_tokens | `llm_tokens` | 1M tokens | + +## Kubernetes application + +Deployed via the existing Helm chart (`infra/`), published to the GCP Marketplace +as a K8s app: + +- `schema.yaml` — the app's deploy-time parameters (tier, tenant config, BYOK). +- The chart is pushed to an Artifact Registry OCI repo (Step 7.7 already publishes + `oci://.../charts/rag-*`); the Marketplace K8s app references it. + +The `schema.yaml` + Marketplace deployer image are the build deliverable +(skeletoned; the Helm install path is already shipped + tested). + +## Submission checklist + +- [ ] Cloud Marketplace Producer Portal access + vendor onboarding +- [ ] Product created; pricing mapped to `pricing.yaml` +- [ ] Procurement API integration (entitlement Pub/Sub → tenant provisioning) +- [ ] Service Control usage reporting wired to the gateway usage export +- [ ] K8s app (`schema.yaml` + deployer) submitted, or SaaS landing page approved +- [ ] E2E procurement test from a sandbox billing account + +See [docs/guides/marketplace-listings.md](../../docs/guides/marketplace-listings.md). diff --git a/marketplace/listing-content.md b/marketplace/listing-content.md new file mode 100644 index 0000000..955192f --- /dev/null +++ b/marketplace/listing-content.md @@ -0,0 +1,62 @@ +# Listing content (shared across AWS / Azure / GCP) + +The canonical marketing + legal copy each marketplace listing reuses. Keep this +the single source; per-cloud READMEs reference it rather than restating it. + +## Title + +**AgentContextOS — Production-grade multi-tenant RAG platform** + +## Short description + +Retrieval-augmented generation for the enterprise: pluggable vector / keyword / +graph backends, hybrid retrieval with reranking, per-tenant governance (ACL, PII +egress, BYOK, audit), and four API surfaces (REST, gRPC, MCP, OpenAI-compatible). + +## Key features + +- **Swappable backends** — pgvector, Qdrant, Pinecone, Weaviate, Elasticsearch; + no code changes, config only. +- **Hybrid retrieval** — dense + sparse fused with RRF, two-stage reranking, + context packing, GraphRAG. +- **Governance** — label-based ACL push-down + egress verifier, PII redaction at + egress, BYOK envelope encryption, immutable hash-chained audit log, SSO/SCIM. +- **Reliability** — circuit breakers, graceful-degradation fallback chain, + hallucination guard, prompt-injection guard. +- **Observability** — per-query tracing + signed provenance, online feedback, + drift monitors, cost-anomaly detection, eval harness + CI gate. +- **Four surfaces** — REST `/v1/*`, gRPC, MCP tools, OpenAI-compatible endpoints. + +## SLA (by tier) + +| Tier | Availability | Latency target | +|------|-------------|----------------| +| Pro | 99.5% / mo | P95 ≤ 1s | +| Business | 99.9% / mo | P95 ≤ 800 ms | +| Enterprise | 99.95% / mo | P95 ≤ 800 ms + custom RPO/RTO | + +Full SLA terms: the **support & SLA guide** (`docs/guides/support-sla.md`, Step 7.8). + +## Support tiers + +Community · Pro (business hours) · Business (24×5) · Enterprise (24×7). See the +support guide for response targets and channels. + +## Pricing + +Per [`pricing.yaml`](pricing.yaml): monthly base per tier + usage-metered +queries / documents / storage / reranker calls / LLM tokens. + +## Terms & compliance + +- Standard SaaS subscription terms; data processing addendum on request. +- SOC 2 control mapping: [docs/compliance/soc2-control-mapping.md](../docs/compliance/soc2-control-mapping.md). +- GDPR mapping: [docs/compliance/gdpr-mapping.md](../docs/compliance/gdpr-mapping.md). +- Data residency configurable per tenant (Step 6.10). + +## Integration guide + +Quickstarts for every surface: [docs/guides/curl-quickstart.md](../docs/guides/curl-quickstart.md), +[openai-quickstart.md](../docs/guides/openai-quickstart.md), +[mcp-quickstart.md](../docs/guides/mcp-quickstart.md), +[sdk-quickstart.md](../docs/guides/sdk-quickstart.md). diff --git a/marketplace/pricing.yaml b/marketplace/pricing.yaml new file mode 100644 index 0000000..2f96a4a --- /dev/null +++ b/marketplace/pricing.yaml @@ -0,0 +1,52 @@ +# Canonical pricing model — the single source of truth all three marketplace +# listings (AWS / Azure / GCP) map to. The metered dimensions mirror the Step 7.9 +# billing/metering signals exactly, so listing prices reconcile with metered +# usage and a pricing change is a one-file edit propagated to every listing. +version: "1.0" +currency: USD + +tiers: + - id: community + name: Community + monthly_base: 0 + description: Self-hosted OSS. Community support. All core retrieval features. + limits: { tenants: 1, queries_per_month: 100000, support: community } + + - id: pro + name: Pro + monthly_base: 499 + description: Self-serve SaaS for a single team. + sla: { availability: "99.5%", p95_latency_ms: 1000 } + included: { queries_per_month: 1000000, storage_gb: 50 } + support: business-hours + + - id: business + name: Business + monthly_base: 2500 + description: Production SaaS for multiple teams. + sla: { availability: "99.9%", p95_latency_ms: 800 } + included: { queries_per_month: 10000000, storage_gb: 500 } + support: 24x5 + + - id: enterprise + name: Enterprise + monthly_base: custom + description: BYOK, dedicated indexes, SSO/SCIM, air-gap, custom RPO/RTO. + sla: { availability: "99.95%", p95_latency_ms: 800, custom_rpo_rto: true } + support: 24x7 + +# Usage-metered dimensions, billed above each tier's inclusions. The `id`s match +# the Step 7.9 metering signals (`docs/reference/billing.md`) one-to-one. +metered_dimensions: + - { id: queries, unit: "1k queries", price: 0.50 } + - { id: docs_ingested, unit: "1k documents", price: 1.00 } + - { id: storage_gb, unit: "GB-month", price: 0.25 } + - { id: reranker_calls, unit: "1k calls", price: 2.00 } + - { id: llm_tokens, unit: "1M tokens", price: 5.00 } + +# Per-marketplace identifiers — placeholders until each listing is approved +# (approval is an external process; see docs/guides/marketplace-listings.md). +marketplace_skus: + aws: { product_code: "TBD", metering: aws-marketplace-metering-api } + azure: { offer_id: "TBD", plan_ids: [pro, business, enterprise] } + gcp: { service_name: "TBD", entitlement: gcp-procurement-api }