312 lines
12 KiB
TypeScript
312 lines
12 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createHash, generateKeyPairSync, sign } from 'node:crypto';
|
|
import {
|
|
AnchoredDomainRuntimeHandoffSource,
|
|
HttpDomainRuntimeHandoffTransport,
|
|
StrictDomainRuntimeHandoffSource,
|
|
} from './domain-runtime-handoff-source.js';
|
|
import { DomainRuntimeHandoffSnapshotLoader } from './domain-runtime-handoff-snapshot.js';
|
|
import {
|
|
parseDomainRuntimeHandoffEndpointRegistry,
|
|
resolveDomainRuntimeHandoffEndpoint,
|
|
} from './domain-runtime-handoff-registry.js';
|
|
import {
|
|
createNodePossessionChallenge,
|
|
nodePossessionChallengeSigningBytes,
|
|
verifyNodePossessionResponse,
|
|
} from './node-possession-proof.js';
|
|
import {
|
|
nodeRegistrationClaimSigningBytes,
|
|
parseNodeRegistrationEndpointRegistry,
|
|
resolveNodeRegistrationEndpoint,
|
|
verifyNodeRegistrationClaim,
|
|
} from './node-registration.js';
|
|
|
|
const NOW = 1_786_291_200_000;
|
|
const DOMAIN_ID = 'DOM-FIFTH-0001';
|
|
const NODE_ID = 'JD-FD-PRIMARY';
|
|
const NODE_TYPE = 'cloud-resident' as const;
|
|
const registrationKeys = generateKeyPairSync('ed25519');
|
|
const nodeKeys = generateKeyPairSync('ed25519');
|
|
const publicKeyPem = nodeKeys.publicKey.export({ format: 'pem', type: 'spki' }).toString();
|
|
const fingerprint = createHash('sha256')
|
|
.update(nodeKeys.publicKey.export({ format: 'der', type: 'spki' }))
|
|
.digest('hex');
|
|
|
|
function handoffEndpoint() {
|
|
const registry = parseDomainRuntimeHandoffEndpointRegistry({
|
|
endpoints: [{
|
|
domainIds: [DOMAIN_ID],
|
|
endpointId: 'GH-DOMAIN-HANDOFF-001',
|
|
nodeTypes: [NODE_TYPE],
|
|
status: 'ACTIVE',
|
|
url: 'https://guanghulab.com/api/ai/v1/domain-runtime/handoff',
|
|
}],
|
|
registryId: 'GH-AIOS-DOMAIN-RUNTIME-HANDOFF-ENDPOINTS-001',
|
|
schema: 'gh-aios.domain-runtime-handoff-endpoints/v1',
|
|
state: 'CURRENT',
|
|
version: '1.0.0',
|
|
}, {
|
|
repositoryId: 'REPO-012',
|
|
sourceCommit: 'b'.repeat(40),
|
|
sourceUrl: `https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/commit/${'b'.repeat(40)}/routing/domain-runtime-handoff-endpoints.json`,
|
|
});
|
|
const endpoint = resolveDomainRuntimeHandoffEndpoint(registry, { domainId: DOMAIN_ID, nodeType: NODE_TYPE });
|
|
assert.ok(endpoint);
|
|
return endpoint;
|
|
}
|
|
|
|
function verifiedPossession() {
|
|
const registry = parseNodeRegistrationEndpointRegistry({
|
|
endpoints: [{
|
|
algorithm: 'Ed25519',
|
|
domainIds: [DOMAIN_ID],
|
|
endpointId: 'GH-NODE-REG-001',
|
|
nodeTypes: [NODE_TYPE],
|
|
publicKeyPem: registrationKeys.publicKey.export({ format: 'pem', type: 'spki' }).toString(),
|
|
signerId: 'GH-NODE-REG-SIGNER-001',
|
|
status: 'ACTIVE',
|
|
url: 'https://guanghulab.com/api/ai/v1/node-registrations/claims',
|
|
}],
|
|
registryId: 'GH-AIOS-NODE-REGISTRATION-ENDPOINTS-001',
|
|
schema: 'gh-aios.node-registration-endpoints/v1',
|
|
state: 'CURRENT',
|
|
version: '1.0.0',
|
|
}, {
|
|
repositoryId: 'REPO-012',
|
|
sourceCommit: 'a'.repeat(40),
|
|
sourceUrl: `https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/commit/${'a'.repeat(40)}/routing/node-registration-endpoints.json`,
|
|
});
|
|
const endpoint = resolveNodeRegistrationEndpoint(registry, { domainId: DOMAIN_ID, nodeType: NODE_TYPE });
|
|
assert.ok(endpoint);
|
|
const payload = {
|
|
accountId: 'bingshuo',
|
|
claimId: 'NODE-CLAIM-001',
|
|
domainId: DOMAIN_ID,
|
|
endpointId: endpoint.endpointId,
|
|
expiresAt: NOW + 120_000,
|
|
issuedAt: NOW - 1_000,
|
|
nodeId: NODE_ID,
|
|
nodeKeyFingerprint: fingerprint,
|
|
nodeType: NODE_TYPE,
|
|
schema: 'gh-aios.node-registration-claim/v1' as const,
|
|
signerId: endpoint.signerId,
|
|
};
|
|
const registration = verifyNodeRegistrationClaim({
|
|
...payload,
|
|
signature: sign(null, nodeRegistrationClaimSigningBytes(payload), registrationKeys.privateKey).toString('base64'),
|
|
}, {
|
|
accountId: payload.accountId,
|
|
domainId: DOMAIN_ID,
|
|
nodeId: NODE_ID,
|
|
nodeType: NODE_TYPE,
|
|
}, endpoint, NOW);
|
|
const challenge = createNodePossessionChallenge(
|
|
registration,
|
|
NOW,
|
|
'NODE-CHALLENGE-001',
|
|
'A'.repeat(43),
|
|
);
|
|
const response = {
|
|
challengeId: challenge.challengeId,
|
|
publicKeyPem,
|
|
schema: 'gh-aios.node-possession-response/v1' as const,
|
|
signature: sign(null, nodePossessionChallengeSigningBytes(challenge), nodeKeys.privateKey).toString('base64'),
|
|
};
|
|
return verifyNodePossessionResponse(response, challenge, registration, NOW + 1);
|
|
}
|
|
|
|
function response(requestId: string, overrides: Record<string, unknown> = {}) {
|
|
return {
|
|
schema: 'gh-aios.domain-runtime-handoff-response/v1',
|
|
handoff: { manifest: { digest: 'untrusted-until-orchestrator-verifies' } },
|
|
request_id: requestId,
|
|
signer_lookup: {
|
|
repository_id: 'REPO-014',
|
|
signer_id: 'GH-LIGHTHOUSE-001',
|
|
},
|
|
status: 'ISSUED',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test('forwards one exact cryptographic authorization bundle without private material', async () => {
|
|
const requests: unknown[] = [];
|
|
const source = new StrictDomainRuntimeHandoffSource(handoffEndpoint(), {
|
|
async request(_endpoint, input) {
|
|
requests.push(input);
|
|
return response(input.requestId);
|
|
},
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
|
|
const candidate = await source.read(verifiedPossession());
|
|
|
|
assert.equal(requests.length, 1);
|
|
assert.deepEqual(Object.keys(requests[0] as object).sort(), [
|
|
'accountId', 'challenge', 'domainId', 'endpointId', 'issuedAt', 'nodeId', 'nodeType',
|
|
'registration', 'requestId', 'response', 'schema',
|
|
]);
|
|
assert.equal(JSON.stringify(requests[0]).includes('PRIVATE KEY'), false);
|
|
assert.deepEqual(candidate, {
|
|
handoff: { manifest: { digest: 'untrusted-until-orchestrator-verifies' } },
|
|
signerLookup: { repositoryId: 'REPO-014', signerId: 'GH-LIGHTHOUSE-001' },
|
|
});
|
|
});
|
|
|
|
test('binds the response to the generated request and rejects malformed envelopes', async () => {
|
|
const samples = [
|
|
null,
|
|
response('OTHER-REQ'),
|
|
response('HANDOFF-REQ-001', { extra: true }),
|
|
response('HANDOFF-REQ-001', { schema: 'other/v1' }),
|
|
response('HANDOFF-REQ-001', { signer_lookup: { repository_id: 'REPO-014', signer_id: 'bad signer' } }),
|
|
response('HANDOFF-REQ-001', { signer_lookup: { repository_id: 'REPO-014', signer_id: 'GH-LIGHTHOUSE-001', public_key: 'forbidden' } }),
|
|
response('HANDOFF-REQ-001', { handoff: null }),
|
|
response('HANDOFF-REQ-001', { handoff: null, signer_lookup: null, status: 'NOT_AUTHORIZED' }),
|
|
];
|
|
for (const sample of samples) {
|
|
const source = new StrictDomainRuntimeHandoffSource(handoffEndpoint(), { async request() { return sample; } }, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.equal(await source.read(verifiedPossession()), null);
|
|
}
|
|
});
|
|
|
|
test('rejects copied, expired and replayed possession authorizations before transport', async () => {
|
|
let requests = 0;
|
|
const possession = verifiedPossession();
|
|
const source = new StrictDomainRuntimeHandoffSource(handoffEndpoint(), {
|
|
async request(_endpoint, input) { requests += 1; return response(input.requestId); },
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.ok(await source.read(possession));
|
|
assert.equal(await source.read(possession), null);
|
|
assert.equal(await source.read({ ...verifiedPossession() }), null);
|
|
const expired = new StrictDomainRuntimeHandoffSource(handoffEndpoint(), {
|
|
async request(_endpoint, input) { requests += 1; return response(input.requestId); },
|
|
}, () => NOW + 60_000, () => 'HANDOFF-REQ-002');
|
|
assert.equal(await expired.read(verifiedPossession()), null);
|
|
assert.equal(requests, 1);
|
|
});
|
|
|
|
test('fails closed on transport errors without exposing remote details', async () => {
|
|
const source = new StrictDomainRuntimeHandoffSource(handoffEndpoint(), {
|
|
async request() { throw new Error('secret remote detail'); },
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.equal(await source.read(verifiedPossession()), null);
|
|
});
|
|
|
|
function handoffAnchor(includeMap = true) {
|
|
return {
|
|
schema: 'guanghu.public-navigation-anchor/v1',
|
|
anchor_id: 'GLW-PUBLIC-NAV-ANCHOR-001',
|
|
state: 'CURRENT_CANONICAL',
|
|
repository_id: 'REPO-012',
|
|
branch: 'main',
|
|
public_entry: 'https://guanghulab.com/api/ai/v1/anchor',
|
|
code_entry: 'https://guanghulab.com/code/bingshuo/guanghu-ice-heart',
|
|
maps: includeMap ? {
|
|
domain_runtime_handoff_endpoints: {
|
|
path: 'routing/domain-runtime-handoff-endpoints.json',
|
|
id: 'GH-AIOS-DOMAIN-RUNTIME-HANDOFF-ENDPOINTS-001',
|
|
version: '1.0.0',
|
|
},
|
|
} : {},
|
|
navigation_source: {
|
|
anchor_id: 'GLW-PUBLIC-NAV-ANCHOR-001',
|
|
source_commit: 'b'.repeat(40),
|
|
source_mode: 'REPO-012_MAIN_GIT_SNAPSHOT',
|
|
source_degraded: false,
|
|
},
|
|
};
|
|
}
|
|
|
|
function handoffRegistry() {
|
|
return {
|
|
endpoints: [{
|
|
domainIds: [DOMAIN_ID], endpointId: 'GH-DOMAIN-HANDOFF-001', nodeTypes: [NODE_TYPE],
|
|
status: 'ACTIVE', url: 'https://guanghulab.com/api/ai/v1/domain-runtime/handoff',
|
|
}],
|
|
registryId: 'GH-AIOS-DOMAIN-RUNTIME-HANDOFF-ENDPOINTS-001',
|
|
schema: 'gh-aios.domain-runtime-handoff-endpoints/v1',
|
|
state: 'CURRENT', version: '1.0.0',
|
|
};
|
|
}
|
|
|
|
function anchoredLoader(includeMap = true) {
|
|
return new DomainRuntimeHandoffSnapshotLoader({
|
|
async fetchJson(url) {
|
|
if (url.endsWith('/api/ai/v1/anchor')) return handoffAnchor(includeMap);
|
|
if (url.includes('/raw/commit/')) return handoffRegistry();
|
|
throw new Error('unexpected_url');
|
|
},
|
|
});
|
|
}
|
|
|
|
test('anchored source resolves the exact endpoint before consuming possession', async () => {
|
|
const requests: Array<{ endpoint: string; endpointId: string }> = [];
|
|
const source = new AnchoredDomainRuntimeHandoffSource(anchoredLoader(), {
|
|
async request(endpoint, input) {
|
|
requests.push({ endpoint: endpoint.url, endpointId: input.endpointId });
|
|
return response(input.requestId);
|
|
},
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.ok(await source.read(verifiedPossession()));
|
|
assert.deepEqual(requests, [{
|
|
endpoint: 'https://guanghulab.com/api/ai/v1/domain-runtime/handoff',
|
|
endpointId: 'GH-DOMAIN-HANDOFF-001',
|
|
}]);
|
|
});
|
|
|
|
test('missing anchored registry fails before network and does not consume possession', async () => {
|
|
let requests = 0;
|
|
const possession = verifiedPossession();
|
|
const unavailable = new AnchoredDomainRuntimeHandoffSource(anchoredLoader(false), {
|
|
async request() { requests += 1; return null; },
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.equal(await unavailable.read(possession), null);
|
|
assert.equal(requests, 0);
|
|
const current = new AnchoredDomainRuntimeHandoffSource(anchoredLoader(), {
|
|
async request(_endpoint, input) { requests += 1; return response(input.requestId); },
|
|
}, () => NOW + 2, () => 'HANDOFF-REQ-002');
|
|
assert.ok(await current.read(possession));
|
|
assert.equal(requests, 1);
|
|
});
|
|
|
|
test('HTTP transport posts only to the registered endpoint without credentials', async () => {
|
|
const endpoint = handoffEndpoint();
|
|
let observedUrl = '';
|
|
let observedInit: RequestInit | undefined;
|
|
const transport = new HttpDomainRuntimeHandoffTransport(async (url, init) => {
|
|
observedUrl = String(url);
|
|
observedInit = init;
|
|
return new Response(JSON.stringify(response('HANDOFF-REQ-001')), {
|
|
headers: { 'Content-Type': 'application/json' }, status: 200,
|
|
});
|
|
});
|
|
const source = new StrictDomainRuntimeHandoffSource(endpoint, transport, () => NOW + 2, () => 'HANDOFF-REQ-001');
|
|
assert.ok(await source.read(verifiedPossession()));
|
|
assert.equal(observedUrl, endpoint.url);
|
|
assert.equal(observedInit?.method, 'POST');
|
|
assert.equal(observedInit?.credentials, 'omit');
|
|
assert.equal(observedInit?.redirect, 'manual');
|
|
assert.equal(observedInit?.cache, 'no-store');
|
|
assert.equal(observedInit?.referrerPolicy, 'no-referrer');
|
|
assert.equal(JSON.stringify(observedInit?.headers).includes('Authorization'), false);
|
|
});
|
|
|
|
test('HTTP transport rejects redirects, non-JSON and oversized responses', async () => {
|
|
const endpoint = handoffEndpoint();
|
|
const request = Object.freeze({
|
|
accountId: 'bingshuo', challenge: {} as never, domainId: DOMAIN_ID,
|
|
endpointId: endpoint.endpointId, issuedAt: NOW, nodeId: NODE_ID, nodeType: NODE_TYPE,
|
|
registration: {} as never, requestId: 'HANDOFF-REQ-001', response: {} as never,
|
|
schema: 'gh-aios.domain-runtime-handoff-request/v1' as const,
|
|
});
|
|
for (const reply of [
|
|
new Response('', { status: 302, headers: { Location: 'https://example.com/' } }),
|
|
new Response('plain', { status: 200, headers: { 'Content-Type': 'text/plain' } }),
|
|
new Response('{}', { status: 200, headers: { 'Content-Type': 'application/json', 'Content-Length': '262145' } }),
|
|
]) {
|
|
const transport = new HttpDomainRuntimeHandoffTransport(async () => reply);
|
|
await assert.rejects(() => transport.request(endpoint, request));
|
|
}
|
|
});
|