guanghu-ice-heart/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.test.mjs

208 lines
6.7 KiB
JavaScript

import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execFileSync } from "node:child_process";
import test from "node:test";
import { createRequire } from "node:module";
import { runDaily } from "./fifth-domain-daily-orchestrator.mjs";
const require = createRequire(import.meta.url);
const { validateUnit } = require(
"../lake-lamp-authz/architecture-provision-broker.js"
);
function git(args, options = {}) {
return execFileSync("/usr/bin/git", args, {
encoding: "utf8",
...options,
}).trim();
}
function createRepository(root, name, commits = 1) {
const work = path.join(root, `${name}-work`);
const bare = path.join(root, `${name}.git`);
fs.mkdirSync(work);
git(["init", "-b", "main"], { cwd: work });
git(["config", "user.name", "fixture"], { cwd: work });
git(["config", "user.email", "fixture@example.test"], { cwd: work });
for (let index = 1; index <= commits; index += 1) {
fs.writeFileSync(
path.join(work, `record-${index}.md`),
`# record ${index}\n`,
);
git(["add", "."], { cwd: work });
git(["commit", "-m", `record ${index}`], { cwd: work });
}
git(["clone", "--bare", work, bare]);
return { work, bare };
}
test("Zhuyuan daily dispatch writes one signed role update per advanced source", async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "persona-daily-"));
try {
const source = createRepository(root, "source", 3);
const names = [
["chenglu-agent", "CHENGLU-AGENT-001", "澄路"],
["guideng", "GUIDENG-AGENT-001", "归灯"],
["kezhou", "ICE-GL-KZ-001", "刻舟"],
];
const keys = new Map();
const members = names.map(([slug, personaId, name], index) => {
const target = createRepository(root, slug, 1);
const pair = crypto.generateKeyPairSync("ed25519");
const publicKey = pair.publicKey.export({
type: "spki",
format: "pem",
});
const fingerprint = `SHA256:${crypto
.createHash("sha256")
.update(
pair.publicKey.export({
type: "spki",
format: "der",
}),
)
.digest("base64")
.replace(/=+$/, "")}`;
keys.set(personaId, { privateKey: pair.privateKey, publicKey });
return {
slug,
persona_id: personaId,
name,
endpoint: `http://127.0.0.1:${4100 + index}/observe`,
identity_fingerprint: fingerprint,
target_repository: target.bare,
commit_email: `${slug}@example.test`,
controller_token: "fixture-controller-token",
scoped_duties: ["bounded fixture duty"],
};
});
let requestCount = 0;
const fetchImpl = async (_url, request) => {
requestCount += 1;
const event = JSON.parse(request.body);
const member = members.find(
(candidate) =>
!Array.from(keys.keys()).every(
(personaId) => personaId !== candidate.persona_id,
) && candidate.endpoint === _url,
);
const key = keys.get(member.persona_id);
const payload = {
schema: "guanghu.fifth-domain-persona-observation-payload/v1",
persona_id: member.persona_id,
arrival_id: "fixture-arrival",
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
role: "fixture-role",
source: event.source,
observation: {
schema: "guanghu.fifth-domain-persona-observation/v1",
persona_id: member.persona_id,
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
source_to_sha: event.source.to_sha,
summary: `${member.name}完成第五域岗位更新`,
role_findings: ["fixture finding"],
self_updates: ["fixture self update"],
recommended_actions: [],
questions: [],
boundary_note: "fixture boundary",
},
model: { provider: "fixture", name: "fixture" },
issued_at: "2026-08-06T00:00:00.000Z",
};
return {
ok: true,
async json() {
return {
ok: true,
persona_id: member.persona_id,
identity_fingerprint: member.identity_fingerprint,
public_key: key.publicKey,
payload,
signature: crypto
.sign(null, Buffer.from(JSON.stringify(payload)), key.privateKey)
.toString("base64"),
signature_algorithm: "Ed25519",
};
},
};
};
const config = {
source_repository: source.bare,
runtime_root: path.join(root, "runtime"),
bootstrap_commit_window: 20,
members,
};
const first = await runDaily(config, {
fetchImpl,
now: "2026-08-06T00:00:00.000Z",
});
assert.equal(first.result, "PASS");
assert.equal(requestCount, 3);
assert.ok(
first.results.every(
(result) => result.status === "FIFTH_DOMAIN_UPDATE_COMMITTED",
),
);
const sourceSha = git([`--git-dir=${source.bare}`, "rev-parse", "main"]);
for (const member of members) {
const current = JSON.parse(
git([
`--git-dir=${member.target_repository}`,
"show",
"main:persona-system/fifth-domain/CURRENT.json",
]),
);
assert.equal(current.last_source_sha, sourceSha);
assert.equal(current.controller, "ICE-P-ZY001");
}
const second = await runDaily(config, {
fetchImpl,
now: "2026-08-07T00:00:00.000Z",
});
assert.equal(second.result, "PASS");
assert.equal(requestCount, 3);
assert.ok(
second.results.every(
(result) => result.status === "NO_NEW_FIFTH_DOMAIN_COMMIT",
),
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("daily dispatcher unit is hardened and restricted to exact persona repositories", () => {
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "../..");
const unit = fs.readFileSync(
path.join(
root,
"server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service",
),
"utf8",
);
const base =
"/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo";
assert.equal(
validateUnit(unit, "guanghu", {
environment_files: [
"/etc/guanghu/persona-secrets/shared-deepseek.env",
],
read_only_paths: [
"/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guanghu-ice-heart.git",
],
writable_paths: [
"/var/lib/guanghu/personas/guanghu/fifth-domain-daily",
`${base}/chenglu-agent.git`,
`${base}/guideng.git`,
`${base}/kezhou.git`,
],
}),
unit,
);
});