Files
quixos-protocol/test/structural-edits.test.ts
T
Timothy J. Aveni 01ca965c7f Make workspace authoring converge through immutable Nix candidates
Coordinate registered resource edits bottom-up into retained exact remote sources.
Use one Nix-owned source graph for provisional checking, template publication,
explicit baseline upgrades and host activation; retain independent runtime pins.

Add scoped contract inspection, historical recovery, derived worklists, crash-safe
locks, named dependency adoption and plain-QX structural editing. Repair TODO
ownership and template instantiation, and document the supported agent workflow.

Validated with protocol and command suites, real jj/Nix convergence and cache
checks, TS/React installed-command acceptance, and fresh TODO first-edit acceptance.
No live deployment or public publication performed. Props projection generation
and a one-command rich feature generator remain explicitly outside this delivery.
2026-09-14 12:25:47 -07:00

57 lines
4.8 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { editStructure, scaffoldResourceSource, instantiateWorkspaceIdentity } from "../src/capability-language/structural-edits.js";
test("template identity binding changes only the workspace header and is idempotent", () => {
const source = '// workspace fake id "do-not-touch"\nworkspace Todo id "workspace:todo" revision "workspace:todo@1" commit "' + "a".repeat(40) + '" { atom Task id "atom:task"; }';
const id = "00000000-0000-0000-0000-000000000123";
const bound = instantiateWorkspaceIdentity(source, id);
assert.match(bound, /atom Task id "atom:task"/);
assert.ok(bound.startsWith('// workspace fake id "do-not-touch"'));
assert.ok(bound.includes(`workspace Todo id "${id}"`));
assert.equal(instantiateWorkspaceIdentity(bound, id), bound);
assert.throws(() => instantiateWorkspaceIdentity(source, "not-a-workspace"), /UUID/);
});
test("package scaffolding and function edits preserve surrounding source and use exact selectors", () => {
const source = `// 🧭 resource comment\n${scaffoldResourceSource("package", "Chess", "package:chess", "package:chess@1")}`;
const functionSource = 'function evaluate id "export:evaluate" : string -> string;';
const appended = editStructure(source, {operation: "append", parent: {kind: "packageResourceDecl", id: "package:chess"}, source: functionSource});
assert.ok(appended.startsWith("// 🧭 resource comment\n"));
assert.ok(appended.includes(functionSource));
const replaced = editStructure(appended, {operation: "replace", target: {kind: "packageFunctionExport", id: "export:evaluate"}, source: 'function evaluate id "export:evaluate" : unit -> string;'});
assert.ok(replaced.includes(": unit -> string;"));
assert.ok(!editStructure(replaced, {operation: "remove", target: {kind: "packageFunctionExport", id: "export:evaluate"}}).includes("evaluate"));
assert.throws(() => editStructure(source, {operation: "remove", target: {kind: "packageResourceDecl", id: "package:chess@1"}}), /exactly once/);
assert.throws(() => editStructure(source, {operation: "append", parent: {kind: "packageResourceDecl"}, source: "not valid QX"}), /Invalid structural/);
const prefixed = `import interface Board;\nexternal atom Game id "atom:game";\n${source}`;
const replacedPackage = editStructure(prefixed, {operation: "replace", target: {kind: "packageResourceDecl", id: "package:chess"}, source: scaffoldResourceSource("package", "Chess", "package:chess", "package:chess@2")});
assert.ok(replacedPackage.startsWith('import interface Board;\nexternal atom Game id "atom:game";'));
});
test("dependency scaffolding validates exact sources and preserves unrelated lock comments", () => {
const source = `// 🧭 lock\nquixos-lock version 1 {\n quixos source { repository "https://example.test/quixos.git"; commit "${"a".repeat(40)}"; }\n // retained comment\n}\n`;
const dependency = {operation: "dependency" as const, kind: "package" as const, name: "Chess", source: {repository: "https://example.test/chess.git", commit: "b".repeat(40)}};
const appended = editStructure(source, dependency);
assert.ok(appended.includes("// retained comment"));
assert.ok(appended.startsWith("// 🧭 lock\n"));
assert.throws(() => editStructure(source, {...dependency, source: {...dependency.source, commit: "main"}}), /Invalid dependency/);
const changed = editStructure(appended, {...dependency, source: {...dependency.source, commit: "c".repeat(40)}});
assert.ok(!changed.includes("b".repeat(40)));
assert.ok(!editStructure(changed, {...dependency, source: null}).includes("package Chess"));
});
test("conformance enrollment, major edits, imports, and private attachment removal preserve valid structure", () => {
const source = `fragment { conform Game as Playable { private state Board id "slot:board" on Game : string policy optimistic-register; } }`;
const selector = {kind: "conformanceDecl", names: ["Game", "Playable"]};
const enrolled = editStructure(source, {operation: "conformance-id", target: selector, id: "conformance:playable"});
assert.ok(enrolled.includes('as Playable id "conformance:playable"'));
const major = editStructure(enrolled, {operation: "semantic-major", target: {kind: "conformanceDecl", id: "conformance:playable"}, major: 2});
assert.ok(major.includes("semantic-major 2"));
assert.throws(() => editStructure(major, {operation: "conformance-id", target: selector, id: "different"}), /Cannot change/);
const removed = editStructure(major, {operation: "remove", target: {kind: "stateDecl", id: "slot:board"}});
assert.ok(!removed.includes("private"));
const imported = editStructure(removed, {operation: "import", kind: "interface", name: "Playable"});
assert.equal(editStructure(imported, {operation: "import", kind: "interface", name: "Playable"}), imported);
});