@growth-labs/conformance 0.3.1 → 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,71 @@
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
+
47
+ ## 0.4.0 — 2026-07-18
48
+
49
+ ### Added
50
+
51
+ - Add optional backward-compatible ownership fields to `publicationSurfaceSchema`:
52
+ `intendedOwner`, `observedOwner`, `ownerReceipt`, `observedCount`, and `minimumCount`.
53
+ - Add `publicationSurfaceOwnerSchema` and `publicationSurfaceOwnerReceiptSchema` exports.
54
+ - Add `publication.surface.static_shadow` finding: emitted when `intendedOwner=runtime` but
55
+ `observedOwner=static`, indicating the Worker is shadowed by a static asset (typically caused by
56
+ `assets.run_worker_first` not being set in `wrangler.toml`).
57
+ - Add `publication.surface.owner_mismatch` finding: emitted when `intendedOwner` and `observedOwner`
58
+ are both explicitly declared, neither is `'na'`, and they do not agree.
59
+ - Add `publication.surface.count_shortfall` finding: emitted when `observedCount < minimumCount`.
60
+ - Add required negative fixture `llms-runtime-static-shadow`: HTTP 200/nonempty `llms` surface with
61
+ `intendedOwner=runtime`, `observedOwner=static`, 14 static entries, 0 minimum dynamic entries.
62
+ Proves the static-shadow detection path before any positive code.
63
+ - The runner does not infer owner from response headers alone; both fields must be explicitly
64
+ declared by the fixture author or collector tool. Raw bodies and URLs are never retained in the
65
+ owner receipt.
66
+ - Document `assets.run_worker_first`, Astro/Cloudflare collector evidence, artifact inspection for
67
+ counts, and explicit `'na'` ownership in `packages-docs/conformance.md`.
68
+
3
69
  ## 0.3.1 — 2026-07-17
4
70
 
5
71
  - Mark the `astro` peer dependency as optional (`peerDependenciesMeta.astro.optional: true`).
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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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { type AstroCspConfig, type AstroCspPolicyOptions, type AstroCspResource, buildAstroCspConfig, buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, buildStrictTransportSecurity, type CachePolicyOptions, type ContentSecurityPolicyOptions, type CrossOriginOpenerPolicy, type CrossOriginResourcePolicy, collectHeaders, type HeaderPolicyOptions, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, type StrictTransportSecurityOptions, } from './policy.js';
2
2
  export { type RunConformanceOptions, runFleetConformance, runSiteConformance } from './runner.js';
