Instrument and improve incremental workspace checks

Profile source capture, Nix evaluation/realization, resource/query checking,
and implementation builds without putting timings into immutable outputs.
Keep modular repositories; bound independent capture work, snapshot jj once
per observation, and retain final concurrent-edit and Git completeness checks.

Compose exact resource/closure/frontend/toolchain checks as memoized Nix
derivations. Preserve whole-workspace validation and the full compiler path
when no checked dependency is supplied. Share canonical Nixpkgs by content,
index workspace build contexts once, and narrow lock/driver/compiler inputs
with conservative complete-source fallback. Batch React witness checks only
when distinct source closures cannot share ambient declarations; otherwise
run the original independent TypeScript checks.

Seed local authoring toolchains with exact canonical fetch identities when
they match the selected inputs; retain store-path inputs for overrides.
Add generic correctness checks rather than permanent Reader timing/content
fixtures. Verify actual Reader edits and rejection/recovery in a private
workbench, preserving the original user's workbench and runtime.

Query checking currently caches at resource/closure boundaries, not individual
query semantic dependency boundaries. Template helper pins and reproducible
fixture snapshots follow in a separate publication change.
This commit is contained in:
Timothy J. Aveni
2026-10-01 04:03:19 -07:00
parent e8d19d2bb7
commit 7c1830bcd5
15 changed files with 527 additions and 141 deletions
+57 -1
View File
@@ -1,5 +1,6 @@
import { readFile, realpath } from "node:fs/promises";
import path from "node:path";
import { profile } from "./profile.js";
import { loadQxSources, resolveQxSources } from "./source-loader.js";
import { compileQuery, compileRepositoryQuery } from "../query/compile.js";
import type { QueryDeclaration } from "../query/types.js";
@@ -43,6 +44,15 @@ export type CapabilityRepositoryResolver = (
kind: LockedResource["kind"],
) => Promise<CapabilityRepositorySnapshot>;
/** Already checked outputs of this compiler, composed by the Nix build DAG.
* Source capture/check reports never grant this authority. */
export type CheckedResourceResolver = (
kind: LockedResource["kind"],
source: GitSource,
lock: QuixosRepositoryLock,
dependencies: ReadonlyMap<string, ResolvedCapabilityResource>,
) => Promise<CapabilityResource | undefined>;
/** An explicitly selected build frontend supplies ordinary query sources. The
* assembler never chooses a frontend by inspecting an interface/contract ID.
* Generated sources go through the same query and imported-fragment checks. */
@@ -221,7 +231,12 @@ const createResourceGraphResolver = (
quixosCommit: string,
resolveResource: CapabilityRepositoryResolver,
generateQueries?: PackageQueryGenerator,
checkedResource?: CheckedResourceResolver,
) => {
const graphStarted = performance.now();
let checkedResources = 0,
reusedResources = 0,
checkedQueries = 0;
const resolved = new Map<string, Promise<ResolvedCapabilityResource>>();
const active: string[] = [];
@@ -275,6 +290,30 @@ const createResourceGraphResolver = (
};
}
const dependencyClosure = resourceClosure(directPairs.map(([, node]) => node));
const dependencies = new Map(
directPairs.map(([dependency, node]) => [bindingKey(dependency.kind, dependency.binding), node]),
);
const checked = await checkedResource?.(locked.kind, locked.source, lockResult.lock, dependencies);
if (checked) {
if (
checked.kind !== locked.kind ||
checked.revision.source.repository !== locked.source.repository ||
checked.revision.source.commit !== locked.source.commit
)
throw new Error("Checked resource identity mismatch");
assertImportsMatchLock("Checked resource", checked.imports, lockResult.lock.resources);
reusedResources++;
return {
key,
kind: locked.kind,
source: locked.source,
directory: snapshot.directory,
lock: lockResult.lock,
resource: structuredClone(checked),
dependencies,
};
}
const checkStarted = performance.now();
const environment = environmentFor(directPairs, dependencyClosure);
const manifestName = locked.kind === "interface" ? "interface.qx" : "package.qx";
const manifestPath = path.join(snapshot.directory, manifestName);
@@ -399,6 +438,15 @@ const createResourceGraphResolver = (
compiled.resource.revision.migrationCatalog = catalog;
}
}
checkedResources++;
const queries =
compiled.resource.kind === "package" ? (compiled.resource.revision.checkedQueries?.length ?? 0) : 0;
checkedQueries += queries;
profile("resource-check", checkStarted, {
kind: locked.kind,
resource: compiled.resource.revision.displayName,
queries,
});
return {
key,
kind: locked.kind,
@@ -420,7 +468,11 @@ const createResourceGraphResolver = (
return {
visit,
nodes: async () => await Promise.all(resolved.values()),
nodes: async () => {
const nodes = await Promise.all(resolved.values());
profile("resource-graph", graphStarted, { checkedResources, reusedResources, checkedQueries });
return nodes;
},
};
};
@@ -430,6 +482,7 @@ export const compileCapabilityResourceRepository = async (options: {
source: GitSource;
resolveResource: CapabilityRepositoryResolver;
generateQueries?: PackageQueryGenerator;
checkedResource?: CheckedResourceResolver;
}): Promise<CompiledCapabilityResourceRepository> => {
const lockResult = await loadQuixosLock(path.join(options.rootDirectory, "quixos.lock"));
if (!lockResult.ok) {
@@ -439,6 +492,7 @@ export const compileCapabilityResourceRepository = async (options: {
lockResult.lock.quixos.commit,
options.resolveResource,
options.generateQueries,
options.checkedResource,
);
const root = await resolver.visit(
{
@@ -466,6 +520,7 @@ export const compileWorkspaceRepository = async (options: {
/** An editor's proposed source snapshot; locks and dependency revisions remain exact. */
readSource?: (name: string) => Promise<string>;
generateQueries?: PackageQueryGenerator;
checkedResource?: CheckedResourceResolver;
}): Promise<CompiledWorkspaceRepository> => {
const rootLockResult = await loadQuixosLock(path.join(options.rootDirectory, "quixos.lock"));
if (!rootLockResult.ok) {
@@ -476,6 +531,7 @@ export const compileWorkspaceRepository = async (options: {
rootLock.quixos.commit,
options.resolveResource,
options.generateQueries,
options.checkedResource,
);
const directPairs: Array<[LockedResource, ResolvedCapabilityResource]> = [];