@volter/twin-catalog 0.2.27 → 0.2.29

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/lib/browse.d.mts CHANGED
@@ -7,6 +7,19 @@ export type Coverage = {
7
7
  };
8
8
  export type Replay = { equal: boolean; runs: number; firstSha256: string; secondSha256: string };
9
9
  export type Measurements = {
10
+ consumer: null | {
11
+ measured: boolean;
12
+ passed: boolean;
13
+ scope: string | null;
14
+ fixture: string | null;
15
+ sdkDependencies: Record<string, string> | null;
16
+ tools: Record<string, string> | null;
17
+ clock: Record<string, unknown> | null;
18
+ retainedReadback: boolean | null;
19
+ retentionNotApplicable: string | null;
20
+ teardownVerified: boolean | null;
21
+ failures: string[] | null;
22
+ };
10
23
  scope: string | null;
11
24
  surface: { total: number; served: number; gap: number } | null;
12
25
  operationCoverage: Coverage | null;
package/lib/browse.mjs CHANGED
@@ -130,6 +130,16 @@ export function browse(root, { vendor, package: packageName, integrity = null }
130
130
  operationCoverage: quick?.operationCoverage ?? null, servedOperations: quick?.servedOperations ?? null,
131
131
  steps: quick?.steps ?? null, answered: quick?.answered ?? null, failures: quick?.failures ?? null,
132
132
  replay: quick?.replay ?? null, conformance: bound.report.conformance ?? null,
133
+ consumer: bound.report.consumer ? {
134
+ measured: bound.report.consumer.measured === true, passed: bound.report.consumer.passed === true,
135
+ scope: bound.report.consumer.scope ?? null, fixture: bound.report.consumer.fixture ?? null,
136
+ sdkDependencies: bound.envelope.prepared?.consumerFixture?.dependencies ?? null,
137
+ tools: bound.report.consumer.tools ?? null, clock: bound.report.consumer.clock ?? null,
138
+ retainedReadback: bound.report.consumer.retainedReadback ?? null,
139
+ retentionNotApplicable: bound.report.consumer.retentionNotApplicable ?? null,
140
+ teardownVerified: bound.report.consumer.teardownVerified ?? null,
141
+ failures: bound.report.consumer.failures ?? null,
142
+ } : null,
133
143
  browser: browser?.measured === true ? browser : null,
134
144
  codeCoverage: quick?.codeCoverage ?? null, stateTransitionCoverage: quick?.stateTransitionCoverage ?? null,
135
145
  domCoverage: browser?.domCoverage ?? null, comparison: bound.report.comparison ?? null } : null };
