Publish quixos-protocol from 932fe7714761fb8b5db4bd6401357cdff762a428
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
|
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
|
||||||
"sourceCommit": "abc91ab1cbbd61ffd7f0a49dbc5768598ac8745c",
|
"sourceCommit": "932fe7714761fb8b5db4bd6401357cdff762a428",
|
||||||
"sourcePath": "quixos-protocol",
|
"sourcePath": "quixos-protocol",
|
||||||
"exportName": "quixos-protocol",
|
"exportName": "quixos-protocol",
|
||||||
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface ArtifactFile {
|
|||||||
export interface ArtifactImplementation {
|
export interface ArtifactImplementation {
|
||||||
id: string;
|
id: string;
|
||||||
target: string;
|
target: string;
|
||||||
compatibility: "quixos-service-v1" | "quixos-js-module-v1";
|
compatibility: "quixos-service-v1" | "quixos-js-module-v1" | "quixos-restricted-module-v1";
|
||||||
path: string;
|
path: string;
|
||||||
ports: "quixos-transaction-ports-v1";
|
ports: "quixos-transaction-ports-v1";
|
||||||
registryExport?: string;
|
registryExport?: string;
|
||||||
@@ -225,7 +225,11 @@ export function parseArtifactGroup(value: unknown): ArtifactGroup {
|
|||||||
["registryExport"],
|
["registryExport"],
|
||||||
path,
|
path,
|
||||||
);
|
);
|
||||||
if (entry.compatibility !== "quixos-service-v1" && entry.compatibility !== "quixos-js-module-v1")
|
if (
|
||||||
|
!["quixos-service-v1", "quixos-js-module-v1", "quixos-restricted-module-v1"].includes(
|
||||||
|
String(entry.compatibility),
|
||||||
|
)
|
||||||
|
)
|
||||||
fail(path, "Unsupported artifact ABI");
|
fail(path, "Unsupported artifact ABI");
|
||||||
if (entry.ports !== "quixos-transaction-ports-v1") fail(path, "Unsupported transaction port ABI");
|
if (entry.ports !== "quixos-transaction-ports-v1") fail(path, "Unsupported transaction port ABI");
|
||||||
if (
|
if (
|
||||||
@@ -233,7 +237,9 @@ export function parseArtifactGroup(value: unknown): ArtifactGroup {
|
|||||||
(entry.target !== "server" || entry.registryExport !== undefined)
|
(entry.target !== "server" || entry.registryExport !== undefined)
|
||||||
)
|
)
|
||||||
fail(path, "Service must target server and has no JS registry export");
|
fail(path, "Service must target server and has no JS registry export");
|
||||||
if (entry.compatibility === "quixos-js-module-v1") text(entry.registryExport, `${path}.registryExport`);
|
if (entry.compatibility !== "quixos-service-v1") text(entry.registryExport, `${path}.registryExport`);
|
||||||
|
if (entry.compatibility === "quixos-restricted-module-v1" && entry.target !== "server")
|
||||||
|
fail(path, "Restricted modules must target server");
|
||||||
const exports = array(entry.exports, `${path}.exports`).map((value) => text(value, `${path}.exports`));
|
const exports = array(entry.exports, `${path}.exports`).map((value) => text(value, `${path}.exports`));
|
||||||
unique(exports, `${path}.exports`);
|
unique(exports, `${path}.exports`);
|
||||||
const files = parseArtifactFiles(entry.files, `${path}.files`);
|
const files = parseArtifactFiles(entry.files, `${path}.files`);
|
||||||
@@ -300,6 +306,11 @@ export function checkPackageCoverage(
|
|||||||
for (const id of implementation.exports) {
|
for (const id of implementation.exports) {
|
||||||
const entry = expected.exports.find((e) => e.id === id);
|
const entry = expected.exports.find((e) => e.id === id);
|
||||||
if (!entry) fail(implementation.id, `Unknown export ${id}`);
|
if (!entry) fail(implementation.id, `Unknown export ${id}`);
|
||||||
|
if (
|
||||||
|
implementation.compatibility === "quixos-restricted-module-v1" &&
|
||||||
|
(entry!.execution.kind === "remote" || !entry!.execution.targets.includes("server"))
|
||||||
|
)
|
||||||
|
fail(implementation.id, `Export ${id} does not promise restricted server computation`);
|
||||||
if (
|
if (
|
||||||
implementation.target !== "server" &&
|
implementation.target !== "server" &&
|
||||||
(!entry?.execution ||
|
(!entry?.execution ||
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ export interface ExecutionInstallation {
|
|||||||
readonly root: string;
|
readonly root: string;
|
||||||
readonly service?: ArtifactImplementation;
|
readonly service?: ArtifactImplementation;
|
||||||
readonly module?: ArtifactImplementation;
|
readonly module?: ArtifactImplementation;
|
||||||
|
/** Checked candidate only; the qualified host verifies its import surface and SDK. */
|
||||||
|
readonly restricted?: ArtifactImplementation;
|
||||||
readonly browserImplementation?: ArtifactImplementation;
|
readonly browserImplementation?: ArtifactImplementation;
|
||||||
readonly browserURL?: string;
|
readonly browserURL?: string;
|
||||||
readonly browserRegistry?: string;
|
readonly browserRegistry?: string;
|
||||||
@@ -251,6 +253,11 @@ function assembleExecutionInstallation(
|
|||||||
exports: exports.map((entry) => entry.id),
|
exports: exports.map((entry) => entry.id),
|
||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
const restrictedCandidates = manifest.implementations.filter(
|
||||||
|
(entry) => entry.compatibility === "quixos-restricted-module-v1",
|
||||||
|
);
|
||||||
|
if (restrictedCandidates.length > 1) fail(revision, "Ambiguous restricted module candidates");
|
||||||
|
const restricted = restrictedCandidates[0];
|
||||||
const browserExports = exports.filter(
|
const browserExports = exports.filter(
|
||||||
(entry) =>
|
(entry) =>
|
||||||
entry.execution.kind !== "remote" &&
|
entry.execution.kind !== "remote" &&
|
||||||
@@ -258,7 +265,13 @@ function assembleExecutionInstallation(
|
|||||||
);
|
);
|
||||||
if (!browserExports.length) {
|
if (!browserExports.length) {
|
||||||
if (selection.browser) fail(revision, "Package has no browser exports to select");
|
if (selection.browser) fail(revision, "Package has no browser exports to select");
|
||||||
packages.push({ revision, root, ...(service ? { service } : {}), ...(module ? { module } : {}) });
|
packages.push({
|
||||||
|
revision,
|
||||||
|
root,
|
||||||
|
...(service ? { service } : {}),
|
||||||
|
...(module ? { module } : {}),
|
||||||
|
...(restricted ? { restricted } : {}),
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const browser = selectArtifactImplementation(manifest, {
|
const browser = selectArtifactImplementation(manifest, {
|
||||||
@@ -289,6 +302,7 @@ function assembleExecutionInstallation(
|
|||||||
root,
|
root,
|
||||||
...(service ? { service } : {}),
|
...(service ? { service } : {}),
|
||||||
...(module ? { module } : {}),
|
...(module ? { module } : {}),
|
||||||
|
...(restricted ? { restricted } : {}),
|
||||||
browserImplementation: browser,
|
browserImplementation: browser,
|
||||||
browserURL: contentArtifactUrl(entry),
|
browserURL: contentArtifactUrl(entry),
|
||||||
browserRegistry: browser.registryExport,
|
browserRegistry: browser.registryExport,
|
||||||
|
|||||||
@@ -23,6 +23,39 @@ export interface ImportFinding {
|
|||||||
readonly detail: string;
|
readonly detail: string;
|
||||||
readonly line: number | null;
|
readonly line: number | null;
|
||||||
}
|
}
|
||||||
|
export const restrictedSDKSpecifier = "quixos:restricted-sdk/v1";
|
||||||
|
export const restrictedSDKPath = "share/quixos/restricted/core.mjs";
|
||||||
|
|
||||||
|
/** Mechanical candidate checks, not authorization or an engine-safety proof.
|
||||||
|
* The caller must first verify the manifest and all declared file digests. */
|
||||||
|
export async function inspectRestrictedImplementation(
|
||||||
|
revision: string,
|
||||||
|
implementation: ArtifactImplementation,
|
||||||
|
read: ArtifactReader,
|
||||||
|
qualifiedSDKDigest?: string,
|
||||||
|
): Promise<ImportFinding[]> {
|
||||||
|
const entry = implementation.files.find((file) => file.path === implementation.path);
|
||||||
|
const sdk = implementation.files.find((file) => file.path === restrictedSDKPath);
|
||||||
|
if (
|
||||||
|
implementation.compatibility !== "quixos-restricted-module-v1" ||
|
||||||
|
implementation.target !== "server" ||
|
||||||
|
implementation.files.length !== 2 ||
|
||||||
|
!entry ||
|
||||||
|
!sdk ||
|
||||||
|
entry === sdk ||
|
||||||
|
entry.mediaType !== "text/javascript" ||
|
||||||
|
sdk.mediaType !== "text/javascript" ||
|
||||||
|
!/^[$A-Z_a-z][$\w]*$/.test(implementation.registryExport ?? "")
|
||||||
|
)
|
||||||
|
return [{ code: "RESTRICTED_CLOSURE", detail: "Expected one closed module and the restricted SDK", line: null }];
|
||||||
|
if (qualifiedSDKDigest && sdk.digest !== qualifiedSDKDigest)
|
||||||
|
return [{ code: "RESTRICTED_SDK_UNSUPPORTED", detail: "SDK differs from the qualified host profile", line: null }];
|
||||||
|
if (entry.bytes > 1024 * 1024 || sdk.bytes > 2 * 1024 * 1024)
|
||||||
|
return [{ code: "ANALYSIS_LIMIT", detail: "Restricted closure exceeds the source budget", line: null }];
|
||||||
|
return inspectJavaScriptSurface(Buffer.from(await read(revision, entry.path, entry.bytes)).toString("utf8"), [
|
||||||
|
restrictedSDKSpecifier,
|
||||||
|
]);
|
||||||
|
}
|
||||||
const nativeImports = new Set(builtinModules.flatMap((name) => [name, name.replace(/^node:/, "")]));
|
const nativeImports = new Set(builtinModules.flatMap((name) => [name, name.replace(/^node:/, "")]));
|
||||||
const ambient = new Set([
|
const ambient = new Set([
|
||||||
"process",
|
"process",
|
||||||
@@ -136,10 +169,8 @@ export function inspectJavaScriptSurface(source: string, checkedSDKImports: read
|
|||||||
return findings;
|
return findings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Derived metadata only. Browser/server portability and available targets say
|
/** Derived metadata only. A build report can describe a closed candidate but
|
||||||
* nothing about sandbox eligibility. Build reports have no platform approval
|
* cannot qualify the host's engine, SDK, OS sandbox or resource controller. */
|
||||||
* catalog, so they conservatively require VM placement. A host can override
|
|
||||||
* placement only for independently reviewed, exact restricted-code approvals. */
|
|
||||||
export async function reportExecutionPlacement(
|
export async function reportExecutionPlacement(
|
||||||
plan: ExecutionPlan,
|
plan: ExecutionPlan,
|
||||||
installation: ExecutionInstallation,
|
installation: ExecutionInstallation,
|
||||||
@@ -156,11 +187,13 @@ export async function reportExecutionPlacement(
|
|||||||
const packages = await Promise.all(
|
const packages = await Promise.all(
|
||||||
installation.packages.map(async (pkg) => {
|
installation.packages.map(async (pkg) => {
|
||||||
const implementations: { id: string; digest: string; compatibility: string; findings: ImportFinding[] }[] = [];
|
const implementations: { id: string; digest: string; compatibility: string; findings: ImportFinding[] }[] = [];
|
||||||
for (const implementation of [pkg.service, pkg.module].filter(
|
for (const implementation of [pkg.service, pkg.module, pkg.restricted].filter(
|
||||||
(entry): entry is ArtifactImplementation => !!entry,
|
(entry): entry is ArtifactImplementation => !!entry,
|
||||||
)) {
|
)) {
|
||||||
let findings: ImportFinding[];
|
let findings: ImportFinding[];
|
||||||
if (implementation.compatibility === "quixos-js-module-v1") {
|
if (implementation.compatibility === "quixos-restricted-module-v1")
|
||||||
|
findings = await inspectRestrictedImplementation(pkg.revision, implementation, read);
|
||||||
|
else if (implementation.compatibility === "quixos-js-module-v1") {
|
||||||
const file = implementation.files.find((file) => file.path === implementation.path)!;
|
const file = implementation.files.find((file) => file.path === implementation.path)!;
|
||||||
if (!file || file.bytes > 1024 * 1024)
|
if (!file || file.bytes > 1024 * 1024)
|
||||||
findings = [
|
findings = [
|
||||||
@@ -192,7 +225,14 @@ export async function reportExecutionPlacement(
|
|||||||
revision: pkg.revision,
|
revision: pkg.revision,
|
||||||
requiresVM: implementations.length > 0,
|
requiresVM: implementations.length > 0,
|
||||||
restrictedEligible: false as const,
|
restrictedEligible: false as const,
|
||||||
reason: "NO_QUALIFIED_RESTRICTED_RUNTIME",
|
reason: pkg.restricted ? "HOST_PROFILE_QUALIFICATION_REQUIRED" : "NO_RESTRICTED_IMPLEMENTATION",
|
||||||
|
restrictedCandidate: pkg.restricted
|
||||||
|
? {
|
||||||
|
digest: pkg.restricted.contentDigest,
|
||||||
|
exports: pkg.restricted.exports,
|
||||||
|
compatible: implementations.find((entry) => entry.id === pkg.restricted!.id)!.findings.length === 0,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
implementations,
|
implementations,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user