@growth-labs/conformance 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @growth-labs/conformance Changelog
2
2
 
3
+ ## 0.5.0 — 2026-07-19
4
+
5
+ ### Added
6
+
7
+ - Ship the stable `./endpoint` export with `initConformanceEndpoint` as the
8
+ deployment path: parses, validates, schema-strips, bounds, and serializes
9
+ the v2 artifact **once** at module initialization; per-request handling
10
+ validates only method and `versionMetadata.tag` — no I/O, no re-serialization.
11
+ Also exports `createDeploymentConformanceResponse` as a non-recommended
12
+ compatibility helper for direct per-request use (not the deployment path).
13
+ - The immutable factory captures body bytes at initialization time; post-init
14
+ source mutation and schema-external enumerable getters cannot change served
15
+ bytes or trigger I/O. The combined stripping parse validates endpoint
16
+ `buildEvidence` and the served v2 bundle together without reading schema-external
17
+ fields — no `.passthrough()`.
18
+ - Require `buildEvidence.generatedAt` (timezone-qualified ISO-8601 datetime) at
19
+ the deployment endpoint boundary alongside the existing `buildEvidence.commitSha`.
20
+ A missing or non-datetime `generatedAt` produces a permanently-failing handler.
21
+ - Support `GET` and `HEAD`; `HEAD` returns the same headers without a body,
22
+ while unsupported methods return generic `405` JSON with `Allow: GET, HEAD`.
23
+ - Require a non-empty string request method at runtime; missing, non-string, or
24
+ empty values fail closed with generic no-store JSON rather than defaulting to
25
+ `GET` or throwing from the helper.
26
+ - Require the expected production site and an exact lowercase 40-character
27
+ deployment tag from Cloudflare version metadata `tag`; expose that tag as
28
+ `X-Growth-Labs-Commit-SHA` without serializing Cloudflare version IDs or
29
+ timestamps.
30
+ - Require endpoint input bundles to carry an exact lowercase 40-character
31
+ `buildEvidence.commitSha` matching the deployment tag before returning any
32
+ success body or commit header. `buildEvidence.commitSha` is set from build
33
+ provenance independently of `versionMetadata.tag`; they are compared per
34
+ request and must match or the endpoint fails closed.
35
+ - Bound successful endpoint JSON responses to 1 MiB and return
36
+ `Content-Type: application/json; charset=utf-8`, `Cache-Control: private,
37
+ no-store`, and `X-Content-Type-Options: nosniff`.
38
+ - Fail closed with generic JSON for malformed bundles, wrong site or
39
+ environment, missing or malformed deployment tags, oversized evidence, and
40
+ internal exceptions.
41
+ - Serialize only the parsed v2 `SiteEvidenceBundle` schema so unknown schema
42
+ fields are stripped before the body is emitted.
43
+ - Document the consumer-owned sanitization boundary: the adapter does not
44
+ perform heuristic secret detection, and documented free-form finding or
45
+ receipt strings remain the consumer's responsibility.
46
+
3
47
  ## 0.4.0 — 2026-07-18
4
48
 
5
49
  ### Added
package/README.md CHANGED
@@ -87,7 +87,7 @@ const fixture = {
87
87
  },
88
88
  buildEvidence: {
89
89
  commitSha: 'bd39d718f6a5b0df9a249e11638a8b430050941e',
90
- packageVersions: { '@growth-labs/conformance': '0.3.0', '@growth-labs/seo': '0.9.0' },
90
+ packageVersions: { '@growth-labs/conformance': '0.5.0', '@growth-labs/seo': '0.9.0' },
91
91
  staticHeaderPolicy: true,
92
92
  ssrHeaderPolicy: true,
93
93
  },
@@ -97,6 +97,50 @@ const siteBundle = runSiteConformance(fixture)
97
97
  const fleetBundle = runFleetConformance([fixture])
