Skip to content

Roadmap: v1.0 — General Availability

Document ID: RM-004
File Path: docs/18-roadmap/v1.0.md
Version: 1.20.0
Status: GA-hardening engineering scope complete — all four RM-GA phases are done (P1 security floor, P2 durability/execution, P3 Track A — Track B deferred to v1.1 by design, P4 contract/operability), all three GA-003 hardening-pass residual findings are closed (see §3 Security row), and GA-002’s remote (S3-compatible) backup destination has shipped (see §3 Reliability row). The v1.0 tag itself is not cut: the Tier-A GA-completion validation workstreams remain open — A1 scale/perf validation not started, A2 reliability/DR / A3 security completion / A5 SDK distribution in progress, A4 marketplace economics partial (abuse workflow shipped; monetization + browse UI open).

GA topology decided (ADR-0010, Accepted 2026-07-06): GA ships as a single-node appliance (Path A). The distributed machinery (workflow Postgres store / work-queue / leases / partitions, Redis breakers, Qdrant semantic cache) stays as library-only code and is deferred to a v1.1 “Scale-Out” milestone; the Helm chart’s replicas: 1 is now a product statement, not a temporary limitation. The GA hardening plan that drove this — 21 architecture-review findings → requirements → phased tickets — is PRD-003 with per-phase ticket docs (Phase 1 security floor · Phase 2 durability/execution · Phase 3 scale/distribution · Phase 4 contract/operability).

DX/SDK: a hand-authored OpenAPI 3.0 spec (docs/09-api/openapi.yaml, cataloging every route wovyr-server actually implements), a TypeScript client (sdks/typescript, GET-only retry/backoff, paginateAll(), an npm test-wired redocly lint contract check — built and verified importable from a real package tarball, but not yet published to npm: needs a live 2FA OTP, deferred), and a Python client (sdks/python, stdlib-only, mirroring the TypeScript client 1:1) published to PyPI as wovyr-sdk and verified installable, plus a deprecation-window policy — all integration-tested against a live server.

Security: the envelope-encryption KMS hierarchy (Encryption §5) is wovyr-kms (Kms trait, LocalKms over AES-256-GCM/ring, rotation, crypto-shredding), wired into three real consumers (wovyr-secrets’s EncryptedFileSecretStore, wovyr-memory’s EncryptingMemoryStore, wovyr-events’s EncryptedFileWebhookStore) and live in wovyr-server (the first two also in wovyr-cli): one shared root key + tenant-key catalog (~/.wovyr/kms) feeds every consumer; memory encryption wraps every store unconditionally (sensitive is a safe, per-record opt-in); secret and webhook-secret encryption are each opt-in per deployment (WOVYR_SECRETS_ENCRYPT_AT_REST / WOVYR_WEBHOOKS_ENCRYPT_AT_REST, since each is a distinct on-disk file, not a transparent migration of existing plaintext). A key-management surface now exists too: /api/v1/kms/tenant-key/rotate (kms:write) / .../destroy (kms:admin — a higher tier, since crypto-shredding is irreversible) and wovyr kms rotate|destroy --tenant <t> (destroy requires --yes), both audited (kms.tenant_key.rotate/.destroy). Verified live end to end: sensitive memory sealed on disk/plaintext on query, secrets opt-in round-trips correctly, cross-process decryption (a CLI-sealed record read back through a separately-running server), and rotate → destroy → subsequent rotate returns 403 with both actions in the tamper-evident audit log. Pen-testing and compliance mapping have now also landed: a new adversarial test suite (crates/wovyr-kms/tests/adversarial.rs) attacks cross-tenant DEK laundering, tenant-key-layer tampering, nonce reuse at volume, version-number/blind forgery, and post-crypto-shred replay — all fail closed — and docs/13-security/compliance-mapping.md maps SOC 2 / ISO 27001 / GDPR controls to the implementation with file-level evidence. That exercise also proved (rather than introduced) a real residual finding: the existing anonymous-default-tenant back-compat bypass (tenant_authorize, shared by every tenant-scoped route) reaches kms:admin with zero grant — documented as an operational requirement (configure X-Wovyr-Principal/RBAC before production use) rather than fixed here, since narrowing the shared bypass is a systemic change outside this slice. Config/PII field encryption has since gained its first real slice too: wovyr-events’s EncryptedFileWebhookStore seals a webhook subscription’s HMAC signing secret through wovyr-kms (opt-in via WOVYR_WEBHOOKS_ENCRYPT_AT_REST, mirroring the secret vault’s switch) — found, while scoping this, that no other durably-persisted PII-shaped field exists in the codebase today (wovyr-tenancy’s Organization/Project/Membership carry no email/PII fields; a future User resource would be the next target once it exists). Remaining: a cloud-KMS-/HSM-backed root, and an actual external pen test / formal compliance audit (this pass was an internal self-assessment, not third-party verification).

