Compare commits

...
Author SHA1 Message Date
Quixos Subtree Publisher 9fae801b7f Publish quixos-protocol from 286ada5419c4fc2184b387cea4715fae1a74bde5 2026-10-10 00:10:14 +00:00
Timothy J. Aveni 2ae7f00acb Reuse checked bootstrap catalogs and coordinate execution deadlines 2026-10-09 17:10:14 -07:00
Timothy J. Aveni 041a9e26ad Document package architecture and organize current guidance and project backlog 2026-10-09 10:33:39 -07:00
Quixos Subtree Publisher 7f3fdfe64e Publish quixos-protocol from d1ab9c912133511cfd3de65550965e0e8806678f 2026-10-08 19:32:06 +00:00
Timothy J. Aveni 0a7bdf7657 Qualify restricted SDK syntax independently of build architecture 2026-10-08 12:32:06 -07:00
Quixos Subtree Publisher 137dcaa101 Publish quixos-protocol from 2ef07e2524ed167421be56b81a5f498a2759ca5d 2026-10-08 19:30:33 +00:00
Timothy J. Aveni a86de3fe5b Qualify restricted SDK syntax independently of build architecture 2026-10-08 12:30:33 -07:00
Timothy J. Aveni 165510341d Repair packed agent startup and bound activation metadata retention 2026-10-08 11:19:19 -07:00
Quixos Subtree Publisher b406738249 Publish quixos-protocol from 11d2ad06170609a09118cbabd4245b5828a148d1 2026-10-08 18:19:19 +00:00
Timothy J. Aveni ffd728b061 Keep pin-upgraded workbench paths relative for relocation 2026-10-08 07:59:49 -07:00
Quixos Subtree Publisher e78b7adf28 Publish quixos-protocol from c4319441699b7b8c5af7e70dade6e4ad8cccddea 2026-10-08 14:59:49 +00:00
Timothy J. Aveni a935273913 Use execution workspace review semantics during bottom-up pin upgrades 2026-10-08 07:43:32 -07:00
Quixos Subtree Publisher e162dc3013 Publish quixos-protocol from e4075003e669be0e307ec8c0585cccb1bd08276a 2026-10-08 14:43:32 +00:00
Quixos Subtree Publisher e65ddad798 Publish quixos-protocol from 932fe7714761fb8b5db4bd6401357cdff762a428 2026-10-08 05:08:28 +00:00
Timothy J. Aveni 31a48e746d Admit checked restricted artifacts without individual code approvals 2026-10-07 21:43:44 -07:00
13 changed files with 567 additions and 64 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"version": 1,
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
"sourceCommit": "abc91ab1cbbd61ffd7f0a49dbc5768598ac8745c",
"sourceCommit": "286ada5419c4fc2184b387cea4715fae1a74bde5",
"sourcePath": "quixos-protocol",
"exportName": "quixos-protocol",
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
+45 -7
View File
@@ -15,7 +15,12 @@ import {
} from "./assembly.js";
import { createGitCapabilityResolver } from "./git-resolver.js";
import { snapshotCommit, buildImmutableCandidate } from "./checked-build.js";
import { planEvolution, type WorkspaceRevision, type EvolutionReview } from "../capability-model/index.js";
import {
planEvolution,
reviewSemanticMajors,
type WorkspaceRevision,
type EvolutionReview,
} from "../capability-model/index.js";
import { withFileLock } from "./file-lock.js";
const execFile = promisify(callback);
type Source = { repository: string; commit: string };
@@ -187,6 +192,34 @@ export type UpgradeEffects = {
snapshot(root: string): Promise<string>;
publish(root: string, commit: string): Promise<void>;
};
/** Review a successfully built immutable candidate using the same boundary as
* ordinary authoring checks. Execution storage compatibility is checked against
* the current graph at activation; the legacy evolution model is not its schema.
*/
export async function reviewUpgradeCandidate({
artifact,
baseline,
candidate,
reviews = [],
}: {
artifact: string;
baseline: WorkspaceRevision | null;
candidate: WorkspaceRevision;
reviews?: EvolutionReview[];
}) {
let execution = false;
try {
await fs.access(path.join(artifact, "execution-plan.json"));
execution = true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
}
return execution
? { filename: "semantic-review.json", review: reviewSemanticMajors(baseline, candidate, reviews) }
: { filename: "evolution.json", review: planEvolution(baseline, candidate, { reviews }) };
}
const effects: UpgradeEffects = {
async check(node, root, output, spec) {
if (node.kind === "workspace" && !spec.baseline && !spec.bootstrap)
@@ -206,10 +239,15 @@ const effects: UpgradeEffects = {
? (JSON.parse(await fs.readFile(spec.baseline, "utf8")) as WorkspaceRevision)
: null;
const reviews = spec.reviews ? (JSON.parse(await fs.readFile(spec.reviews, "utf8")) as EvolutionReview[]) : [];
const evolution = planEvolution(baseline, JSON.parse(candidate), { reviews });
await fs.writeFile(path.join(output, "evolution.json"), JSON.stringify(evolution, null, 2));
if (evolution.blockers.length)
throw new Error(`Refactor required in ${node.directory}: ${evolution.blockers.join("; ")}`);
const { filename, review } = await reviewUpgradeCandidate({
artifact,
baseline,
candidate: JSON.parse(candidate),
reviews,
});
await fs.writeFile(path.join(output, filename), JSON.stringify(review, null, 2));
if (review.blockers.length)
throw new Error(`Refactor required in ${node.directory}: ${review.blockers.join("; ")}`);
}
},
async snapshot(root) {
@@ -443,13 +481,13 @@ export const applyPinUpgrades = async (
quixos: compiled.lock.quixos,
directResources: [...compiled.directResources.entries()].map(([bindingKey, node]) => {
const [kind, binding] = bindingKey.split("\0");
return { kind, binding, resourceKey: node.key, directory: node.directory };
return { kind, binding, resourceKey: node.key, directory: path.relative(plan.workbench, node.directory) };
}),
resources: [...resources.values()].map((node) => ({
key: node.key,
kind: node.kind,
source: node.source,
directory: node.directory,
directory: path.relative(plan.workbench, node.directory),
...(node.resource.kind === "build"
? {}
: {
+11 -5
View File
@@ -1,5 +1,11 @@
# Closed execution plans and artifacts
This page documents current compiler/runtime representations. Its universal
artifact inventory, React metadata and overlapping world/installation structures
are [known architectural gaps](../../../docs/ARCHITECTURE_STATUS.md), not the
[core package contract](../../../docs/ARCHITECTURE.md). Historical LF task numbers
refer to the original implementation sequence, not an active queue.
`compileExecutionPlan` validates a workspace, links its checked queries, resolves
public forwarding, and emits one versioned plan with an SHA-256 digest. It retains
exact interface/package revisions and generic applications, owner initialization,
@@ -60,11 +66,11 @@ the core codec's canonical ordering and domain-separated SHA-256 framing. The
monorepo `camino-execution-world` check compares the compiler and core implementations.
No machine-local Nix path enters the world descriptor.
The current binding schema is the closed workspace schema. This is conservative:
an unrelated contract change can require checking/rebuilding several packages.
LF-05 may narrow it to exact checked per-package closures, but must use the same
schema for generation, receipts, and world validation. It must not substitute an
older package schema just because the source revision did not change.
Reusable package compilation now receives a canonical per-package build contract;
exact source provenance and workspace linking remain separate. See
[package build contracts](../../../docs/PACKAGE_BUILD_CONTRACTS.md). Generation,
receipts and checking must agree on that contract; unchanged source alone does
not justify reusing an incompatible binding schema.
## Transaction-port ABI
+14 -3
View File
@@ -11,7 +11,7 @@ export interface ArtifactFile {
export interface ArtifactImplementation {
id: 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;
ports: "quixos-transaction-ports-v1";
registryExport?: string;
@@ -225,7 +225,11 @@ export function parseArtifactGroup(value: unknown): ArtifactGroup {
["registryExport"],
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");
if (entry.ports !== "quixos-transaction-ports-v1") fail(path, "Unsupported transaction port ABI");
if (
@@ -233,7 +237,9 @@ export function parseArtifactGroup(value: unknown): ArtifactGroup {
(entry.target !== "server" || entry.registryExport !== undefined)
)
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`));
unique(exports, `${path}.exports`);
const files = parseArtifactFiles(entry.files, `${path}.files`);
@@ -300,6 +306,11 @@ export function checkPackageCoverage(
for (const id of implementation.exports) {
const entry = expected.exports.find((e) => e.id === 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 (
implementation.target !== "server" &&
(!entry?.execution ||
+43 -22
View File
@@ -2,7 +2,11 @@ import { graphExecutionRepresentation } from "./graph-execution.js";
import { lstat } from "node:fs/promises";
import { join } from "node:path";
import { hexDigest, ExecutionPlanError, type ExecutionPlan } from "./plan.js";
import { loadExecutionInstallation, type PackageInstallationSelection } from "./installation.js";
import {
loadExecutionInstallation,
createClientContractCatalog,
type PackageInstallationSelection,
} from "./installation.js";
import {
candidateMetadataBudget,
readCandidateMetadata,
@@ -36,33 +40,37 @@ export async function loadCheckedInstallationCandidate(
if (!rootPattern.test(root) || !(await lstat(root)).isDirectory())
throw Error("Candidate must be an immutable Nix output directory");
const scope = (resources.budget ?? candidateMetadataBudget).acquire(resources.owner ?? root);
let releaseValidation = () => {};
try {
// Validate the duplicated source contract by digest, then discard its tree
// before allocating the substantially larger checked execution plan.
const workspaceDigest = await (async () => {
const input = await readJson(root, "candidate.json", scope);
try {
const { executionContracts: _legacyContracts, ...workspace } = input.value;
return hexDigest(workspace);
} finally {
input.releaseTree();
}
})();
// Sequential reads avoid partially rejected Promise.all() work allocating
// after the failed candidate's reservation has been released.
const values = [];
for (const file of [
"candidate.json",
"execution-plan.json",
"execution-artifacts.json",
"source.json",
"entry.json",
"kernel.json",
"queries.json",
"graph-execution.json",
]) {
const parsed = await readJson(root, file, scope);
values.push(parsed.value);
// candidate.json duplicates the checked plan for validation. Nothing in
// the installed candidate retains this input tree after validation.
if (file === "candidate.json") releaseValidation = parsed.releaseTree;
}
const [candidate, plan, artifacts, source, entryRequest, kernel, queries, graph] = values;
const { executionContracts: _legacyContracts, ...workspace } = candidate;
const [plan, artifacts, source, entryRequest, kernel, queries] = values;
if (
plan?.definition?.codec !== "camino-execution-plan-v1" ||
hexDigest(plan.definition) !== plan.digest ||
hexDigest(workspace) !== hexDigest(plan.definition.workspace)
workspaceDigest !== hexDigest(plan.definition.workspace)
)
throw new ExecutionPlanError(
"CANDIDATE_PLAN_MISMATCH",
@@ -113,14 +121,24 @@ export async function loadCheckedInstallationCandidate(
"Stored interpreter input must match the checked build and plan",
);
const expectedGraph = graphExecutionRepresentation(plan, installation, kernel, queries);
if (hexDigest(graph) !== hexDigest(expectedGraph) || artifacts.execution !== hexDigest(graph))
throw new ExecutionPlanError(
"CANDIDATE_EXECUTION_MISMATCH",
root,
"Stored graph execution differs from checked inputs",
);
// The stored graph embeds the same kernel/query programs. Validate it in a
// short-lived scope and retain the representation that shares those trees.
await (async () => {
const input = await readJson(root, "graph-execution.json", scope);
try {
const digest = hexDigest(input.value);
if (digest !== hexDigest(expectedGraph) || artifacts.execution !== digest)
throw new ExecutionPlanError(
"CANDIDATE_EXECUTION_MISMATCH",
root,
"Stored graph execution differs from checked inputs",
);
} finally {
input.releaseTree();
}
})();
const provenance = {
workspaceRevision: workspace.id as string,
workspaceRevision: plan.definition.workspace.id as string,
source: { repository: source.repository as string, commit: source.commit as string },
generator: artifacts.generator as string,
packages: (plan as ExecutionPlan).definition.packages.map((pkg) => ({
@@ -139,30 +157,33 @@ export async function loadCheckedInstallationCandidate(
programs: artifacts.programs,
}),
};
const catalog = createClientContractCatalog(plan, installation, scope, kernel);
return {
reference,
workspace: plan.definition.workspace.workspaceId,
world: hexDigest(graph),
world: hexDigest(expectedGraph),
plan: kernel.plan as string,
graphExecution: graph,
graphExecution: expectedGraph,
provenance,
entry,
kernel,
queries,
installation,
executionPlan: plan as ExecutionPlan,
clientContractCatalog: catalog.select,
metadata: {
get bytes() {
return scope.bytes;
},
release: scope.release,
release: () => {
catalog.close();
scope.release();
},
},
};
} catch (error) {
scope.release();
throw error;
} finally {
releaseValidation();
}
}
+17 -14
View File
@@ -35,20 +35,23 @@ export interface InspectionTemplate {
}
/** A finite installed template per interface/lane, not a per-client query compiler.
* Flags select public cache boundaries; normal scope identity bounds specialization. */
export function compileInspectionTemplates(plan: ExecutionPlan) {
const kernel = compileKernelProgram(plan) as {
operations: {
key: string;
atom: string;
interface: string;
operation: string;
effect: string;
targets: string[];
unsupported: string | null;
output: unknown;
binding: { kind: string };
}[];
};
export interface InspectionKernel {
operations: {
key: string;
atom: string;
interface: string;
operation: string;
effect: string;
targets: string[];
unsupported: string | null;
output: unknown;
binding: { kind: string };
}[];
}
export function compileInspectionTemplates(
plan: ExecutionPlan,
kernel: InspectionKernel = compileKernelProgram(plan) as InspectionKernel,
) {
const queries: unknown[] = [],
contracts: PublicQueryContract[] = [],
templates: InspectionTemplate[] = [];
+87 -3
View File
@@ -1,4 +1,4 @@
import { compileInspectionTemplates, type InspectionTemplate } from "./inspection.js";
import { compileInspectionTemplates, type InspectionTemplate, type InspectionKernel } from "./inspection.js";
import path from "node:path";
import { loadCheckedArtifactWorld } from "./receipts.js";
import { contentArtifactUrl, loadArtifactWorld, type LoadedArtifactWorld } from "./files.js";
@@ -45,6 +45,7 @@ export function clientContractCatalog(
plan: ExecutionPlan,
installation: ExecutionInstallation,
requestedPackages: readonly string[],
checkedKernel?: InspectionKernel,
): ClientContractCatalog {
if (installation.plan !== plan.digest || hexDigest(plan.definition) !== plan.digest)
throw new ExecutionPlanError(
@@ -69,7 +70,7 @@ export function clientContractCatalog(
.map((operation) => publicOperationContract(iface, operation)),
),
);
const inspection = compileInspectionTemplates(plan);
const inspection = compileInspectionTemplates(plan, checkedKernel);
return {
inspections: inspection.templates,
resultInterfaces: Object.fromEntries(
@@ -98,6 +99,75 @@ export function clientContractCatalog(
};
}
/** Candidate-owned compiler output, never graph state or authorization. Compile
* once, then project each requested package set without hashing/recompiling the
* plan. Reserve bounded metadata before compilation; disposal releases both the
* catalog and its charge. Callers must supply the candidate's checked inputs. */
export function createClientContractCatalog(
plan: ExecutionPlan,
installation: ExecutionInstallation,
metadata: CandidateMetadataScope,
checkedKernel?: InspectionKernel,
) {
const revisions = plan.definition.workspace.packageImports.map((pkg) => pkg.revisionId);
const installed = new Set<string>(revisions);
let catalog: ClientContractCatalog | undefined;
let release: (() => void) | undefined;
let closed = false;
const freeze = (value: unknown, seen = new WeakSet<object>()) => {
if (!value || typeof value !== "object" || seen.has(value)) return;
seen.add(value);
for (const child of Object.values(value)) freeze(child, seen);
Object.freeze(value);
};
return {
select(requestedPackages: readonly string[]): ClientContractCatalog {
if (closed) throw Error("CANDIDATE_METADATA_CLOSED");
for (const revision of requestedPackages)
if (!installed.has(revision))
throw new ExecutionPlanError("UNINSTALLED_PACKAGE", revision, "Requested catalog package is not installed");
if (!catalog) {
// Like other candidate admission charges, this is an allocation estimate,
// not a V8 heap limit. The process/cgroup ceiling bounds transient work.
const reservation = metadata.reserve(32 * 1024 * 1024);
try {
const compiled = clientContractCatalog(plan, installation, revisions, checkedKernel);
const bytes = Buffer.byteLength(JSON.stringify(compiled));
if (bytes > 8 * 1024 * 1024) throw Error("CANDIDATE_CATALOG_LIMIT");
freeze(compiled);
// No await between reservations: replacing the transient upper bound
// with a smaller retained estimate cannot race another admission.
reservation();
release = metadata.reserve(Math.max(64 * 1024, bytes * 4));
catalog = compiled;
} catch (error) {
reservation();
throw error;
}
}
const requested = new Set(requestedPackages);
return {
inspections: catalog.inspections,
resultInterfaces: catalog.resultInterfaces,
operations: catalog.operations,
queries: [
...catalog.queries.filter((query) => !installed.has(query.package)),
...requestedPackages.flatMap((revision) => catalog!.queries.filter((query) => query.package === revision)),
],
components: catalog.components.filter((component) => requested.has(component.packageRevision)),
moduleBindings: catalog.moduleBindings.filter((binding) => requested.has(binding.packageRevision)),
presentations: catalog.presentations.filter((presentation) => requested.has(presentation.packageRevision)),
};
},
close() {
closed = true;
catalog = undefined;
release?.();
release = undefined;
},
};
}
export interface PackageInstallationSelection {
readonly browser?: { readonly id?: string };
readonly service?: { readonly id?: string };
@@ -113,6 +183,8 @@ export interface ExecutionInstallation {
readonly root: string;
readonly service?: ArtifactImplementation;
readonly module?: ArtifactImplementation;
/** Checked candidate only; the qualified host verifies its import surface and SDK. */
readonly restricted?: ArtifactImplementation;
readonly browserImplementation?: ArtifactImplementation;
readonly browserURL?: string;
readonly browserRegistry?: string;
@@ -251,6 +323,11 @@ function assembleExecutionInstallation(
exports: exports.map((entry) => entry.id),
})
: 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(
(entry) =>
entry.execution.kind !== "remote" &&
@@ -258,7 +335,13 @@ function assembleExecutionInstallation(
);
if (!browserExports.length) {
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;
}
const browser = selectArtifactImplementation(manifest, {
@@ -289,6 +372,7 @@ function assembleExecutionInstallation(
root,
...(service ? { service } : {}),
...(module ? { module } : {}),
...(restricted ? { restricted } : {}),
browserImplementation: browser,
browserURL: contentArtifactUrl(entry),
browserRegistry: browser.registryExport,
+5 -1
View File
@@ -9,7 +9,11 @@ export class CandidateMetadataBudget {
private bytes = 0;
private scopes = 0;
private readonly owners = new Map<string, number>();
constructor(limits = { bytes: 512 * 1024 * 1024, ownerBytes: 256 * 1024 * 1024, candidates: 128 }) {
// A cutover holds both the serving and proposed installation plus transient
// parsing space. The 57-repository reader retains ~133 MiB per installation;
// a 256 MiB owner ceiling cannot admit its ordinary atomic replacement.
// Keep the aggregate ceiling independent and leave room for parsing overlap.
constructor(limits = { bytes: 512 * 1024 * 1024, ownerBytes: 384 * 1024 * 1024, candidates: 128 }) {
for (const value of Object.values(limits))
if (!Number.isSafeInteger(value) || value < 1) throw Error("INVALID_CANDIDATE_METADATA_BUDGET");
if (limits.ownerBytes > limits.bytes) throw Error("INVALID_CANDIDATE_METADATA_BUDGET");
+83 -7
View File
@@ -23,6 +23,75 @@ export interface ImportFinding {
readonly detail: string;
readonly line: number | null;
}
export const restrictedSDKSpecifier = "quixos:restricted-sdk/v1";
export const restrictedSDKPath = "share/quixos/restricted/core.mjs";
/** Compare trusted SDK syntax without build-machine paths in source comments.
* Keep literal/directive spelling and every executable AST node. This is SDK
* compatibility only: artifact files and the executed host SDK still have exact
* byte digests, and authored SDK bytes are never loaded by the restricted host.
*/
export function restrictedSDKIdentity(source: string): string {
if (Buffer.byteLength(source) > 2 * 1024 * 1024) throw Error("RESTRICTED_SDK_ANALYSIS_LIMIT");
const syntax = parse(source, { sourceType: "module", attachComment: false });
const metadata = new Set([
"start",
"end",
"loc",
"comments",
"leadingComments",
"innerComments",
"trailingComments",
"parenStart",
]);
let nodes = 0;
const encoded = JSON.stringify(syntax, (key, value) => {
if (metadata.has(key)) return undefined;
if (value && typeof value === "object" && typeof value.type === "string" && ++nodes > 100000)
throw Error("RESTRICTED_SDK_ANALYSIS_LIMIT");
return value;
});
return hexDigest({ codec: "quixos-restricted-sdk-syntax-v1", syntax: JSON.parse(encoded) });
}
/** 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,
qualifiedSDKIdentity?: 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 (entry.bytes > 1024 * 1024 || sdk.bytes > 2 * 1024 * 1024)
return [{ code: "ANALYSIS_LIMIT", detail: "Restricted closure exceeds the source budget", line: null }];
if (qualifiedSDKIdentity) {
const source = Buffer.from(await read(revision, sdk.path, sdk.bytes)).toString("utf8");
try {
if (restrictedSDKIdentity(source) !== qualifiedSDKIdentity) throw Error("SDK syntax differs");
} catch {
return [
{ code: "RESTRICTED_SDK_UNSUPPORTED", detail: "SDK differs from the qualified host profile", 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 ambient = new Set([
"process",
@@ -136,10 +205,8 @@ export function inspectJavaScriptSurface(source: string, checkedSDKImports: read
return findings;
}
/** Derived metadata only. Browser/server portability and available targets say
* nothing about sandbox eligibility. Build reports have no platform approval
* catalog, so they conservatively require VM placement. A host can override
* placement only for independently reviewed, exact restricted-code approvals. */
/** Derived metadata only. A build report can describe a closed candidate but
* cannot qualify the host's engine, SDK, OS sandbox or resource controller. */
export async function reportExecutionPlacement(
plan: ExecutionPlan,
installation: ExecutionInstallation,
@@ -156,11 +223,13 @@ export async function reportExecutionPlacement(
const packages = await Promise.all(
installation.packages.map(async (pkg) => {
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,
)) {
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)!;
if (!file || file.bytes > 1024 * 1024)
findings = [
@@ -192,7 +261,14 @@ export async function reportExecutionPlacement(
revision: pkg.revision,
requiresVM: implementations.length > 0,
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,
};
}),
+56
View File
@@ -4,6 +4,62 @@ import { mkdtemp, writeFile, symlink, rm } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { CandidateMetadataBudget, readCandidateMetadata } from "../src/execution-world/metadata.js";
import { loadCheckedInstallationCandidate } from "../src/execution-world/candidate.js";
test(
"a real checked application can stage its replacement within the default metadata budget",
{
skip: !process.env.QX_CHECKED_CANDIDATE,
},
async () => {
const root = process.env.QX_CHECKED_CANDIDATE!;
const budget = new CandidateMetadataBudget();
const first = await loadCheckedInstallationCandidate(root, {}, { budget, owner: "reader" });
try {
const retained = budget.snapshot().bytes;
const second = await loadCheckedInstallationCandidate(root, {}, { budget, owner: "reader" });
try {
assert.equal(budget.snapshot().bytes, retained * 2);
assert.deepEqual(second.reference, first.reference, "Compaction preserves exact checked identity");
assert.equal(second.graphExecution.kernel, second.kernel, "Graph representation shares the validated program");
assert.equal(second.graphExecution.queries, second.queries);
// A deliberately tighter pool admits the serving installation but must
// reject replacement parsing without leaking a candidate or tree lease.
const tight = new CandidateMetadataBudget({
bytes: retained + 1,
ownerBytes: retained + 1,
candidates: 2,
});
const blocker = tight.acquire("reader");
blocker.charge(retained);
try {
await assert.rejects(
loadCheckedInstallationCandidate(root, {}, { budget: tight, owner: "reader" }),
/CANDIDATE_METADATA_LIMIT/,
);
assert.equal(tight.snapshot().bytes, retained);
assert.equal(tight.snapshot().candidates, 1);
} finally {
blocker.release();
}
const other = budget.acquire("other");
try {
assert.throws(() => other.charge(budget.limits.bytes), /CANDIDATE_METADATA_LIMIT/);
assert.equal(budget.snapshot().bytes, retained * 2, "Rejected admission must not leak charges");
} finally {
other.release();
}
} finally {
second.metadata.release();
}
assert.equal(budget.snapshot().bytes, retained, "The serving candidate survives failed or completed staging");
} finally {
first.metadata.release();
}
assert.equal(budget.snapshot().bytes, 0);
assert.equal(budget.snapshot().candidates, 0);
},
);
test("concurrent candidate reservations enforce aggregate and owner limits and release exactly once", () => {
const budget = new CandidateMetadataBudget({ bytes: 1000, ownerBytes: 600, candidates: 3 });
+97 -1
View File
@@ -5,9 +5,90 @@ import os from "node:os";
import path from "node:path";
import { promisify } from "node:util";
import { execFile as callback } from "node:child_process";
import { planPinUpgrades, applyPinUpgrades, type UpgradeEffects } from "../src/capability-language/pin-upgrades.js";
import {
planPinUpgrades,
applyPinUpgrades,
discoverUpgradeSpec,
reviewUpgradeCandidate,
type UpgradeEffects,
} from "../src/capability-language/pin-upgrades.js";
import { capabilityId } from "../src/capability-model/index.js";
import { makeValidCapabilityWorkspace } from "./fixtures/capability-model.js";
const execFile = promisify(callback);
test("execution pin upgrades accept unchanged shared attachments without legacy migration planning", async (context) => {
const artifact = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-execution-review-"));
context.after(() => fs.rm(artifact, { recursive: true, force: true }));
await fs.writeFile(path.join(artifact, "execution-plan.json"), "{}");
const baseline = makeValidCapabilityWorkspace();
assert.ok(baseline.sharedAttachments.length);
const candidate = structuredClone(baseline);
candidate.sourceRootCommit = "f".repeat(40);
const { filename, review } = await reviewUpgradeCandidate({ artifact, baseline, candidate });
assert.equal(filename, "semantic-review.json");
assert.equal(review.checkerVersion, "quixos-semantic-review-v1");
assert.deepEqual(review.blockers, []);
assert.equal("migrationRequired" in review, false);
assert.equal("runtimeActions" in review, false);
});
test("execution pin upgrades require exact semantic-major receipts and reject foreign workspaces", async (context) => {
const artifact = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-semantic-review-"));
context.after(() => fs.rm(artifact, { recursive: true, force: true }));
await fs.writeFile(path.join(artifact, "execution-plan.json"), "{}");
const baseline = makeValidCapabilityWorkspace();
baseline.conformances[0]!.id = capabilityId.conformance("conformance:project:named");
const candidate = structuredClone(baseline);
candidate.conformances[0]!.semanticMajor = 2;
const { review } = await reviewUpgradeCandidate({ artifact, baseline, candidate });
assert.equal(review.reviews.length, 1);
assert.equal(review.reviews[0]!.accepted, false);
assert.match(review.blockers[0]!, /Semantic-major review required/);
const receipt = {
requirementDigest: review.reviews[0]!.requirementDigest,
decision: "accepted-unchanged" as const,
rationale: "Reviewed the consumer against the provider's unchanged label behavior",
agentId: "upgrade-fixture-agent",
};
assert.deepEqual(
(await reviewUpgradeCandidate({ artifact, baseline, candidate, reviews: [receipt] })).review.blockers,
[],
);
candidate.packageImports[0]!.source.commit = "f".repeat(40);
assert.equal(
(await reviewUpgradeCandidate({ artifact, baseline, candidate, reviews: [receipt] })).review.reviews[0]!.accepted,
false,
);
candidate.workspaceId = capabilityId.workspace("workspace:foreign");
await assert.rejects(() => reviewUpgradeCandidate({ artifact, baseline, candidate }), /different workspace/);
});
test("nonexecution pin upgrades retain their evolution checks", async (context) => {
const artifact = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-evolution-review-"));
context.after(() => fs.rm(artifact, { recursive: true, force: true }));
const baseline = makeValidCapabilityWorkspace();
const { filename, review } = await reviewUpgradeCandidate({
artifact,
baseline,
candidate: structuredClone(baseline),
});
assert.equal(filename, "evolution.json");
assert.equal(review.checkerVersion, "quixos-evolution-v1");
assert.ok(review.blockers.some((message) => message.includes("legacy workspace-shared attachments")));
assert.equal("migrationRequired" in review, true);
});
test("unexpected artifact access failures do not select nonexecution checks", async (context) => {
const directory = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-review-failure-"));
context.after(() => fs.rm(directory, { recursive: true, force: true }));
const artifact = path.join(directory, "not-a-directory");
await fs.writeFile(artifact, "not an artifact");
const candidate = makeValidCapabilityWorkspace();
await assert.rejects(() => reviewUpgradeCandidate({ artifact, baseline: candidate, candidate }), {
code: "ENOTDIR",
});
});
test(
"real jj snapshots and immutable Git publication propagate a changed interface into the root",
{ skip: !process.env.QX_CHECK_GENERATOR },
@@ -73,6 +154,21 @@ test(
await run(workbench, "git", ["--git-dir", path.join(workbench, "remotes/named.git"), "show-ref"]),
new RegExp(commit),
);
assert.equal(graph.resources[0].directory, "resources/Named");
assert.equal(graph.directResources[0].directory, "resources/Named");
// A retained workbench can move without keeping its original absolute path
// alive. Recovery journals remain bound to their original writer/root.
const relocated = `${workbench}-relocated`;
context.after(() => fs.rm(relocated, { recursive: true, force: true }));
await fs.cp(workbench, relocated, { recursive: true });
const discovered = await discoverUpgradeSpec(relocated);
assert.equal(discovered.nodes[1]!.directory, "resources/Named");
const relocatedPlan = await planPinUpgrades(relocated, { ...discovered, bootstrap: true });
assert.equal(relocatedPlan.workbench, relocated);
assert.deepEqual(
relocatedPlan.nodes.map((node) => node.directory),
["resources/Named", "root"],
);
},
);
+54
View File
@@ -6,10 +6,64 @@ import {
compileExecutionPlan,
hexDigest,
inspectJavaScriptSurface,
inspectRestrictedImplementation,
restrictedSDKIdentity,
restrictedSDKPath,
type ArtifactImplementation,
reportExecutionPlacement,
type ExecutionInstallation,
} from "../src/execution-world/index.js";
test("restricted SDK identity ignores build comments and positions, preserving executable syntax", () => {
const source = 'export function value() { return ("hello"); }';
const x86 = "// /nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-core/dist/portable.js\n" + source;
const arm = "// /nix/store/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-core/dist/portable.js\n\n" + source;
assert.equal(restrictedSDKIdentity(x86), restrictedSDKIdentity(arm));
for (const changed of [
'export function value() { return ("goodbye"); }',
'export function value() { return\n("hello"); }',
'export function value() { fetch("hello"); }',
'import x from "node:fs"; ' + source,
'export function value() { return "/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-core"; }',
])
assert.notEqual(restrictedSDKIdentity(source), restrictedSDKIdentity(changed));
assert.notEqual(restrictedSDKIdentity('"use strict";'), restrictedSDKIdentity('"use\\x20strict";'));
assert.notEqual(restrictedSDKIdentity('const value="// comment";'), restrictedSDKIdentity('const value="";'));
assert.throws(() => restrictedSDKIdentity("const ???"));
assert.throws(() => restrictedSDKIdentity(" ".repeat(2 * 1024 * 1024 + 1)), /ANALYSIS_LIMIT/);
});
test("restricted admission accepts the same SDK syntax and rejects changed SDK behavior", async () => {
const source = "export const registry = {};";
const sdk = 'export const value = "trusted";';
const implementation: ArtifactImplementation = {
id: "restricted",
target: "server",
compatibility: "quixos-restricted-module-v1",
path: "module.mjs",
ports: "quixos-transaction-ports-v1",
registryExport: "registry",
exports: ["value"],
contentDigest: "a".repeat(64),
files: [
{ path: "module.mjs", digest: "b".repeat(64), bytes: source.length, mediaType: "text/javascript" },
{ path: restrictedSDKPath, digest: "c".repeat(64), bytes: sdk.length, mediaType: "text/javascript" },
],
};
const check = (candidateSDK: string) => {
implementation.files[1]!.bytes = Buffer.byteLength(candidateSDK);
return inspectRestrictedImplementation(
"package:test@1",
implementation,
async (_revision, path) => Buffer.from(path === restrictedSDKPath ? candidateSDK : source),
restrictedSDKIdentity(sdk),
);
};
assert.deepEqual(await check("// a different build path\n" + sdk), []);
assert.equal((await check('export const value = "untrusted";'))[0]?.code, "RESTRICTED_SDK_UNSUPPORTED");
assert.equal((await check("export const ???"))[0]?.code, "RESTRICTED_SDK_UNSUPPORTED");
});
test("compiled-source inspection finds authority imports and ambient facilities without executing code", () => {
const surface = inspectJavaScriptSurface(
`
+54
View File
@@ -19,12 +19,16 @@ import {
expectedArtifactReceipt,
checkExecutionInstallation,
clientContractCatalog,
createClientContractCatalog,
CandidateMetadataBudget,
compileKernelProgram,
type ComponentArtifact,
type PackageArtifacts,
} from "../src/execution-world/index.js";
import { validateWorkspaceRevision } from "../src/capability-model/index.js";
import { presentationDeclarations, preparationArtifact } from "../src/react-build/declarations.js";
import { compileQueryComposition } from "../src/query/composition.js";
import type { InspectionKernel } from "../src/execution-world/inspection.js";
const source = { repository: "https://example.test/components.git", commit: "a".repeat(40) };
const contract = (name: string) => {
@@ -255,6 +259,56 @@ test("checked component-only artifacts install without a service and reject miss
() => clientContractCatalog(plan, { ...installation, plan: "bad" }, [pkg.revision]),
/CATALOG_PLAN_MISMATCH/,
);
const budget = new CandidateMetadataBudget();
const scope = budget.acquire("catalog-test");
const prepared = createClientContractCatalog(
plan,
installation,
scope,
compileKernelProgram(plan) as InspectionKernel,
);
try {
assert.throws(() => prepared.select(["absent"]), /UNINSTALLED_PACKAGE/);
assert.equal(scope.bytes, 0, "Unknown requests do not allocate compiler metadata");
assert.deepEqual(prepared.select([pkg.revision]), catalog);
const retained = scope.bytes;
assert.ok(retained > 0);
assert.ok(retained < 32 * 1024 * 1024, "Small catalogs retain a proportional metadata charge");
const full = prepared.select([pkg.revision]);
const empty = prepared.select([]);
assert.deepEqual(empty.components, []);
assert.deepEqual(empty.presentations, []);
assert.deepEqual(empty.moduleBindings, []);
assert.equal(empty.operations, full.operations, "Shared compiled metadata is reused");
assert.equal(Object.isFrozen(full.operations), true);
// Any plan access now would reveal a repeated digest/compile on the warm path.
const definition = plan.definition;
Object.defineProperty(plan, "definition", {
configurable: true,
get() {
throw Error("RECOMPILED_PLAN");
},
});
try {
assert.deepEqual(prepared.select([pkg.revision]), full);
assert.equal(scope.bytes, retained, "Package projections do not accumulate cache entries");
} finally {
Object.defineProperty(plan, "definition", { configurable: true, value: definition });
}
prepared.close();
assert.equal(scope.bytes, 0);
assert.throws(() => prepared.select([pkg.revision]), /CANDIDATE_METADATA_CLOSED/);
} finally {
prepared.close();
scope.release();
}
const tight = new CandidateMetadataBudget({ bytes: 1000, ownerBytes: 1000, candidates: 1 });
const tightScope = tight.acquire("catalog-test");
const refused = createClientContractCatalog(plan, installation, tightScope);
assert.throws(() => refused.select([pkg.revision]), /CANDIDATE_METADATA_LIMIT/);
assert.equal(tightScope.bytes, 0);
refused.close();
tightScope.release();
} finally {
await rm(root, { recursive: true, force: true });
}