98
98
  ```
99
99
 
100
+ ## Deployment Endpoint Adapter
101
+
102
+ Consumers own the route, the conformance artifact, and the Cloudflare
103
+ `[version_metadata]` binding. The CI/build probe step runs
104
+ `runSiteConformance()`, serializes the result to a JSON artifact file, and
105
+ bundles that file with the Worker. The adapter reads the pre-built artifact at
106
+ module load (not per request) and serves it:
107
+
108
+ ```ts
109
+ import artifact from './conformance-artifact.json' with { type: 'json' }
110
+ import { initConformanceEndpoint } from '@growth-labs/conformance/endpoint'
111
+
112
+ // Artifact produced by the CI probe step before deployment.
113
+ // Static import: a missing conformance-artifact.json is a build-time error —
114
+ // the Worker never starts if the artifact is absent.
115
+ // Artifact is parsed, schema-stripped, bounded, and serialized ONCE here.
116
+ const handler = initConformanceEndpoint(artifact, 'fronts')
117
+
118
+ // src/pages/.well-known/growth-labs-conformance.json.ts
119
+ export function GET({ locals, request }) {
120
+ return handler.handle({
121
+ method: request.method,
122
+ versionMetadata: locals.runtime.env.CF_VERSION_METADATA,
123
+ })
124
+ }
125
+
126
+ export const HEAD = GET
127
+ ```
128
+
129
+ `initConformanceEndpoint` parses the artifact, validates it against the v2
130
+ schema, checks `environment: 'production'` and the expected site, requires
131
+ `buildEvidence.commitSha` (lowercase 40-character hex) and
132
+ `buildEvidence.generatedAt` (timezone-qualified ISO-8601 datetime), and
133
+ serializes the schema-stripped body bytes once. Per-request handling only
134
+ validates the method and compares `versionMetadata.tag` against the baked commit
135
+ SHA — no I/O, no probe execution, no re-serialization. Missing/malformed
136
+ artifacts and wrong site/environment produce a handler that always returns 503.
137
+ The adapter never reads or serializes environment bindings, request headers,
138
+ Cloudflare version IDs, Cloudflare version timestamps, internal exceptions, or
139
+ fields outside the parsed v2 schema. It does not perform heuristic secret
140
+ detection: documented free-form strings such as finding messages, finding
141
+ evidence, remediation text, and receipt evidence remain unchanged and are the
142
+ consumer's sanitization responsibility.
143
+
100
144
  ## Shared Header Policy
101
145
 
102
146
  Use `buildSharedPublicationHeaders()` when a site wants the package-owned
@@ -0,0 +1,21 @@
1
+ export declare const CONFORMANCE_ENDPOINT_MAX_BYTES: number;
2
+ export interface CloudflareVersionMetadataLike {
3
+ id?: unknown;
4
+ tag?: unknown;
5
+ timestamp?: unknown;
6
+ }
7
+ export interface DeploymentConformanceResponseOptions {
8
+ method: string;
9
+ bundle: unknown;
10
+ expectedSite: string;
11
+ versionMetadata?: CloudflareVersionMetadataLike | null;
12
+ }
13
+ export interface ConformanceEndpointHandler {
14
+ handle(options: {
15
+ method: unknown;
16
+ versionMetadata?: CloudflareVersionMetadataLike | null;
17
+ }): Response;
18
+ }
19
+ export declare function initConformanceEndpoint(artifact: unknown, expectedSite: string): ConformanceEndpointHandler;
20
+ export declare function createDeploymentConformanceResponse(options: DeploymentConformanceResponseOptions): Response;
21
+ //# sourceMappingURL=endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,8BAA8B,QAAc,CAAA;AAiBzD,MAAM,WAAW,6BAA6B;IAC7C,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,oCAAoC;IACpD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAA;CACtD;AAED,MAAM,WAAW,0BAA0B;IAC1C,MAAM,CAAC,OAAO,EAAE;QACf,MAAM,EAAE,OAAO,CAAA;QACf,eAAe,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAA;KACtD,GAAG,QAAQ,CAAA;CACZ;AAED,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,OAAO,EACjB,YAAY,EAAE,MAAM,GAClB,0BAA0B,CA+C5B;AAUD,wBAAgB,mCAAmC,CAClD,OAAO,EAAE,oCAAoC,GAC3C,QAAQ,CA8BV"}
@@ -0,0 +1,225 @@
1
+ import { z } from 'zod';
2
+ import { buildEvidenceSchema, siteEvidenceBundleSchema } from './schema.js';
3
+ export const CONFORMANCE_ENDPOINT_MAX_BYTES = 1024 * 1024;
4
+ const COMMIT_SHA_PATTERN = /^[0-9a-f]{40}$/;
5
+ const CONTENT_TYPE = 'application/json; charset=utf-8';
6
+ const GENERIC_FAILURE_BODY = '{"status":"unavailable"}';
7
+ const INIT_FAILURE_DIAGNOSTIC = '[conformance] initConformanceEndpoint: artifact validation failed at init';
8
+ // Single stripping schema: validates endpoint buildEvidence and the v2 bundle together
9
+ // without touching schema-external fields. No .passthrough() — unknown fields are stripped.
10
+ const deploymentArtifactSchema = siteEvidenceBundleSchema.extend({
11
+ buildEvidence: buildEvidenceSchema.extend({
12
+ commitSha: z.string().regex(COMMIT_SHA_PATTERN),
13
+ generatedAt: z.string().datetime({ offset: true }),
14
+ }),
15
+ });
16
+ export function initConformanceEndpoint(artifact, expectedSite) {
17
+ let capturedBody = null;
18
+ let capturedBuildCommitSha = null;
19
+ try {
20
+ const site = readExpectedSite(expectedSite);
21
+ const { buildEvidence, ...bundle } = deploymentArtifactSchema.parse(artifact);
22
+ if (bundle.site !== site || bundle.environment !== 'production') {
23
+ throw new Error('Conformance endpoint evidence does not match the expected production site.');
24
+ }
25
+ capturedBody = stringifyJsonBounded(bundle, CONFORMANCE_ENDPOINT_MAX_BYTES);
26
+ capturedBuildCommitSha = buildEvidence.commitSha;
27
+ }
28
+ catch {
29
+ reportInitFailure();
30
+ }
31
+ return {
32
+ handle(options) {
33
+ let isHead = false;
34
+ try {
35
+ const methodStr = readRequestMethod(options.method);
36
+ isHead = methodStr === 'HEAD';
37
+ if (methodStr !== 'GET' && methodStr !== 'HEAD') {
38
+ return genericFailureResponse(405, false, { Allow: 'GET, HEAD' });
39
+ }
40
+ if (capturedBody === null || capturedBuildCommitSha === null) {
41
+ throw new Error('Conformance endpoint artifact initialization failed.');
42
+ }
43
+ const commitSha = readDeploymentCommitSha(options.versionMetadata);
44
+ if (!commitShaEquals(capturedBuildCommitSha, commitSha)) {
45
+ throw new Error('Conformance endpoint build evidence does not match the deployment tag.');
46
+ }
47
+ return new Response(isHead ? null : capturedBody, {
48
+ status: 200,
49
+ headers: responseHeaders(commitSha),
50
+ });
51
+ }
52
+ catch {
53
+ return genericFailureResponse(503, isHead);
54
+ }
55
+ },
56
+ };
57
+ }
58
+ function reportInitFailure() {
59
+ try {
60
+ console.error(INIT_FAILURE_DIAGNOSTIC);
61
+ }
62
+ catch {
63
+ // Logging must never turn a fail-closed handler into an import-time crash.
64
+ }
65
+ }
66
+ export function createDeploymentConformanceResponse(options) {
67
+ let isHead = false;
68
+ try {
69
+ const method = readRequestMethod(options.method);
70
+ isHead = method === 'HEAD';
71
+ if (method !== 'GET' && method !== 'HEAD') {
72
+ return genericFailureResponse(405, false, { Allow: 'GET, HEAD' });
73
+ }
74
+ const commitSha = readDeploymentCommitSha(options.versionMetadata);
75
+ const expectedSite = readExpectedSite(options.expectedSite);
76
+ const { buildEvidence, ...bundle } = deploymentArtifactSchema.parse(options.bundle);
77
+ if (bundle.site !== expectedSite || bundle.environment !== 'production') {
78
+ throw new Error('Conformance endpoint evidence does not match the expected production site.');
79
+ }
80
+ if (!commitShaEquals(buildEvidence.commitSha, commitSha)) {
81
+ throw new Error('Conformance endpoint build evidence does not match the deployment tag.');
82
+ }
83
+ const body = stringifyJsonBounded(bundle, CONFORMANCE_ENDPOINT_MAX_BYTES);
84
+ return new Response(isHead ? null : body, {
85
+ status: 200,
86
+ headers: responseHeaders(commitSha),
87
+ });
88
+ }
89
+ catch {
90
+ return genericFailureResponse(503, isHead);
91
+ }
92
+ }
93
+ function readRequestMethod(method) {
94
+ if (typeof method !== 'string') {
95
+ throw new Error('Request method is required.');
96
+ }
97
+ const normalizedMethod = method.trim().toUpperCase();
98
+ if (normalizedMethod.length === 0) {
99
+ throw new Error('Request method is required.');
100
+ }
101
+ return normalizedMethod;
102
+ }
103
+ function readExpectedSite(expectedSite) {
104
+ if (typeof expectedSite !== 'string' || expectedSite.trim().length === 0) {
105
+ throw new Error('Expected site identity is required.');
106
+ }
107
+ return expectedSite;
108
+ }
109
+ function readDeploymentCommitSha(versionMetadata) {
110
+ if (!versionMetadata || typeof versionMetadata !== 'object') {
111
+ throw new Error('Cloudflare version metadata is required.');
112
+ }
113
+ const { tag } = versionMetadata;
114
+ if (typeof tag !== 'string' || !COMMIT_SHA_PATTERN.test(tag)) {
115
+ throw new Error('Cloudflare version metadata tag must be a lowercase 40-character commit SHA.');
116
+ }
117
+ return tag;
118
+ }
119
+ function commitShaEquals(left, right) {
120
+ if (left.length !== right.length)
121
+ return false;
122
+ let difference = 0;
123
+ for (let index = 0; index < left.length; index += 1) {
124
+ difference |= left.charCodeAt(index) ^ right.charCodeAt(index);
125
+ }
126
+ return difference === 0;
127
+ }
128
+ function responseHeaders(commitSha) {
129
+ const headers = new Headers({
130
+ 'Content-Type': CONTENT_TYPE,
131
+ 'Cache-Control': 'private, no-store',
132
+ 'X-Content-Type-Options': 'nosniff',
133
+ });
134
+ if (commitSha)
135
+ headers.set('X-Growth-Labs-Commit-SHA', commitSha);
136
+ return headers;
137
+ }
138
+ function genericFailureResponse(status, head, extraHeaders = {}) {
139
+ const headers = responseHeaders();
140
+ for (const [name, value] of Object.entries(extraHeaders))
141
+ headers.set(name, value);
142
+ return new Response(head ? null : GENERIC_FAILURE_BODY, { status, headers });
143
+ }
144
+ function stringifyJsonBounded(value, maxBytes) {
145
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1) {
146
+ throw new RangeError('maxBytes must be a positive safe integer.');
147
+ }
148
+ const encoder = new TextEncoder();
149
+ const parts = [];
150
+ const seen = new Set();
151
+ let bytes = 0;
152
+ function append(part) {
153
+ const nextBytes = bytes + encoder.encode(part).byteLength;
154
+ if (nextBytes > maxBytes)
155
+ throw new RangeError('Conformance endpoint response is too large.');
156
+ bytes = nextBytes;
157
+ parts.push(part);
158
+ }
159
+ function writeJsonString(text) {
160
+ append(JSON.stringify(text));
161
+ }
162
+ function write(next) {
163
+ if (next === null) {
164
+ append('null');
165
+ return;
166
+ }
167
+ switch (typeof next) {
168
+ case 'string':
169
+ writeJsonString(next);
170
+ return;
171
+ case 'number':
172
+ append(Number.isFinite(next) ? String(next) : 'null');
173
+ return;
174
+ case 'boolean':
175
+ append(next ? 'true' : 'false');
176
+ return;
177
+ case 'object':
178
+ writeObject(next);
179
+ return;
180
+ default:
181
+ throw new TypeError('Unsupported JSON value.');
182
+ }
183
+ }
184
+ function writeObject(next) {
185
+ if (seen.has(next))
186
+ throw new TypeError('Cannot serialize circular evidence.');
187
+ seen.add(next);
188
+ try {
189
+ if (Array.isArray(next)) {
190
+ append('[');
191
+ next.forEach((item, index) => {
192
+ if (index > 0)
193
+ append(',');
194
+ if (item === undefined || typeof item === 'function' || typeof item === 'symbol') {
195
+ append('null');
196
+ return;
197
+ }
198
+ write(item);
199
+ });
200
+ append(']');
201
+ return;
202
+ }
203
+ append('{');
204
+ let first = true;
205
+ for (const key of Object.keys(next)) {
206
+ const item = next[key];
207
+ if (item === undefined || typeof item === 'function' || typeof item === 'symbol')
208
+ continue;
209
+ if (!first)
210
+ append(',');
211
+ first = false;
212
+ append(JSON.stringify(key));
213
+ append(':');
214
+ write(item);
215
+ }
216
+ append('}');
217
+ }
218
+ finally {
219
+ seen.delete(next);
220
+ }
221
+ }
222
+ write(value);
223
+ return parts.join('');
224
+ }
225
+ //# sourceMappingURL=endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"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"}