Reliability: a first real slice — deployment/docker-compose.yml, one wovyr binary (built with tiered-memory,postgres) + Postgres (backs the marketplace registry, genuinely wired into the running server) + Qdrant (backs tiered memory, CLI-only today). Chaos-checked live: stopping Postgres degrades marketplace routes to a clean 502 rather than a crash, and recovers automatically on the next request once Postgres returns — no wovyr restart, and the rest of the server (incl. its own /healthz) unaffected throughout. This exercise also found and fixed a real, previously-latent crash bug: every marketplace route panicked (“Cannot start a runtime from within a runtime”) the moment it was Postgres-backed, because the sync postgres crate’s Client drives its own internal Tokio runtime for every call and can’t be invoked directly from an Axum handler (which already runs on one of the server’s own runtime threads) — fixed by routing every marketplace registry call through tokio::task::spawn_blocking. A real Helm chart now exists too (deployment/helm/wovyr/, 2026-07-05): the same single-binary + Postgres + Qdrant topology as compose, as a StatefulSet (fixed at 1 replica — wovyr’s durable state is local files on a PVC, not shareable across replicas yet). Downloaded portable kubectl/helm/kubeconform binaries into this dev environment specifically to validate it offline (helm lint, helm template, and kubeconform schema-validating all 9 rendered resources against the real Kubernetes OpenAPI definitions — no live cluster needed for any of these) — this caught and fixed a real bug (duplicate app.kubernetes.io/name/instance label keys from a helper-composition mistake) before it ever reached a real manifest. Never applied to a live cluster — no cluster exists in this environment, so deploying and chaos-testing it (the compose precedent) is still open. docs/12-deployment/ {kubernetes,helm}.md describe a materially bigger, aspirational multi-service split that isn’t built; terraform.md remains spec-only with no artifacts.

Everything else in this roadmap (sharding, multi-region) remains unstarted — see §3 below, which is still directional rather than a checklist with exit criteria the way v0.1–v0.3 had.
Owner: Product Team
Last Updated: 2026-07-07


Production-ready GA. Stability, scale, security, and operability sufficient for enterprises to run critical workloads.


  • Stability: stable APIs, DSL, plugin API; documented compatibility guarantees.
  • Scale: validated at target NFRs — billions of memories, thousands of concurrent runs (performance).
  • Security & compliance: hardened posture, audit, supply chain; readiness for SOC 2 / ISO 27001 / GDPR (security).
  • Operability: HA deployment, autoscaling, runbooks, SLOs (deployment, observability).
  • Multi-region option for residency and resilience.
  • SDKs beyond Rust (e.g. Python/TypeScript client SDKs).

Each row below has a dedicated delivery doc under v1.0/ (GA-001…GA-005) with current state, work breakdown, exit criteria, and environment caveats. Beyond-GA directions are tracked separately as Tier B research bets.

