prepare records an immutable manifest of every regular backend/dist file (path/size/sha256/dev/ino) in the owned root and binds its record identity in ownership; serve revalidates record and every file before spawn, passes the manifest to the child on fd 4, and the immutable preload hash-verifies all files at startup and serves only cached verified bytes for any import below backend/dist, so imported dependency replacement is refused before RUNNING or never executes. The render command validates the commit snapshot.json manifest, binds snapshot bytes to the manifest digest and the installed Git blob, and passes the expected digest to the renderer, which revalidates head/files digest with bounded no-follow reads and renders only verified bytes with lease release on refusal.
71 lines
7.7 KiB
JavaScript
71 lines
7.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { createHash } from "node:crypto";
|
|
import { chmod, lstat, mkdir, mkdtemp, readFile, realpath, rename, rm, symlink, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join } from "node:path";
|
|
import test from "node:test";
|
|
import { renderOwnedSnapshot } from "./p1-render-snapshot.mjs";
|
|
|
|
const roots=[];
|
|
const sha256=bytes=>createHash("sha256").update(bytes).digest("hex");
|
|
async function fixture() {
|
|
const repo=await realpath(await mkdtemp(join(tmpdir(),"p1-render-repo-"))); roots.push(repo);
|
|
const root=join(repo,".artifacts/manual-acceptance/p1"); const commit="a".repeat(40); const snapshot=join(root,"installation/registry/snapshots",commit,"p1-filesystem.yaml");
|
|
for (const p of [dirname(snapshot),join(root,"rendered"),join(root,"installation/registry/snapshots/runtime"),join(root,"installation/data"),join(root,"fixture-secrets"),join(repo,"harness")]) await mkdir(p,{recursive:true,mode:0o700});
|
|
await writeFile(join(root,"ownership.json"),JSON.stringify({schemaVersion:1,kind:"p1-manual-acceptance",nonce:"b".repeat(64),repositoryRoot:repo,root,status:"PENDING",listener:{host:"127.0.0.1",port:8791}}));
|
|
await writeFile(join(root,"installation/base.yaml"),"{}\n");
|
|
const secret=join(root,"fixture-secrets/dwh-password"); await writeFile(secret,"not-inspected",{mode:0o600});
|
|
await writeFile(snapshot,`workspace:
|
|
schema_version: 3
|
|
id: p1-filesystem
|
|
name: P1 filesystem
|
|
language: en
|
|
dwh:
|
|
engine: postgres
|
|
database: postgres
|
|
schema: public
|
|
supported_transports: [postgres_direct]
|
|
semantic_index:
|
|
vector_store: {engine: qdrant, collection: p1-filesystem, dimensions: 1024, distance: cosine}
|
|
embedding: {provider: ollama_internal, model: qwen3-embedding:0.6b, dimensions: 1024}
|
|
llm_policy:
|
|
allowed: [zai/glm-5.2]
|
|
evidence:
|
|
source: {type: filesystem, uri: workspace-content/p1-filesystem/evidence, patterns: ["**/*.md"], max_bytes: 10485760}
|
|
policy: {max_chunk_chars: 4000, retain_published_generations: 3}
|
|
`);
|
|
const snapshotBytes=await readFile(snapshot); const snapshotSha256=sha256(snapshotBytes);
|
|
const manifestPath=join(dirname(snapshot),"snapshot.json");
|
|
await writeFile(manifestPath,JSON.stringify({head:commit,revisions:[{id:"p1-filesystem",commit,blob:"0".repeat(40),snapshotPath:snapshot,state:"operational"}],files:{"p1-filesystem.yaml":snapshotSha256}}));
|
|
const env={THT_WS_P1_FILESYSTEM_DWH_TRANSPORT:"postgres_direct",THT_WS_P1_FILESYSTEM_DWH_HOST:"dwh.invalid",THT_WS_P1_FILESYSTEM_DWH_PORT:"5432",THT_WS_P1_FILESYSTEM_DWH_USER:"reader",THT_WS_P1_FILESYSTEM_DWH_PASSWORD_FILE:secret};
|
|
return {repo,root,snapshot,snapshotSha256,manifestPath,env};
|
|
}
|
|
test.afterEach(async()=>Promise.all(roots.splice(0).map(r=>rm(r,{recursive:true,force:true}))));
|
|
|
|
const call=(f,extra={})=>renderOwnedSnapshot({repositoryRoot:f.repo,ownershipPath:join(f.root,"ownership.json"),snapshotPath:f.snapshot,snapshotSha256:f.snapshotSha256,env:{...process.env,...f.env},...extra});
|
|
const runtimeLeases=async f=>await (await import("node:fs/promises")).readdir(join(f.root,"installation/registry/snapshots/runtime"));
|
|
|
|
test("renderer copies a production lease deterministically with mode 0600 and no leases",async()=>{ const f=await fixture(); const one=join(f.root,"rendered/one.yaml"),two=join(f.root,"rendered/two.yaml"); await call(f,{outputPath:one}); await call(f,{outputPath:two}); assert.deepEqual(await readFile(one),await readFile(two)); assert.equal((await lstat(one)).mode&0o777,0o600); assert.deepEqual(await runtimeLeases(f),[]); });
|
|
|
|
test("renderer rejects unowned, symlink, out-of-root and missing-digest paths",async()=>{ const f=await fixture(); const outside=join(f.repo,"outside.yaml"); await writeFile(outside,"x"); await assert.rejects(renderOwnedSnapshot({repositoryRoot:f.repo,ownershipPath:join(f.root,"ownership.json"),snapshotPath:outside,outputPath:join(f.root,"rendered/x.yaml"),snapshotSha256:f.snapshotSha256,env:f.env}),/owned|snapshot/); const link=join(dirname(f.snapshot),"linked.yaml"); await symlink(f.snapshot,link); await assert.rejects(renderOwnedSnapshot({repositoryRoot:f.repo,ownershipPath:join(f.root,"ownership.json"),snapshotPath:link,outputPath:join(f.root,"rendered/x.yaml"),snapshotSha256:f.snapshotSha256,env:f.env}),/snapshot|symlink/); await assert.rejects(renderOwnedSnapshot({repositoryRoot:f.repo,ownershipPath:join(f.root,"ownership.json"),snapshotPath:f.snapshot,outputPath:outside,snapshotSha256:f.snapshotSha256,env:f.env}),/output/); await assert.rejects(renderOwnedSnapshot({repositoryRoot:f.repo,ownershipPath:join(f.root,"ownership.json"),snapshotPath:f.snapshot,outputPath:join(f.root,"rendered/x.yaml"),env:f.env}),/snapshot digest identity/); });
|
|
|
|
test("renderer releases its acquired lease when atomic output copy fails",async()=>{ const f=await fixture(); const output=join(f.root,"rendered/existing.yaml"); await mkdir(output); await assert.rejects(call(f,{outputPath:output}),/anchored|publication|unsafe/); assert.deepEqual(await runtimeLeases(f),[]); });
|
|
|
|
test("renderer refuses a same-path regular snapshot byte replacement against manifest and expected digest",async()=>{ const f=await fixture(); const output=join(f.root,"rendered/replaced.yaml"); const replaced=(await readFile(f.snapshot,"utf8")).replace("max_chunk_chars: 4000","max_chunk_chars: 3999"); await writeFile(f.snapshot,replaced); await assert.rejects(call(f,{outputPath:output}),/snapshot bytes changed/); await assert.rejects(lstat(output)); assert.deepEqual(await runtimeLeases(f),[]); });
|
|
|
|
test("renderer refuses snapshot manifest head, digest, and expected-digest tampering",async()=>{ const f=await fixture(); const output=join(f.root,"rendered/tampered.yaml"); const manifest=JSON.parse(await readFile(f.manifestPath,"utf8"));
|
|
await writeFile(f.manifestPath,JSON.stringify({...manifest,head:"c".repeat(40)})); await assert.rejects(call(f,{outputPath:output}),/snapshot manifest identity/);
|
|
await writeFile(f.manifestPath,JSON.stringify({...manifest,files:{"p1-filesystem.yaml":"d".repeat(64)}})); await assert.rejects(call(f,{outputPath:output}),/snapshot manifest digest/);
|
|
await writeFile(f.manifestPath,JSON.stringify(manifest)); await assert.rejects(call(f,{outputPath:output,snapshotSha256:"e".repeat(64)}),/snapshot manifest digest/);
|
|
await assert.rejects(lstat(output)); assert.deepEqual(await runtimeLeases(f),[]); });
|
|
|
|
test("renderer refuses a missing or malformed snapshot manifest",async()=>{ const f=await fixture(); const output=join(f.root,"rendered/nomanifest.yaml"); await rm(f.manifestPath); await assert.rejects(call(f,{outputPath:output}),/snapshot manifest.*(missing|unbounded|unsafe)/); await writeFile(f.manifestPath,"{not json"); await assert.rejects(call(f,{outputPath:output}),/snapshot manifest.*malformed/); await assert.rejects(lstat(output)); assert.deepEqual(await runtimeLeases(f),[]); });
|
|
|
|
test("renderer rejects a regular snapshot replacement against its manifest",async()=>{ const f=await fixture(); const output=join(f.root,"rendered/replaced.yaml"); await assert.rejects(call(f,{outputPath:output,beforePublish:async()=>{await writeFile(f.snapshot,"workspace:\n schema_version: 3\n id: p1-filesystem\n name: replaced\n")}}),/snapshot content changed/); await assert.rejects(lstat(output)); });
|
|
|
|
test("renderer anchors publication when rendered parent is concurrently swapped", async()=>{
|
|
const f=await fixture(),output=join(f.root,"rendered/raced.yaml"),moved=join(f.root,"rendered-moved"),outside=join(f.repo,"outside-rendered"); await mkdir(outside);
|
|
await assert.rejects(call(f,{outputPath:output,beforePublish:async()=>{await rename(join(f.root,"rendered"),moved);await symlink(outside,join(f.root,"rendered"));}}),/identity|changed|unsafe|publication/i);
|
|
assert.deepEqual(await (await import("node:fs/promises")).readdir(outside),[]);
|
|
});
|