3
- export { type Audience, audienceSchema, type BuildEvidence, buildEvidenceSchema, type CacheVariant, type ConformanceCheckReceipt, type ConformanceFinding, type ConformanceFixture, type ConformanceFixtureInput, type CspReportReceipt, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, type EvidenceSummary, evidenceSummarySchema, type FleetEvidenceBundle, findingSeveritySchema, fleetEvidenceBundleSchema, type HeaderMap, headerMapSchema, headerValueSchema, type InlineStyleAttributeInventory, inlineStyleAttributeInventorySchema, type PublicationSurfaceEvidence, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, type RenderMode, type RequiredNegativeFindingCode, type RequiredNegativeFixtureId, renderModeSchema, type SecurityFunctionalProbeReceipt, type SecurityReceipts, type SiteEvidenceBundle, type SurfaceResponse, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
3
+ export { type Audience, audienceSchema, type BuildEvidence, buildEvidenceSchema, type CacheVariant, type ConformanceCheckReceipt, type ConformanceFinding, type ConformanceFixture, type ConformanceFixtureInput, type CspReportReceipt, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, type EvidenceSummary, evidenceSummarySchema, type FleetEvidenceBundle, findingSeveritySchema, fleetEvidenceBundleSchema, type HeaderMap, headerMapSchema, headerValueSchema, type InlineStyleAttributeInventory, inlineStyleAttributeInventorySchema, type PublicationSurfaceEvidence, type PublicationSurfaceOwner, type PublicationSurfaceOwnerReceipt, parseConformanceFixture, publicationSurfaceOwnerReceiptSchema, publicationSurfaceOwnerSchema, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, type RenderMode, type RequiredNegativeFindingCode, type RequiredNegativeFixtureId, renderModeSchema, type SecurityFunctionalProbeReceipt, type SecurityReceipts, type SiteEvidenceBundle, type SurfaceResponse, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,cAAc,EACd,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,8BAA8B,GACnC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EACN,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,SAAS,EACd,eAAe,EACf,iBAAiB,EACjB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,0BAA0B,EAC/B,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAC/B,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,cAAc,EACd,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,8BAA8B,GACnC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EACN,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,SAAS,EACd,eAAe,EACf,iBAAiB,EACjB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,uBAAuB,EACvB,oCAAoC,EACpC,6BAA6B,EAC7B,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAC/B,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { buildAstroCspConfig, buildCacheControl, buildContentSecurityPolicy, buildSharedPublicationHeaders, buildStrictTransportSecurity, collectHeaders, isPrivateAudience, normalizeHeaders, REQUIRED_SECURITY_HEADERS, } from './policy.js';
2
2
  export { runFleetConformance, runSiteConformance } from './runner.js';
3
- export { audienceSchema, buildEvidenceSchema, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, evidenceSummarySchema, findingSeveritySchema, fleetEvidenceBundleSchema, headerMapSchema, headerValueSchema, inlineStyleAttributeInventorySchema, parseConformanceFixture, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, renderModeSchema, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
3
+ export { audienceSchema, buildEvidenceSchema, cacheVariantSchema, checkStatusSchema, conformanceCheckReceiptSchema, conformanceExpectedSchema, conformanceFindingSchema, conformanceFixtureSchema, cspReportReceiptSchema, EVIDENCE_SCHEMA_VERSION, evidenceSummarySchema, findingSeveritySchema, fleetEvidenceBundleSchema, headerMapSchema, headerValueSchema, inlineStyleAttributeInventorySchema, parseConformanceFixture, publicationSurfaceOwnerReceiptSchema, publicationSurfaceOwnerSchema, publicationSurfaceSchema, REQUIRED_FUNCTIONAL_PROBE_NAMES, REQUIRED_NEGATIVE_FIXTURE_CODES, renderModeSchema, securityFunctionalProbeReceiptSchema, securityReceiptsSchema, siteEvidenceBundleSchema, surfaceResponseSchema, validateFleetEvidenceBundle, validateSiteEvidenceBundle, } from './schema.js';
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAK5B,cAAc,EAEd,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,GAEzB,MAAM,aAAa,CAAA;AACpB,OAAO,EAA8B,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAEN,cAAc,EAEd,mBAAmB,EAOnB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EAEvB,qBAAqB,EAErB,qBAAqB,EACrB,yBAAyB,EAEzB,eAAe,EACf,iBAAiB,EAEjB,mCAAmC,EAEnC,uBAAuB,EACvB,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAI/B,gBAAgB,EAKhB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAK5B,cAAc,EAEd,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,GAEzB,MAAM,aAAa,CAAA;AACpB,OAAO,EAA8B,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAEN,cAAc,EAEd,mBAAmB,EAOnB,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EAEvB,qBAAqB,EAErB,qBAAqB,EACrB,yBAAyB,EAEzB,eAAe,EACf,iBAAiB,EAEjB,mCAAmC,EAInC,uBAAuB,EACvB,oCAAoC,EACpC,6BAA6B,EAC7B,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAI/B,gBAAgB,EAKhB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,GAC1B,MAAM,aAAa,CAAA"}
package/dist/runner.js CHANGED
@@ -825,7 +825,7 @@ function checkPublicationSurfaces(fixture) {
825
825
  findings.push({
826
826
  code: 'publication.surface.missing',
827
827
  severity: 'error',
828
- message: `Publication surface ${required} must be present or explicitly declared NA.`,
828
+ message: 'Required publication surface is missing or not declared NA.',
829
829
  path: `publicationSurfaces.${required}`,
830
830
  });
831
831
  }
@@ -839,7 +839,6 @@ function checkPublicationSurfaces(fixture) {
839
839
  severity: 'error',
840
840
  message: 'NA publication surfaces require a capability boundary and evidence.',
841
841
  path,
842
- evidence: surface.name,
843
842
  remediation: 'Declare why the site cannot provide the surface and attach supporting evidence.',
844
843
  });
845
844
  }
@@ -849,7 +848,7 @@ function checkPublicationSurfaces(fixture) {
849
848
  findings.push({
850
849
  code: 'publication.surface.missing',
851
850
  severity: 'error',
852
- message: `Publication surface ${surface.name} is missing.`,
851
+ message: 'Publication surface is missing.',
853
852
  path,
854
853
  });
855
854
  return;
@@ -858,18 +857,85 @@ function checkPublicationSurfaces(fixture) {
858
857
  findings.push({
859
858
  code: 'publication.surface.http_error',
860
859
  severity: 'error',
861
- message: `Publication surface ${surface.name} returned HTTP ${surface.httpStatus}.`,
860
+ message: 'Publication surface returned an HTTP error.',
862
861
  path: `${path}.httpStatus`,
862
+ evidence: `httpStatus=${surface.httpStatus}`,
863
863
  });
864
864
  }
865
865
  if (surface.bodyBytes !== undefined && surface.bodyBytes === 0) {
866
866
  findings.push({
867
867
  code: 'publication.surface.empty',
868
868
  severity: 'error',
869
- message: `Publication surface ${surface.name} has an empty body.`,
869
+ message: 'Publication surface has an empty body.',
870
870
  path: `${path}.bodyBytes`,
871
871
  });
872
872
  }
873
+ const { intendedOwner, observedOwner } = surface;
874
+ const hasIntended = intendedOwner !== undefined;
875
+ const hasObserved = observedOwner !== undefined;
876
+ if (hasIntended !== hasObserved) {
877
+ findings.push({
878
+ code: 'publication.surface.owner_pair_incomplete',
879
+ severity: 'error',
880
+ message: 'Publication surface ownership requires both intendedOwner and observedOwner.',
881
+ path: hasIntended ? `${path}.observedOwner` : `${path}.intendedOwner`,
882
+ remediation: 'Declare both intendedOwner and observedOwner together, or omit both for legacy surfaces.',
883
+ });
884
+ }
885
+ else if (hasIntended && hasObserved && intendedOwner !== 'na' && observedOwner !== 'na') {
886
+ if (!surface.ownerReceipt) {
887
+ findings.push({
888
+ code: 'publication.surface.owner_receipt_missing',
889
+ severity: 'error',
890
+ message: 'Publication surface ownership requires a deterministic receipt when ownership is declared.',
891
+ path: `${path}.ownerReceipt`,
892
+ remediation: 'Attach a privacy-safe receipt with a versioned collector, observedAt timestamp, and signalHash.',
893
+ });
894
+ }
895
+ if (intendedOwner !== observedOwner) {
896
+ if (intendedOwner === 'runtime' && observedOwner === 'static') {
897
+ findings.push({
898
+ code: 'publication.surface.static_shadow',
899
+ severity: 'error',
900
+ message: 'Publication surface is intended to be runtime-owned but is served from static assets.',
901
+ path: `${path}.observedOwner`,
902
+ evidence: 'intended=runtime; observed=static',
903
+ remediation: 'Set assets.run_worker_first = true in wrangler.toml so the Worker handles requests before static assets.',
904
+ });
905
+ }
906
+ else {
907
+ findings.push({
908
+ code: 'publication.surface.owner_mismatch',
909
+ severity: 'error',
910
+ message: 'Publication surface intended owner does not match observed owner.',
911
+ path: `${path}.observedOwner`,
912
+ evidence: `intended=${intendedOwner}; observed=${observedOwner}`,
913
+ remediation: 'Verify the routing configuration ensures the intended owner handles requests for this surface.',
914
+ });
915
+ }
916
+ }
917
+ }
918
+ if (surface.minimumCount !== undefined && surface.observedCount === undefined) {
919
+ findings.push({
920
+ code: 'publication.surface.count_dimension_incomplete',
921
+ severity: 'error',
922
+ message: 'Publication surface count minimum requires both observedCount and minimumCount.',
923
+ path: `${path}.observedCount`,
924
+ remediation: 'Provide both observedCount and minimumCount, or omit both for surfaces without a count contract.',
925
+ });
926
+ }
927
+ else if (surface.minimumCount !== undefined &&
928
+ surface.observedCount !== undefined &&
929
+ surface.observedCount < surface.minimumCount) {
930
+ findings.push({
931
+ code: 'publication.surface.count_shortfall',
932
+ severity: 'error',
933
+ message: 'Publication surface has fewer entries than the required minimum.',
934
+ path: `${path}.observedCount`,
935
+ evidence: `observed=${surface.observedCount}; minimum=${surface.minimumCount}`,
936
+ remediation: 'Verify the surface is populated with the expected number of entries by the intended owner.',
937
+ });
938
+ }
873
939
  });
874
940
  return receipt('publication-surfaces', findings);
875
941
  }