AreaDeliverableStatus
ReliabilityHA, DR, backup/restore, chaos-validatedIn progress — a first, real slice landed: deployment/docker-compose.yml (single wovyr binary + Postgres + Qdrant, not the aspirational multi-service split docs/12-deployment/docker-compose.md describes), chaos-checked live (a Postgres outage degrades the marketplace routes it backs to a clean 502, recovering automatically once Postgres returns, with the rest of the server unaffected) — which also surfaced and fixed a real crash bug (every marketplace route panicked when Postgres-backed, since the sync postgres crate can’t run directly on an Axum handler’s async-runtime thread; fixed via tokio::task::spawn_blocking). A real Helm chart now exists too (deployment/helm/wovyr/) for the same single-binary topology — validated offline against portable helm/kubectl/kubeconform binaries (helm lint, helm template, full OpenAPI schema validation of all 9 rendered resources; caught and fixed a real duplicate-label bug), but never applied to a live cluster (none exists here). docs/12-deployment/{kubernetes,helm}.md still describe a bigger, unbuilt multi-service split; terraform.md remains spec-only with no artifacts. wovyr admin backup|restore now supports a remote s3://bucket/prefix destination (2026-07-09, GA-002 §4.1), not just a local path — a hand-rolled AWS SigV4 signer (apps/wovyr-cli/src/s3.rs) over reqwest/hmac/sha2 rather than the full aws-sdk-s3 crate, verified against independently-computed .NET crypto reference values; not yet validated against a live S3-compatible endpoint (none available here)
SecurityPen-tested, compliance-ready, key managementIn progressthe RM-GA-P1 security floor is done: real credential verification (WOVYR_AUTH_MODE=jwt|apikey, crates/wovyr-server/src/auth.rs) overwrites any client-asserted X-Wovyr-Principal before it reaches authorization, TLS is enforced-or-refused on non-loopback binds, and per-principal rate limiting/CORS/body/timeout/concurrency limits are all wired — see phase1-security-floor-tickets.md for the ticket-by-ticket evidence. The anonymous-default-tenant RBAC bypass is now fully closed (2026-07-09, GA-003): WOVYR_ALLOW_ANONYMOUS=1 used to grant an anonymous caller against the default tenant every scope, including kms:admin (crypto-shredding) — that short-circuit in tenant_authorize is deleted; the flag now governs only whether an unauthenticated request reaches a handler at all, never its RBAC outcome (an anonymous caller now 403s on any tenant-scoped route exactly like a real principal with no memberships would). The other two GA-003 residual findings are closed too: kms.json (the wrapped tenant-key catalog) is now restricted to owner-only access after every write, and — authored and verified live on a real Windows host, not just reasoned about — the non-Unix root-key/kms.json ACL gap is closed via a new shared wovyr_common::fs::restrict_to_owner primitive (chmod 0600 on Unix, icacls /inheritance:r /grant:r <user>:F on Windows), replacing three independent #[cfg(unix)]-only copies of the same logic. Separately, audit/secrets/RBAC groundwork exists (wovyr-audit/wovyr-secrets/wovyr-tenancy, all v0.3); the envelope-encryption KMS hierarchy in docs/13-security/encryption.md §5 (wovyr-kms) is live in wovyr-server (secrets/memory also in wovyr-cli) — every consumer shares one root key/tenant-key catalog (~/.wovyr/kms), memory encryption is always wrapped (opt-in per record), and secret/webhook-secret encryption are each opt-in per deployment (WOVYR_SECRETS_ENCRYPT_AT_REST / WOVYR_WEBHOOKS_ENCRYPT_AT_REST, since each swaps the on-disk file). A key-management surface exists and is audited: /api/v1/kms/tenant-key/rotate|destroy (RBAC-tiered kms:write/kms:admin) + wovyr kms rotate|destroy, both logging kms.tenant_key.* events. Verified end to end, including cross-process decryption and the post-destroy fail-closed path. Internal pen-testing, a first compliance mapping, and a first config/PII-field-encryption slice have also landed: an adversarial test suite (crates/wovyr-kms/tests/adversarial.rs), docs/13-security/compliance-mapping.md (SOC2/ISO27001/GDPR controls mapped to the encryption/key-management implementation), and wovyr-events’s new EncryptedFileWebhookStore (webhook signing secrets — the only PII/config-shaped field found to exist durably outside secrets/memory). Remaining: a cloud-KMS-/HSM-backed root, encryption for any future PII field (e.g. a User.email, once that resource exists), and an actual external pen test / formal compliance audit (this was a self-assessment)
ScaleSharding/partitioning, multi-region optionNot started at real scale — wovyr-memory/wovyr-provider perf tests are deliberately toy-scale (250 records, in-process mock provider); billions-of-memories / thousands-of-concurrent-runs needs real capacity engineering against live Postgres/Qdrant
EcosystemMature marketplace, monetization (v1)Not started (marketplace core itself is done in v0.3; monetization/abuse-report remain open per that roadmap)
DXStable SDKs, polished docs, migration guidesIn progressdocs/09-api/openapi.yaml (hand-authored spec covering every implemented route) + a TypeScript client (sdks/typescript) with retry/backoff and pagination helpers, a redocly lint contract test wired into npm test, + a Python client (sdks/python, stdlib-only, same resource shape + retry/pagination helpers, unittest-tested against a live server) — published to PyPI as wovyr-sdk, and a deprecation-window policy, all integration-tested against a live server. Remaining: npm publish of sdks/typescript (blocked on a live 2FA OTP the operator needs to supply interactively — deferred, not a code gap), further language clients, polished docs/migration guides

  • /v1 API and plugin API: backward-compatible within the major version.
  • Deprecations announced with a window; breaking changes only at major bumps (API versioning).

  • Meets published SLOs (alerting) in production.
  • Passes security review and external pen test.
  • Reference customers running critical workloads.