package/lib/runner.mjs CHANGED
@@ -25,7 +25,8 @@ export function withContainer(root, input, output, execute, { spawn = spawnSync
25
25
  let volume = false;
26
26
  try {
27
27
  const tools = input.policy.tools;
28
- run(['build', '--iidfile', imageFile, '--build-arg', `NODE_IMAGE=${input.policy.nodeImage}`, '--build-arg', `BUN_VERSION=${input.policy.bun}`, '--build-arg', `STANDARD_VERSION=${tools['@volter/twin-standard']}`, '--build-arg', `CORE_VERSION=${tools['@volter/world-core']}`, '--build-arg', `RUNTIME_VERSION=${tools['@volter/world-runtime']}`, '--build-arg', `PLAYWRIGHT_VERSION=${tools.playwright}`, '-f', join(root, 'runner/Dockerfile'), root]);
28
+ requireThat(tools['@volter/world'], 'policy must pin the product CLI for installed customer workflows');
29
+ run(['build', '--iidfile', imageFile, '--build-arg', `NODE_IMAGE=${input.policy.nodeImage}`, '--build-arg', `BUN_VERSION=${input.policy.bun}`, '--build-arg', `STANDARD_VERSION=${tools['@volter/twin-standard']}`, '--build-arg', `CORE_VERSION=${tools['@volter/world-core']}`, '--build-arg', `RUNTIME_VERSION=${tools['@volter/world-runtime']}`, '--build-arg', `CLI_VERSION=${tools['@volter/world']}`, '--build-arg', `PLAYWRIGHT_VERSION=${tools.playwright}`, '-f', join(root, 'runner/Dockerfile'), root]);
29
30
  const image = readFileSync(imageFile, 'utf8').trim();
30
31
  requireThat(/^sha256:[a-f0-9]{64}$/.test(image), 'container image has no immutable identity');
31
32
  run(['volume', 'create', '--label', `twin-catalog.owner=${id}`, '--label', `twin-catalog.run=${runOwner}`, id]); volume = true;
@@ -56,12 +57,15 @@ export function evaluate(root, input, output, options = {}) {
56
57
  const lock = run([...common, '--network', 'none', image, '-e', 'process.stdout.write(require("fs").readFileSync("/work/package-lock.json","utf8"))']).stdout;
57
58
  requireThat(digest(lock) === prepared.dependencyLockSha256, 'dependency lock identity changed');
58
59
  write(`${output}.lock.json`, JSON.parse(lock));
60
+ const consumerLock = run([...common, '--network', 'none', image, '-e', 'process.stdout.write(require("fs").readFileSync("/work/customer-app/package-lock.json","utf8"))']).stdout;
61
+ requireThat(digest(consumerLock) === prepared.consumerDependencyLockSha256, 'customer SDK lock identity changed');
62
+ write(`${output}.consumer-lock.json`, JSON.parse(consumerLock));
59
63
  phase = 'offline-assessment';
60
64
  const result = run([...common, '--network', 'none', '--entrypoint', 'bun', image, '/opt/catalog/node_modules/@volter/world-runtime/src/cli.ts', 'run', '/work/world.json', '--root', '/work', '--env-out', '/work/world.env', '--owner', owner, '--', 'bun', '/opt/catalog/runner/evaluate.mjs'], true);
61
65
  const reportRead = run([...common, '--network', 'none', image, '-e', 'process.stdout.write(require("fs").readFileSync("/work/report.json","utf8"))'], true);
62
66
  const report = reportRead.status === 0 ? JSON.parse(reportRead.stdout) : null;
63
67
  requireThat(!report || (report.schemaVersion === 1 && report.package === input.submission.package && report.version === input.submission.version && report.integrity === input.submission.integrity), 'evaluator returned a mismatched report');
64
- const envelope = { schemaVersion: 1, inputSha256: digest(input), input, image, prepared, dependencyLock: JSON.parse(lock), status: result.status === 0 && report?.ready === true ? 'ready' : 'changes-needed', report, evaluatedAt: new Date().toISOString() };
68
+ const envelope = { schemaVersion: 1, inputSha256: digest(input), input, image, prepared, dependencyLock: JSON.parse(lock), consumerDependencyLock: JSON.parse(consumerLock), status: result.status === 0 && report?.ready === true ? 'ready' : 'changes-needed', report, evaluatedAt: new Date().toISOString() };
65
69
  write(output, envelope);
66
70
  return envelope;
67
71
  }, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/twin-catalog",
3
- "version": "0.2.27",
3
+ "version": "0.2.29",
4
4
  "description": "The moderated twin distribution: approved versions and submission tooling for independent publishers.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "evidence"
39
39
  ],
40
40
  "catalog": {
41
- "sourceCommit": "c27c7eb3ddb06ebc3dd9f28005e5912d9611f4c8",
42
- "digest": "444d6dddb05c1a2a6bb3a145d485325213664f442d4eaf61154942d2e918db0d"
41
+ "sourceCommit": "251b4771b7e0f8f262041cc47f436d8b4f785537",
42
+ "digest": "3195c901d6068ef7be8e9e23676b9b6ec58fb4e50c2d5604bbea390fefec9fdb"
43
43
  }
44
44
  }
package/policy.json CHANGED
@@ -2,10 +2,11 @@
2
2
  "schemaVersion": 1,
3
3
  "registry": "https://registry.npmjs.org",
4
4
  "tools": {
5
- "@volter/world-core": "3.0.98",
6
- "@volter/world-runtime": "3.0.98",
7
- "@volter/twin-standard": "1.0.90",
8
- "playwright": "1.63.0"
5
+ "@volter/world-core": "3.0.100",
6
+ "@volter/world-runtime": "3.0.100",
7
+ "@volter/twin-standard": "1.0.92",
8
+ "playwright": "1.63.0",
9
+ "@volter/world": "3.0.100"
9
10
  },
10
11
  "bun": "1.4.2",
11
12
  "nodeImage": "node:24-bookworm-slim",
package/runner/Dockerfile CHANGED
@@ -4,13 +4,18 @@ ARG BUN_VERSION=1.3.11
4
4
  ARG STANDARD_VERSION=1.0.37
5
5
  ARG CORE_VERSION=3.0.45
6
6
  ARG RUNTIME_VERSION=3.0.45
7
+ ARG CLI_VERSION
7
8
  ARG PLAYWRIGHT_VERSION=1.63.0
8
9
  ENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright
9
- RUN apt-get update && apt-get install -y --no-install-recommends git openssl ca-certificates libfaketime && rm -rf /var/lib/apt/lists/*
10
+ # Install native PostgreSQL tools without a distribution-owned cluster; each World owns its own data and lifetime.
11
+ # https://manpages.debian.org/bookworm/postgresql-common/pg_createcluster.1.en.html#DEFAULT_VALUES
12
+ RUN mkdir -p /etc/postgresql-common && printf 'create_main_cluster = false\n' > /etc/postgresql-common/createcluster.conf \
13
+ && apt-get update && apt-get install -y --no-install-recommends git openssl ca-certificates libfaketime postgresql-15 && rm -rf /var/lib/apt/lists/*
14
+ ENV VOLTER_WORLD_POSTGRES_BIN=/usr/lib/postgresql/15/bin
10
15
  WORKDIR /opt/catalog
11
16
  RUN npm install --ignore-scripts --no-audit --no-fund --save-exact \
12
17
  @oven/bun-linux-x64@${BUN_VERSION} @volter/twin-standard@${STANDARD_VERSION} \
13
- @volter/world-core@${CORE_VERSION} @volter/world-runtime@${RUNTIME_VERSION} tar@7.5.7 semver@7.8.5 sigstore@4.1.1 playwright@${PLAYWRIGHT_VERSION}
18
+ @volter/world-core@${CORE_VERSION} @volter/world-runtime@${RUNTIME_VERSION} @volter/world@${CLI_VERSION} tar@7.5.7 semver@7.8.5 sigstore@4.1.1 playwright@${PLAYWRIGHT_VERSION}
14
19
  ENV PATH="/opt/catalog/node_modules/@oven/bun-linux-x64/bin:/opt/catalog/node_modules/.bin:${PATH}"
15
20
  RUN ./node_modules/.bin/playwright install --with-deps chromium
16
21
  COPY lib /opt/catalog/lib
@@ -7,9 +7,10 @@ requireThat(Boolean(process.env.VOLTER_WORLD), 'evaluation must run inside a Wor
7
7
  const { submission: s } = read('/input/input.json');
8
8
  const requireFromPack = createRequire('/work/package.json');
9
9
  const { assessPack } = await import(requireFromPack.resolve('@volter/twin-standard'));
10
- const assessment = await assessPack(join('/work/packs', s.vendor), { browser: true });
10
+ const prepared = read('/work/prepared.json');
11
+ const assessment = await assessPack(join('/work/packs', s.vendor), { browser: true, consumer: prepared.consumer });
11
12
  requireThat(assessment.package === s.package && assessment.version === s.version && assessment.vendor === s.vendor, 'assessment returned a different artifact identity');
12
- const report = { ...assessment, integrity: s.integrity, prepared: read('/work/prepared.json') };
13
+ const report = { ...assessment, integrity: s.integrity, prepared };
13
14
  report.comparison = compareReports(report, existsSync('/input/baseline.json') ? read('/input/baseline.json') : null);
14
15
  write('/work/report.json', report);
15
16
  process.exit(report.ready ? 0 : 1);
@@ -81,6 +81,18 @@ const provenance = await verifiedProvenance(await response.json(), source, bytes
81
81
  // Keep a vendor-named package directory for the standard's public directory API; preserve the installed artifact.
82
82
  mkdirSync('/work/packs', { recursive: true });
83
83
  cpSync(join('/work/node_modules', s.package), join('/work/packs', s.vendor), { recursive: true });
84
+ const { prepareConsumerApp } = await import(evaluatorRequire.resolve('@volter/twin-standard'));
85
+ const appDir = '/work/customer-app';
86
+ const consumerFixture = prepareConsumerApp(join('/work/packs', s.vendor), appDir);
87
+ const appInstall = spawnSync('npm', ['install', '--ignore-scripts', '--no-audit', '--no-fund', '--registry', policy.registry], { cwd: appDir, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
88
+ requireThat(appInstall.status === 0, `customer SDK preparation failed: ${appInstall.stderr}`);
89
+ const consumerLock = read(join(appDir, 'package-lock.json'));
90
+ for (const [path, entry] of Object.entries(consumerLock.packages ?? {})) {
91
+ if (!path) continue;
92
+ requireThat(!entry.link && entry.resolved && entry.integrity, `${path}: customer dependency is not a locked registry artifact`);
93
+ registryURL(entry.resolved, policy.registry);
94
+ }
95
+ const consumer = { appDir, cli: '/work/node_modules/.bin/volter', artifactIntegrity: s.integrity };
84
96
  // Retain listing facts from these exact bytes, never the registry's moving latest metadata.
85
97
  const packageMetadata = {
86
98
  description: typeof pack.description === 'string' ? pack.description : null,
@@ -90,5 +102,5 @@ const packageMetadata = {
90
102
  repositoryDirectory: typeof pack.repository === 'object' ? pack.repository.directory ?? null : null,
91
103
  bugs: typeof pack.bugs === 'string' ? pack.bugs : pack.bugs?.url ?? null,
92
104
  };
93
- write('/work/prepared.json', { schemaVersion: 1, submission: s, integrity: s.integrity, provenance, packageMetadata, dependencyLockSha256: digest(readFileSync('/work/package-lock.json', 'utf8')), clientSdkLocks, clientDependencyChoices, tools: policy.tools });
105
+ write('/work/prepared.json', { schemaVersion: 1, submission: s, integrity: s.integrity, provenance, packageMetadata, dependencyLockSha256: digest(readFileSync('/work/package-lock.json', 'utf8')), clientSdkLocks, clientDependencyChoices, tools: policy.tools, consumer, consumerFixture, consumerDependencyLockSha256: digest(readFileSync(join(appDir, 'package-lock.json'), 'utf8')) });
94
106
  write('/work/world.json', { id: 'catalog-assessment', network: { egress: [] }, services: [] });
@@ -0,0 +1,20 @@
1
+ {
2
+ "vendor": "clerk",
3
+ "packages": [
4
+ {
5
+ "name": "@volter/twin-clerk",
6
+ "source": "twin-packs-open",
7
+ "versions": [
8
+ {
9
+ "version": "1.0.2",
10
+ "status": "live",
11
+ "integrity": "sha512-3HZEt5czGpF/wEWcoDk+1/2Ln6J4Tg00kqFbgWTJ6VP8th5myZ1c9x2QowBmFcSdmdp0U00HMMxD7VJ4ucSkxw==",
12
+ "submission": "fa756dfc21662a70679a660dd88fcb2b4f8bad30f408f1134cd87b0668289fc6",
13
+ "commit": "c7c9a81cfb79e7410ddf7b26a51c2359647cd1a8",
14
+ "at": "2026-10-07T01:03:20Z",
15
+ "by": "moderated-merge"
16
+ }
17
+ ]
18
+ }
19
+ ]
20
+ }