📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-07-18 00:02:59 +00:00
parent 82f7c6e56a
commit 47ce7f78dc
1446 changed files with 141041 additions and 6442 deletions
@@ -0,0 +1,6 @@
"use strict";
const { validateManifest } = require("./manifest");
const { assertVersionHandshake, buildPlanEnvelope, validatePlanEnvelope } = require("./plan");
module.exports = { assertVersionHandshake, buildPlanEnvelope, validateManifest, validatePlanEnvelope };
@@ -0,0 +1,182 @@
"use strict";
const versions = require("../versions");
const { canonicalJson, sha256 } = require("../canonical-json");
const DIGEST_PATTERN = /^sha256-[a-f0-9]{64}$/;
const ID_PATTERN = /^[a-z0-9][a-z0-9._-]*(?:\/[a-z0-9][a-z0-9._-]*)*$/;
const PACKAGE_PATTERN = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
const SUPPORTED_HOSTS = new Set(["codex", "claude"]);
const SUPPORTED_SCOPES = new Set(["project", "user"]);
const SUPPORTED_RISKS = new Set(["none", "safe", "unknown", "critical", "offensive"]);
function isPlainObject(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
const prototype = Object.getPrototypeOf(value);
return prototype === Object.prototype || prototype === null;
}
function issue(path, code, details = {}) {
return { path, code, ...details };
}
function rejectUnknownKeys(value, allowed, path, issues) {
if (!isPlainObject(value)) return;
for (const key of Object.keys(value).sort()) {
if (!allowed.has(key)) issues.push(issue(`${path}.${key}`, "AAS_STACK_FIELD_UNKNOWN"));
}
}
function validateString(value, path, issues, options = {}) {
const { minimum = 1, maximum = 256, pattern } = options;
if (typeof value !== "string" || value.length < minimum || value.length > maximum) {
issues.push(issue(path, "AAS_STACK_STRING_INVALID"));
return false;
}
if (pattern && !pattern.test(value)) {
issues.push(issue(path, "AAS_STACK_STRING_FORMAT_INVALID"));
return false;
}
return true;
}
function validateUniqueStringArray(value, path, issues, options = {}) {
const { minimum = 0, maximum = 64, pattern, allowed } = options;
if (!Array.isArray(value) || value.length < minimum || value.length > maximum) {
issues.push(issue(path, "AAS_STACK_ARRAY_INVALID"));
return;
}
const seen = new Set();
value.forEach((entry, index) => {
if (!validateString(entry, `${path}[${index}]`, issues, { maximum: 128, pattern })) return;
if (allowed && !allowed.has(entry)) issues.push(issue(`${path}[${index}]`, "AAS_STACK_VALUE_UNSUPPORTED"));
if (seen.has(entry)) issues.push(issue(`${path}[${index}]`, "AAS_STACK_VALUE_DUPLICATE"));
seen.add(entry);
});
}
function invalidResult(issues) {
return {
schemaVersion: 1,
ok: false,
status: "invalid",
...versions,
code: "AAS_STACK_MANIFEST_INVALID",
category: "invalidInput",
details: { issues },
};
}
function validateManifest(manifest) {
const issues = [];
if (!isPlainObject(manifest)) return invalidResult([issue("$", "AAS_STACK_OBJECT_REQUIRED")]);
rejectUnknownKeys(
manifest,
new Set(["schemaVersion", "name", "catalog", "targets", "intent", "policy", "skills"]),
"$",
issues,
);
if (manifest.schemaVersion !== 1) issues.push(issue("$.schemaVersion", "AAS_STACK_SCHEMA_VERSION_UNSUPPORTED"));
validateString(manifest.name, "$.name", issues, { maximum: 128, pattern: /^[A-Za-z0-9][A-Za-z0-9._ -]*$/ });
if (!isPlainObject(manifest.catalog)) {
issues.push(issue("$.catalog", "AAS_STACK_OBJECT_REQUIRED"));
} else {
rejectUnknownKeys(manifest.catalog, new Set(["package", "version", "integrity"]), "$.catalog", issues);
validateString(manifest.catalog.package, "$.catalog.package", issues, { maximum: 214, pattern: PACKAGE_PATTERN });
validateString(manifest.catalog.version, "$.catalog.version", issues, { maximum: 64, pattern: /^[0-9A-Za-z][0-9A-Za-z.+-]*$/ });
validateString(manifest.catalog.integrity, "$.catalog.integrity", issues, { maximum: 71, pattern: DIGEST_PATTERN });
}
if (!Array.isArray(manifest.targets) || manifest.targets.length < 1 || manifest.targets.length > 8) {
issues.push(issue("$.targets", "AAS_STACK_TARGETS_INVALID"));
} else {
const seenTargets = new Set();
manifest.targets.forEach((target, index) => {
const path = `$.targets[${index}]`;
if (!isPlainObject(target)) {
issues.push(issue(path, "AAS_STACK_OBJECT_REQUIRED"));
return;
}
rejectUnknownKeys(target, new Set(["host", "scope"]), path, issues);
if (!SUPPORTED_HOSTS.has(target.host)) issues.push(issue(`${path}.host`, "AAS_STACK_TARGET_HOST_UNSUPPORTED"));
if (!SUPPORTED_SCOPES.has(target.scope)) issues.push(issue(`${path}.scope`, "AAS_STACK_TARGET_SCOPE_UNSUPPORTED"));
const key = `${target.host}:${target.scope}`;
if (seenTargets.has(key)) issues.push(issue(path, "AAS_STACK_TARGET_DUPLICATE"));
seenTargets.add(key);
});
}
if (!isPlainObject(manifest.intent)) {
issues.push(issue("$.intent", "AAS_STACK_OBJECT_REQUIRED"));
} else {
rejectUnknownKeys(manifest.intent, new Set(["goals"]), "$.intent", issues);
validateUniqueStringArray(manifest.intent.goals, "$.intent.goals", issues, {
minimum: 1,
maximum: 32,
pattern: ID_PATTERN,
});
}
if (!isPlainObject(manifest.policy)) {
issues.push(issue("$.policy", "AAS_STACK_OBJECT_REQUIRED"));
} else {
rejectUnknownKeys(
manifest.policy,
new Set(["allowedRisk", "requireKnownSource", "allowManualSetup"]),
"$.policy",
issues,
);
validateUniqueStringArray(manifest.policy.allowedRisk, "$.policy.allowedRisk", issues, {
minimum: 1,
maximum: 5,
allowed: SUPPORTED_RISKS,
});
for (const key of ["requireKnownSource", "allowManualSetup"]) {
if (typeof manifest.policy[key] !== "boolean") issues.push(issue(`$.policy.${key}`, "AAS_STACK_BOOLEAN_REQUIRED"));
}
}
if (!Array.isArray(manifest.skills) || manifest.skills.length > 128) {
issues.push(issue("$.skills", "AAS_STACK_SKILLS_INVALID"));
} else {
const seenSkills = new Set();
manifest.skills.forEach((skill, index) => {
const path = `$.skills[${index}]`;
if (!isPlainObject(skill)) {
issues.push(issue(path, "AAS_STACK_OBJECT_REQUIRED"));
return;
}
rejectUnknownKeys(skill, new Set(["id"]), path, issues);
if (validateString(skill.id, `${path}.id`, issues, { maximum: 256, pattern: ID_PATTERN })) {
if (seenSkills.has(skill.id)) issues.push(issue(`${path}.id`, "AAS_STACK_SKILL_DUPLICATE"));
seenSkills.add(skill.id);
}
});
}
if (issues.length) return invalidResult(issues);
const serialized = canonicalJson(manifest);
return {
schemaVersion: 1,
ok: true,
status: "valid",
...versions,
reasonCodes: [],
unknown: [],
details: {},
manifest,
canonicalJson: serialized,
manifestDigest: sha256(serialized),
};
}
module.exports = {
DIGEST_PATTERN,
ID_PATTERN,
SUPPORTED_HOSTS,
SUPPORTED_SCOPES,
validateManifest,
};
@@ -0,0 +1,356 @@
"use strict";
const versions = require("../versions");
const { canonicalJson, canonicalize, sha256 } = require("../canonical-json");
const { DIGEST_PATTERN, ID_PATTERN, validateManifest } = require("./manifest");
const { validateInstance } = require("../schema-validator");
const VERSION_KEYS = Object.freeze([
"protocolVersion",
"coreVersion",
"metadataSchemaVersion",
"scorerVersion",
]);
const OPERATION_KINDS = new Set(["install", "replaceManaged", "removeManaged"]);
const OVERRIDE_KINDS = new Set(["discoveryCandidate", "managedDrift"]);
const OPERATION_ORDER = Object.freeze({ removeManaged: 0, replaceManaged: 1, install: 2 });
function compareStrings(left, right) {
return left < right ? -1 : (left > right ? 1 : 0);
}
function planError(code, category, details = {}) {
const error = new Error(code);
error.code = code;
error.category = category;
error.details = details;
return error;
}
function assertPlainObject(value, name) {
const prototype = value && typeof value === "object" ? Object.getPrototypeOf(value) : null;
if (!value || Array.isArray(value) || (prototype !== Object.prototype && prototype !== null)) {
throw planError("AAS_PLAN_INPUT_INVALID", "invalidInput", { field: name });
}
}
function assertExactKeys(value, allowed, field) {
const unknown = Object.keys(value).filter((key) => !allowed.has(key)).sort();
if (unknown.length) throw planError("AAS_PLAN_FIELD_UNKNOWN", "invalidInput", { field, keys: unknown });
}
function assertDigest(value, field) {
if (typeof value !== "string" || !DIGEST_PATTERN.test(value)) {
throw planError("AAS_PLAN_DIGEST_INVALID", "invalidInput", { field });
}
}
function assertNonEmptyString(value, field, maximum = 256) {
if (typeof value !== "string" || value.length < 1 || value.length > maximum) {
throw planError("AAS_PLAN_STRING_INVALID", "invalidInput", { field });
}
}
function assertVersionHandshake(handshake) {
assertPlainObject(handshake, "handshake");
assertExactKeys(handshake, new Set(VERSION_KEYS), "handshake");
const incompatible = VERSION_KEYS.filter((key) => handshake[key] !== versions[key]);
if (incompatible.length) {
throw planError("AAS_PLAN_VERSION_INCOMPATIBLE", "incompatibleVersion", {
fields: incompatible,
expected: Object.fromEntries(incompatible.map((key) => [key, versions[key]])),
received: Object.fromEntries(incompatible.map((key) => [key, handshake[key] ?? null])),
});
}
return Object.fromEntries(VERSION_KEYS.map((key) => [key, versions[key]]));
}
function normalizeCatalog(catalog, manifestCatalog) {
assertPlainObject(catalog, "catalog");
assertExactKeys(catalog, new Set(["package", "version", "integrity"]), "catalog");
for (const key of ["package", "version", "integrity"]) {
if (catalog[key] !== manifestCatalog[key]) {
throw planError("AAS_PLAN_CATALOG_MISMATCH", "integrity", { field: key });
}
}
assertDigest(catalog.integrity, "catalog.integrity");
return { package: catalog.package, version: catalog.version, integrity: catalog.integrity };
}
function normalizeRuntime(runtime) {
assertPlainObject(runtime, "runtime");
assertExactKeys(runtime, new Set(["package", "version", "integrity", "closureDigest"]), "runtime");
assertNonEmptyString(runtime.package, "runtime.package", 214);
assertNonEmptyString(runtime.version, "runtime.version", 64);
assertNonEmptyString(runtime.integrity, "runtime.integrity", 512);
assertDigest(runtime.closureDigest, "runtime.closureDigest");
return { ...runtime };
}
function normalizeTarget(target, manifest) {
assertPlainObject(target, "target");
assertExactKeys(target, new Set(["host", "scope", "adapterVersion", "identityDigest"]), "target");
assertNonEmptyString(target.adapterVersion, "target.adapterVersion", 64);
assertDigest(target.identityDigest, "target.identityDigest");
if (!manifest.targets.some((candidate) => candidate.host === target.host && candidate.scope === target.scope)) {
throw planError("AAS_PLAN_TARGET_NOT_IN_MANIFEST", "invalidInput", { host: target.host, scope: target.scope });
}
return { ...target };
}
function normalizeInstalledState(installedState) {
assertPlainObject(installedState, "installedState");
assertExactKeys(installedState, new Set(["digest", "entries"]), "installedState");
assertDigest(installedState.digest, "installedState.digest");
if (!Array.isArray(installedState.entries) || installedState.entries.length > 128) {
throw planError("AAS_PLAN_INSTALLED_STATE_INVALID", "invalidInput", {});
}
const seen = new Set();
const entries = installedState.entries.map((entry, index) => {
assertPlainObject(entry, `installedState.entries[${index}]`);
assertExactKeys(entry, new Set(["skillId", "treeDigest", "catalogIntegrity"]), `installedState.entries[${index}]`);
if (typeof entry.skillId !== "string" || !ID_PATTERN.test(entry.skillId) || seen.has(entry.skillId)) {
throw planError("AAS_PLAN_INSTALLED_ENTRY_INVALID", "invalidInput", { index });
}
seen.add(entry.skillId);
assertDigest(entry.treeDigest, `installedState.entries[${index}].treeDigest`);
assertDigest(entry.catalogIntegrity, `installedState.entries[${index}].catalogIntegrity`);
return { ...entry };
});
entries.sort((left, right) => compareStrings(left.skillId, right.skillId));
const computedDigest = sha256(canonicalJson({ schemaVersion: 1, entries }));
if (installedState.digest !== computedDigest) {
throw planError("AAS_PLAN_INSTALLED_STATE_DIGEST_MISMATCH", "integrity", {});
}
return { digest: installedState.digest, entries };
}
function normalizeOperation(operation, index, desiredSkillIds) {
assertPlainObject(operation, `operations[${index}]`);
assertExactKeys(
operation,
new Set(["kind", "skillId", "sourceTreeDigest", "expectedTreeDigest", "resultTreeDigest", "backupRequired"]),
`operations[${index}]`,
);
if (!OPERATION_KINDS.has(operation.kind) || typeof operation.skillId !== "string" || !ID_PATTERN.test(operation.skillId)) {
throw planError("AAS_PLAN_OPERATION_INVALID", "invalidInput", { index });
}
if (operation.kind !== "removeManaged" && !desiredSkillIds.has(operation.skillId)) {
throw planError("AAS_PLAN_OPERATION_SKILL_NOT_DESIRED", "invalidInput", { index, skillId: operation.skillId });
}
if (operation.kind === "removeManaged" && desiredSkillIds.has(operation.skillId)) {
throw planError("AAS_PLAN_REMOVE_SKILL_STILL_DESIRED", "invalidInput", { index, skillId: operation.skillId });
}
if (operation.kind === "install") {
if (operation.expectedTreeDigest !== null || operation.backupRequired !== false) {
throw planError("AAS_PLAN_OPERATION_PRECONDITION_INVALID", "invalidInput", { index });
}
assertDigest(operation.sourceTreeDigest, `operations[${index}].sourceTreeDigest`);
assertDigest(operation.resultTreeDigest, `operations[${index}].resultTreeDigest`);
if (operation.sourceTreeDigest !== operation.resultTreeDigest) {
throw planError("AAS_PLAN_OPERATION_RESULT_MISMATCH", "integrity", { index });
}
} else if (operation.kind === "replaceManaged") {
assertDigest(operation.sourceTreeDigest, `operations[${index}].sourceTreeDigest`);
assertDigest(operation.expectedTreeDigest, `operations[${index}].expectedTreeDigest`);
assertDigest(operation.resultTreeDigest, `operations[${index}].resultTreeDigest`);
if (operation.sourceTreeDigest !== operation.resultTreeDigest) {
throw planError("AAS_PLAN_OPERATION_RESULT_MISMATCH", "integrity", { index });
}
if (operation.backupRequired !== true) {
throw planError("AAS_PLAN_OPERATION_BACKUP_REQUIRED", "invalidInput", { index });
}
} else {
if (operation.sourceTreeDigest !== null || operation.resultTreeDigest !== null || operation.backupRequired !== true) {
throw planError("AAS_PLAN_OPERATION_PRECONDITION_INVALID", "invalidInput", { index });
}
assertDigest(operation.expectedTreeDigest, `operations[${index}].expectedTreeDigest`);
}
return { ...operation };
}
function normalizeOperations(operations, manifest) {
if (!Array.isArray(operations) || operations.length > 256) {
throw planError("AAS_PLAN_OPERATIONS_INVALID", "invalidInput", {});
}
const desiredSkillIds = new Set(manifest.skills.map((skill) => skill.id));
const normalized = operations.map((operation, index) => normalizeOperation(operation, index, desiredSkillIds));
const seen = new Set();
for (const operation of normalized) {
if (seen.has(operation.skillId)) {
throw planError("AAS_PLAN_OPERATION_DUPLICATE", "invalidInput", { skillId: operation.skillId });
}
seen.add(operation.skillId);
}
return normalized.sort((left, right) => (
OPERATION_ORDER[left.kind] - OPERATION_ORDER[right.kind]
|| compareStrings(left.skillId, right.skillId)
));
}
function normalizeOverrides(overrides, operationIds, desiredSkillIds) {
if (!Array.isArray(overrides) || overrides.length > 128) {
throw planError("AAS_PLAN_OVERRIDES_INVALID", "invalidInput", {});
}
const seen = new Set();
const normalized = overrides.map((override, index) => {
assertPlainObject(override, `overrides[${index}]`);
assertExactKeys(override, new Set(["kind", "skillId", "reasonCodes", "unknownFields"]), `overrides[${index}]`);
const skillAllowed = override.kind === "discoveryCandidate"
? desiredSkillIds.has(override.skillId)
: operationIds.has(override.skillId);
if (!OVERRIDE_KINDS.has(override.kind) || typeof override.skillId !== "string" || !skillAllowed) {
throw planError("AAS_PLAN_OVERRIDE_INVALID", "invalidInput", { index });
}
if (!Array.isArray(override.reasonCodes) || override.reasonCodes.length < 1 || override.reasonCodes.some((value) => typeof value !== "string")) {
throw planError("AAS_PLAN_OVERRIDE_REASON_REQUIRED", "invalidInput", { index });
}
if (!Array.isArray(override.unknownFields) || override.unknownFields.some((value) => typeof value !== "string")) {
throw planError("AAS_PLAN_OVERRIDE_UNKNOWN_FIELDS_INVALID", "invalidInput", { index });
}
const key = `${override.kind}:${override.skillId}`;
if (seen.has(key)) throw planError("AAS_PLAN_OVERRIDE_DUPLICATE", "invalidInput", { index });
seen.add(key);
return {
kind: override.kind,
skillId: override.skillId,
reasonCodes: [...new Set(override.reasonCodes)].sort(),
unknownFields: [...new Set(override.unknownFields)].sort(),
};
});
return normalized.sort((left, right) => compareStrings(`${left.kind}:${left.skillId}`, `${right.kind}:${right.skillId}`));
}
function normalizeStateCommit(stateCommit, installedStateDigest) {
assertPlainObject(stateCommit, "stateCommit");
assertExactKeys(stateCommit, new Set(["previousDigest", "nextDigest", "position"]), "stateCommit");
if (stateCommit.previousDigest !== installedStateDigest) {
throw planError("AAS_PLAN_STATE_COMMIT_MISMATCH", "drift", {});
}
assertDigest(stateCommit.nextDigest, "stateCommit.nextDigest");
if (stateCommit.position !== "final") throw planError("AAS_PLAN_STATE_COMMIT_NOT_FINAL", "invalidInput", {});
return { ...stateCommit };
}
function expectedNextStateDigest(installedState, operations, catalogIntegrity) {
const entries = new Map(installedState.entries.map((entry) => [entry.skillId, entry]));
for (const operation of operations) {
if (operation.kind === "removeManaged") entries.delete(operation.skillId);
else entries.set(operation.skillId, {
skillId: operation.skillId,
treeDigest: operation.resultTreeDigest,
catalogIntegrity,
});
}
const normalized = [...entries.values()].sort((left, right) => compareStrings(left.skillId, right.skillId));
return sha256(canonicalJson({ schemaVersion: 1, entries: normalized }));
}
function buildPlanEnvelope(input) {
assertPlainObject(input, "input");
assertExactKeys(
input,
new Set(["manifest", "handshake", "catalog", "runtime", "target", "installedState", "operations", "overrides", "stateCommit"]),
"input",
);
const validation = validateManifest(input.manifest);
if (!validation.ok) throw planError("AAS_PLAN_MANIFEST_INVALID", "invalidInput", validation.details);
const boundVersions = assertVersionHandshake(input.handshake);
const catalog = normalizeCatalog(input.catalog, input.manifest.catalog);
const runtime = normalizeRuntime(input.runtime);
const target = normalizeTarget(input.target, input.manifest);
const installedState = normalizeInstalledState(input.installedState);
const operations = normalizeOperations(input.operations, input.manifest);
const operationIds = new Set(operations.map((operation) => operation.skillId));
const desiredSkillIds = new Set(input.manifest.skills.map((skill) => skill.id));
const overrides = normalizeOverrides(input.overrides ?? [], operationIds, desiredSkillIds);
const stateCommit = normalizeStateCommit(input.stateCommit, installedState.digest);
if (runtime.package !== catalog.package || runtime.version !== catalog.version) {
throw planError("AAS_PLAN_RUNTIME_CATALOG_MISMATCH", "integrity", {});
}
if (stateCommit.nextDigest !== expectedNextStateDigest(installedState, operations, catalog.integrity)) {
throw planError("AAS_PLAN_NEXT_STATE_MISMATCH", "integrity", {});
}
const payload = canonicalize({
schemaVersion: 1,
kind: "aas.stack-plan.payload",
versions: boundVersions,
manifestDigest: validation.manifestDigest,
catalog,
runtime,
target,
installedState,
desiredSkills: input.manifest.skills.map((skill) => skill.id).sort(),
policy: input.manifest.policy,
operations,
overrides,
stateCommit,
});
const payloadJson = canonicalJson(payload);
return validateInstance("plan.schema.json", {
schemaVersion: 1,
kind: "aas.stack-plan",
digest: sha256(payloadJson),
payload,
}, "AAS_PLAN_SCHEMA_INVALID", "invalidInput");
}
function validatePlanEnvelope(plan) {
validateInstance("plan.schema.json", plan, "AAS_TRANSACTION_PLAN_SCHEMA_INVALID");
assertPlainObject(plan, "plan");
assertExactKeys(plan, new Set(["schemaVersion", "kind", "digest", "payload"]), "plan");
if (plan.schemaVersion !== 1 || plan.kind !== "aas.stack-plan") {
throw planError("AAS_TRANSACTION_PLAN_INVALID", "integrity", {});
}
assertDigest(plan.digest, "plan.digest");
assertPlainObject(plan.payload, "plan.payload");
assertExactKeys(plan.payload, new Set([
"schemaVersion", "kind", "versions", "manifestDigest", "catalog", "runtime", "target",
"installedState", "desiredSkills", "policy", "operations", "overrides", "stateCommit",
]), "plan.payload");
if (plan.payload.schemaVersion !== 1 || plan.payload.kind !== "aas.stack-plan.payload"
|| plan.digest !== sha256(canonicalJson(plan.payload))) {
throw planError("AAS_TRANSACTION_PLAN_INVALID", "integrity", {});
}
assertDigest(plan.payload.manifestDigest, "manifestDigest");
if (!Array.isArray(plan.payload.desiredSkills) || plan.payload.desiredSkills.length > 128
|| plan.payload.desiredSkills.some((id) => typeof id !== "string" || !ID_PATTERN.test(id))) {
throw planError("AAS_PLAN_DESIRED_SKILLS_INVALID", "invalidInput", {});
}
const syntheticManifest = {
schemaVersion: 1,
name: "validated-plan",
catalog: plan.payload.catalog,
targets: [{ host: plan.payload.target?.host, scope: plan.payload.target?.scope }],
intent: { goals: ["validate"] },
policy: plan.payload.policy,
skills: plan.payload.desiredSkills.map((id) => ({ id })),
};
const rebuilt = buildPlanEnvelope({
manifest: syntheticManifest,
handshake: plan.payload.versions,
catalog: plan.payload.catalog,
runtime: plan.payload.runtime,
target: plan.payload.target,
installedState: plan.payload.installedState,
operations: plan.payload.operations,
overrides: plan.payload.overrides,
stateCommit: plan.payload.stateCommit,
});
const expectedPayload = { ...rebuilt.payload, manifestDigest: plan.payload.manifestDigest };
if (canonicalJson(expectedPayload) !== canonicalJson(plan.payload)) {
throw planError("AAS_TRANSACTION_PLAN_INVALID", "integrity", {});
}
return plan;
}
module.exports = {
OPERATION_KINDS,
OVERRIDE_KINDS,
VERSION_KEYS,
assertVersionHandshake,
buildPlanEnvelope,
validatePlanEnvelope,
};