VersionDateDescription
1.20.02026-07-15Status-truth pass: the header still said “in progress — three workstreams now have code” while all four RM-GA phase docs report Done; now states the real position — engineering scope complete, v1.0 tag gated on the Tier-A validation workstreams (A1 not started, A2/A3/A5 in progress, A4 partial)
1.19.02026-07-09Reliability row: GA-002 §4.1’s remote (S3-compatible) wovyr admin backup|restore destination has shipped — s3://bucket/prefix, via a hand-rolled SigV4 signer verified against independently-computed .NET crypto reference values. See A2-reliability-ha-dr.md
1.18.02026-07-09Security row: the remaining two GA-003 residual findings are closed — kms.json is now owner-only after every write, and the non-Unix root-key/kms.json ACL gap (previously documented as needing a Windows environment this repo’s CI/dev setup lacked) is closed via a new shared wovyr_common::fs::restrict_to_owner primitive, authored and verified live on a real Windows host. See A3-security-completion.md
1.17.02026-07-09Security row: the anonymous-default-tenant RBAC bypass (GA-003, a documented residual finding from the KMS pen-testing pass) is closed — tenant_authorize’s short-circuit deleted, so WOVYR_ALLOW_ANONYMOUS=1 no longer implies any RBAC grant. See A3-security-completion.md
1.16.02026-07-07Documentation-sync correction: the §3 Security row never mentioned that RM-GA-P1 (the security floor — real JWT/API-key auth, TLS enforcement, rate limiting, CORS, resource limits, safe-by-default sandboxing) had shipped, even though all 15 of its tickets were committed before this doc’s 1.15.0 revision. phase1-security-floor-tickets.md had the identical gap (still read “Ready for grooming” with no Done markers) and CLAUDE.md/docs/09-api/overview.md separately still described auth as unverified headers — all corrected in this pass. No code changed
1.15.02026-07-06GA deployment topology decided: ADR-0010 ratified Path A (single-node appliance) — distributed machinery deferred to a v1.1 “Scale-Out” milestone. Linked the GA-hardening plan (PRD-003) and its four phased ticket docs, derived from the 2026-07-06 solution-architecture review’s 21 findings
1.14.02026-07-05Reliability: added a real Helm chart (deployment/helm/wovyr/) for the actual single-binary + Postgres + Qdrant topology, validated offline against downloaded helm/kubectl/kubeconform binaries (caught a real duplicate-label bug); never applied to a live cluster
1.13.02026-07-05Added per-workstream delivery docs under v1.0/ (GA-001…GA-005 + index): each §3 In-Scope row now has a doc with current state, work breakdown, exit criteria, and environment caveats. Mirrors the Tier B future/ structure; §3 intro links the folder
1.12.02026-07-05Config/PII field encryption’s first real slice: wovyr-events’s new EncryptedFileWebhookStore seals a webhook subscription’s HMAC signing secret through wovyr-kms (keyed by the subscription’s own tenant), selected via WOVYR_WEBHOOKS_ENCRYPT_AT_REST (opt-in, mirroring the secret vault’s file-swap rationale). wovyr-events now depends on wovyr-kms. Scoping this surfaced that no other durably-persisted PII-shaped field exists in the codebase today — checked wovyr-tenancy’s Organization/Project/Membership (no email/PII fields; Membership.user is an opaque id) and every other FileStore-style JSON persistence path. compliance-mapping.md and encryption.md updated with the new consumer. Full workspace build/clippy/fmt/test clean
1.11.02026-07-05Closed out the KMS/encryption slice’s last two remaining items from 1.9.0: pen-testing (crates/wovyr-kms/tests/adversarial.rs — cross-tenant DEK laundering via rewrap, tenant-key-layer tampering, nonce-reuse-at-volume, version-number/blind forgery, post-crypto-shred replay via envelope, all fail closed) and compliance mapping (docs/13-security/compliance-mapping.md, new — SOC 2/ISO 27001/GDPR controls mapped to the encryption/key-management implementation with file-level evidence, explicitly scoped as an internal self-assessment, not a certification). The exercise also proved a real, pre-existing residual-risk finding — wovyr-server’s anonymous default-tenant back-compat bypass (tenant_authorize) reaches kms:admin with zero grant — via a new documented-gap test, rather than silently carrying the risk; left the shared tenant_authorize behavior unchanged (narrowing it is a systemic change affecting every tenant-scoped route, out of scope for this slice) and instead documented the required operational mitigation. Full workspace build/clippy/fmt/test clean
1.10.02026-07-05Reliability’s first slice: deployment/docker-compose.yml (real single-binary wovyr + Postgres + Qdrant, vs. docs/12-deployment/docker-compose.md’s aspirational multi-service C4 topology) and a parameterized deployment/docker/Dockerfile (FEATURES build arg, curl added for a real /healthz healthcheck). Found and fixed a genuine crash bug while verifying it live against a real Postgres: every marketplace route panicked (“Cannot start a runtime from within a runtime”) once Postgres-backed, since the sync postgres crate’s blocking Client can’t run directly on an Axum handler’s own async-runtime thread — fixed via a with_registry helper (tokio::task::spawn_blocking) now used by all 10 marketplace routes. Chaos-checked: a Postgres outage degrades marketplace routes to a clean 502, recovering automatically on the next request once Postgres returns, with wovyr’s own /healthz and every non-marketplace route unaffected throughout. make compose-up/compose-down added. Full workspace build/clippy/fmt/test clean
1.9.02026-07-04Added a key-management surface + audit integration: POST /api/v1/kms/tenant-key/rotate (kms:write) / .../destroy (kms:admin — a higher tier, since crypto-shredding is irreversible) and matching wovyr kms rotate|destroy --tenant <t> CLI commands (destroy requires --yes). Both log kms.tenant_key.rotate/.destroy through wovyr-audit (tenant reference, never key material). New RBAC scopes kms:write/kms:admin (no wovyr-tenancy logic changes needed — they already fell out of the existing generic write/admin patterns; added to the privilege-ladder test for coverage). AppState gained a shared kms field. Verified live: rotate → destroy → a subsequent rotate attempt returns 403 fail-closed, all three actions present in the tamper-evident audit log; the CLI mirrors the same behavior locally. Full workspace build/clippy/fmt/test clean
1.8.02026-07-04Both encrypting stores made live: wovyr-server (default_kms() in lib.rs) and wovyr-cli (config::kms()) each build one shared LocalKms — root key from WOVYR_KMS_ROOT_KEY or generated at ~/.wovyr/kms/root.key, tenant catalog in the same directory, so either process can decrypt the other’s sealed data. wovyr-memory’s store is now always wrapped in EncryptingMemoryStore (safe no-op unless a record sets sensitive — exposed as the memory-put API’s sensitive field and CLI --sensitive). wovyr-secrets’s vault swaps to EncryptedFileSecretStore when WOVYR_SECRETS_ENCRYPT_AT_REST is set (opt-in, not default, since it reads/writes a distinct file rather than migrating existing plaintext secrets — the CLI’s plugin-secret-injection path honors the same env var so the two processes agree). Verified live against a running server: sensitive memory content sealed on disk / plaintext on query, non-sensitive and default-secrets behavior unchanged, secrets opt-in round-trips correctly, and — proving the shared-key design — a CLI-sealed memory record was read back through a separately-running server process. Full workspace build/clippy/fmt/test clean across all feature combinations (plugin-wasi, tiered-memory)
1.7.02026-07-04wovyr-kms gets a second real consumer: wovyr-memory’s new MemoryRecord.sensitive flag (default false, round-tripped by every store including the tiered Postgres backend’s new sensitive column) plus an EncryptingMemoryStore decorator that seals content through wovyr-kms::envelope before it reaches the wrapped inner store, transparently unsealing on every read (all/get) so retrieval/ranking still operate on plaintext. Wraps any MemoryStore including TieredStore, but always reports supports_pushdown() == false when wrapping one — a purpose-built index can’t score ciphertext, so wrapping trades pushdown acceleration for correctness, documented rather than silently degraded. MemoryEngine::remember_full (which remember_scoped/remember now delegate to) sets the flag. wovyr-memory now depends on wovyr-kms. 5 new unit tests plus the existing 12 (17 total, --features tiered also verified — including the tiered backend’s 6 integration tests, which ran live against a real Postgres/Qdrant in this pass, not just skip-checked); full workspace build/clippy/test unaffected
1.6.02026-07-04wovyr-kms gets its first real consumer: wovyr-secrets’s new EncryptedFileSecretStore seals a secret’s current and retained-previous value through wovyr-kms::envelope before they reach disk (secrets.enc.json, distinct from the plaintext FileSecretStore’s secrets.json), keyed by the secret’s own namespace as the KMS tenant. wovyr-secrets now depends on wovyr-kms (both wovyr-common-only, so the spine stays one-directional). 7 new tests (round-trip, rotation/previous recovery, on-disk-never-plaintext, cross-instance-KMS failure, tenant-scoped listing) alongside the existing 15; full workspace build/clippy/test unaffected
1.5.02026-07-04Security’s key-management row gets its first code slice: new crate wovyr-kms implementing docs/13-security/encryption.md §5’s root→tenant→DEK envelope-encryption hierarchy (Kms trait, LocalKms over AES-256-GCM/ring, rotation via rotate_tenant_key+rewrap_data_key, crypto-shredding via destroy_tenant_key). 22 unit tests, clean clippy --all-targets -- -D warnings and fmt --check, full cargo build --workspace unaffected. Depends only on wovyr-common; not yet wired into any consumer, server route, CLI command, or wovyr-audit
1.4.02026-07-04Published wovyr-sdk to PyPI (verified installable in a clean venv). Found and fixed a real bug in sdks/typescript/package.json while prepping its first publish: main/types/exports pointed at ./dist/index.js, which never existed (tsc’s rootDir emits to dist/src/*) — would have shipped an unimportable package. npm publish itself is deferred: it requires a live 2FA OTP the operator supplies interactively, which doesn’t fit a non-interactive session
1.3.02026-07-04DX/SDK workstream: added sdks/python (wovyr-sdk), a stdlib-only (no requests/httpx) Python client mirroring the TypeScript SDK’s resource shape and retry/pagination helpers 1:1, unittest-integration-tested against a live wovyr dev server (all 15 tests pass, no bugs found — the contract was already proven out by the TypeScript SDK’s own bug-hunting integration tests)
1.2.02026-07-04DX/SDK workstream: TypeScript SDK gained GET-only retry/backoff and a paginateAll() helper, npm test now runs redocly lint on openapi.yaml as a contract check, and added docs/09-api/deprecation-policy.md (90-day window, Deprecation/Sunset headers)
1.1.02026-07-03Status → in progress: first slice of the DX/Stability workstream landed — docs/09-api/openapi.yaml (hand-authored OpenAPI 3.0 spec covering every wovyr-server route, surfacing where overview.md’s conventions are aspirational vs. real) and a TypeScript client (sdks/typescript), integration-tested against a live wovyr dev server (11 tests, including a genuine bug hunt: found and fixed a wrong assumption about workflow-status casing and org/project RBAC’s lack of a default-tenant bypass). Added a Status column to §3’s In Scope table with a grounded read (survey-based) on what groundwork already exists per area — most of v1.0 (HA/DR, sharding, KMS, compliance) is unstarted
1.0.02026-06-27Initial v1.0 roadmap