Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ runtimes/ Peer runtime implementations, currently Python
contracts/ OpenAPI-derived public SDK catalog and JSON schemas
conformance/ Language-neutral cross-runtime fixtures
examples/ Short HTTP client recipes
experiments/ Consumer-neutral provider proofs that are not published packages
samples/ Runnable .NET and execution examples
tests/ Unit, integration, conformance, and adapter suites
qualification/ Versioned adapter qualification report and policy
Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/generation-bound-retrieval.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ those operations can be promoted into a credible portable contract.
The Cloudflare service-reader topology gives the public query Worker no R2 binding. A separate
non-public Worker alone binds the bucket and exposes only an authenticated, allowlisted read
operation over a service binding. The query Worker fails closed when neither or both read modes are
configured. See the [reference implementation and proof harness](../../experiments/worker-r2-generation-projection).
configured. See the [reference implementation and proof harness](../../src/Vyral.Cloudflare/WorkerR2GenerationProjection).

The consumer validation used a small synthetic corpus and does not establish representative
traffic, production capacity, availability, cost, or provider observability. The public evidence
Expand Down
48 changes: 24 additions & 24 deletions qualification/retrieval-projection-qualification.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://openvyral.com/qualification/retrieval-projection-qualification.schema.json",
"schemaVersion": "1.0",
"coreContractVersion": "0.3.0",
"generatedAtUtc": "2026-08-27T18:41:00Z",
"generatedAtUtc": "2026-08-27T19:17:00Z",
"qualificationExpiresAfterDays": 90,
"adapters": [
{
Expand Down Expand Up @@ -128,10 +128,10 @@
{
"adapterId": "worker-r2-generation-direct",
"displayName": "Cloudflare Worker/R2 generation-bound projection (direct R2)",
"implementation": "experiments/worker-r2-generation-projection/src/worker.mjs",
"implementation": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/worker.mjs",
"implementationArtifacts": [
{
"path": "experiments/worker-r2-generation-projection/src/worker.mjs",
"path": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/worker.mjs",
"sha256": "sha256:e9311869f2e671397b6f2a017882002bde33b46b9a78d4367d3e7ea192f0d6fc"
}
],
Expand All @@ -155,24 +155,24 @@
"evidence": [
{
"kind": "unit_gate",
"observedAtUtc": "2026-08-27T18:38:00Z",
"expiresAtUtc": "2026-11-25T18:38:00Z",
"reference": "experiments/worker-r2-generation-projection/verify.mjs",
"observedAtUtc": "2026-08-27T19:15:12Z",
"expiresAtUtc": "2026-11-25T19:15:12Z",
"reference": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/verify.mjs",
"disclosure": "public",
"sourceCommit": "3f35a88b5e9d7e4e6840ab64dfe786fe612d14a2",
"sourceTreeDigest": "sha256:2663cd143a60fb2f54522116f9b63c9c5549f36073855e6b230d5ec770bd28f7",
"sourceCommit": "7db0be8d97b151752105c4efb54d6c06f04cfda0",
"sourceTreeDigest": "sha256:c49743c03747580a291cd1e032120fbf192264ddec456be8ff5010c6636a8fb6",
"sourceDirty": false,
"generationIds": [],
"descriptorDigests": []
},
{
"kind": "local_gate",
"observedAtUtc": "2026-08-27T18:38:00Z",
"expiresAtUtc": "2026-11-25T18:38:00Z",
"observedAtUtc": "2026-08-27T19:15:12Z",
"expiresAtUtc": "2026-11-25T19:15:12Z",
"reference": "scripts/verify-worker-r2-generation-projection.py",
"disclosure": "public",
"sourceCommit": "3f35a88b5e9d7e4e6840ab64dfe786fe612d14a2",
"sourceTreeDigest": "sha256:2663cd143a60fb2f54522116f9b63c9c5549f36073855e6b230d5ec770bd28f7",
"sourceCommit": "7db0be8d97b151752105c4efb54d6c06f04cfda0",
"sourceTreeDigest": "sha256:c49743c03747580a291cd1e032120fbf192264ddec456be8ff5010c6636a8fb6",
"sourceDirty": false,
"generationIds": [],
"descriptorDigests": []
Expand All @@ -182,14 +182,14 @@
{
"adapterId": "worker-r2-generation-service-reader",
"displayName": "Cloudflare Worker/R2 generation-bound projection (service reader)",
"implementation": "experiments/worker-r2-generation-projection/src/worker.mjs + src/object-reader.mjs",
"implementation": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/worker.mjs + src/object-reader.mjs",
"implementationArtifacts": [
{
"path": "experiments/worker-r2-generation-projection/src/object-reader.mjs",
"path": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/object-reader.mjs",
"sha256": "sha256:9fe0cba9c743210314ef6a91d9306a867527a6267068f75108fd5d868bd15a28"
},
{
"path": "experiments/worker-r2-generation-projection/src/worker.mjs",
"path": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/worker.mjs",
"sha256": "sha256:e9311869f2e671397b6f2a017882002bde33b46b9a78d4367d3e7ea192f0d6fc"
}
],
Expand All @@ -213,24 +213,24 @@
"evidence": [
{
"kind": "unit_gate",
"observedAtUtc": "2026-08-27T18:38:00Z",
"expiresAtUtc": "2026-11-25T18:38:00Z",
"reference": "experiments/worker-r2-generation-projection/src/object-reader.mjs",
"observedAtUtc": "2026-08-27T19:15:12Z",
"expiresAtUtc": "2026-11-25T19:15:12Z",
"reference": "src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/object-reader.mjs",
"disclosure": "public",
"sourceCommit": "3f35a88b5e9d7e4e6840ab64dfe786fe612d14a2",
"sourceTreeDigest": "sha256:2663cd143a60fb2f54522116f9b63c9c5549f36073855e6b230d5ec770bd28f7",
"sourceCommit": "7db0be8d97b151752105c4efb54d6c06f04cfda0",
"sourceTreeDigest": "sha256:c49743c03747580a291cd1e032120fbf192264ddec456be8ff5010c6636a8fb6",
"sourceDirty": false,
"generationIds": [],
"descriptorDigests": []
},
{
"kind": "local_gate",
"observedAtUtc": "2026-08-27T18:38:00Z",
"expiresAtUtc": "2026-11-25T18:38:00Z",
"observedAtUtc": "2026-08-27T19:15:12Z",
"expiresAtUtc": "2026-11-25T19:15:12Z",
"reference": "scripts/verify-worker-r2-generation-projection.py",
"disclosure": "public",
"sourceCommit": "3f35a88b5e9d7e4e6840ab64dfe786fe612d14a2",
"sourceTreeDigest": "sha256:2663cd143a60fb2f54522116f9b63c9c5549f36073855e6b230d5ec770bd28f7",
"sourceCommit": "7db0be8d97b151752105c4efb54d6c06f04cfda0",
"sourceTreeDigest": "sha256:c49743c03747580a291cd1e032120fbf192264ddec456be8ff5010c6636a8fb6",
"sourceDirty": false,
"generationIds": [],
"descriptorDigests": []
Expand Down
13 changes: 6 additions & 7 deletions scripts/export-public-tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"contracts",
"deploy",
"examples",
"experiments",
"packaging",
"qualification",
"runtimes",
Expand Down Expand Up @@ -166,12 +165,12 @@
"examples/python/retrieval_migration.py",
"examples/python/canonical_store_cutover.py",
"examples/python/stateless_mcp_round_robin.py",
"experiments/worker-r2-generation-projection/README.md",
"experiments/worker-r2-generation-projection/package-lock.json",
"experiments/worker-r2-generation-projection/package.json",
"experiments/worker-r2-generation-projection/src/object-reader.mjs",
"experiments/worker-r2-generation-projection/src/worker.mjs",
"experiments/worker-r2-generation-projection/verify.mjs",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/README.md",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/package-lock.json",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/package.json",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/object-reader.mjs",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/src/worker.mjs",
"src/Vyral.Cloudflare/WorkerR2GenerationProjection/verify.mjs",
"LICENSE",
"packaging/nuget/README.md",
"packaging/container-security-release.json",
Expand Down
10 changes: 5 additions & 5 deletions scripts/verify-worker-r2-generation-projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


ROOT = Path(__file__).resolve().parent.parent
EXPERIMENT = ROOT / "experiments" / "worker-r2-generation-projection"
PROJECTION = ROOT / "src" / "Vyral.Cloudflare" / "WorkerR2GenerationProjection"
CONTRACT_SCHEMA = (
ROOT
/ "src"
Expand Down Expand Up @@ -460,13 +460,13 @@ def main() -> int:
completed = subprocess.run(
[
"node",
str(EXPERIMENT / "verify.mjs"),
str(PROJECTION / "verify.mjs"),
"--bundle",
str(bundle_path),
"--mode",
mode,
],
cwd=EXPERIMENT,
cwd=PROJECTION,
check=False,
stdout=subprocess.PIPE,
text=True,
Expand All @@ -485,9 +485,9 @@ def main() -> int:
"status": "complete",
"generation": generation,
"implementation": {
"workerSha256": digest_bytes((EXPERIMENT / "src" / "worker.mjs").read_bytes()),
"workerSha256": digest_bytes((PROJECTION / "src" / "worker.mjs").read_bytes()),
"objectReaderSha256": digest_bytes(
(EXPERIMENT / "src" / "object-reader.mjs").read_bytes()
(PROJECTION / "src" / "object-reader.mjs").read_bytes()
),
},
"verification": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Worker/R2 generation-bound projection

This experiment implements Vyral's optional generation-bound candidate contract on Cloudflare
Workers and R2. It is consumer-neutral reference code, not a published package or a portable index
file format.
This reference integration implements Vyral's optional generation-bound candidate contract on
Cloudflare Workers and R2. It is consumer-neutral reference code, not a published package or a
portable index file format.

The query Worker:

Expand Down Expand Up @@ -53,7 +53,7 @@ Install the exact locked dependency graph and exercise both topologies against a
consumer-neutral fixture:

```shell
npm ci --ignore-scripts --prefix experiments/worker-r2-generation-projection
npm ci --ignore-scripts --prefix src/Vyral.Cloudflare/WorkerR2GenerationProjection
python3 scripts/verify-worker-r2-generation-projection.py \
--output /tmp/vyral-worker-r2-proof.json
```
Expand Down
Loading