feat: add bounded TCS brains and channel continuity
This commit is contained in:
parent
08598d6356
commit
1d4286c11b
61 changed files with 5416 additions and 54 deletions
152
tcs-core/channel-system/guanghu-broadcast-compiler.mjs
Normal file
152
tcs-core/channel-system/guanghu-broadcast-compiler.mjs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
import { createHash } from "node:crypto";
|
||||
|
||||
const ACTIONS = new Set(["DRAFT", "CONFIRM_LANGUAGE", "CHECK_DISPATCH", "DISPATCH", "REPORT_DELIVERY", "TARGET_ACCEPT", "VERIFY_EFFECT", "CORRECT", "REJECT"]);
|
||||
const STATES = new Set(["DRAFTED", "LANGUAGE_CONFIRMED", "DISPATCH_ELIGIBLE", "DISPATCHED", "DELIVERED", "TARGET_ACCEPTED", "REALITY_VERIFIED", "SUPERSEDED", "REJECTED"]);
|
||||
const SOURCES = new Set(["HUMAN_DIRECT_LANGUAGE", "PERSONA_COMMIT", "MODEL_RESPONSE", "REALITY_EVIDENCE"]);
|
||||
const CLAIMS = new Set(["LANGUAGE_ONTOLOGY", "LANGUAGE_SIMULATION", "ENGINEERING_PROPOSAL", "REALITY_CLAIM"]);
|
||||
|
||||
function required(object, field) {
|
||||
if (typeof object[field] !== "string" || object[field].trim() === "") throw new TypeError(`${field} must be a non-empty string`);
|
||||
}
|
||||
|
||||
function authorized(value) {
|
||||
return Boolean(value?.current && value?.scoped && value?.unexpired && typeof value.ref === "string" && value.ref.length > 0);
|
||||
}
|
||||
|
||||
function proofFor(evidence, target, proof) {
|
||||
return (evidence ?? []).some((item) => item?.external === true && item?.verified === true && item?.target === target && Array.isArray(item.proves) && item.proves.includes(proof));
|
||||
}
|
||||
|
||||
function idFor(value) {
|
||||
return `GH-BR-${createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 20)}`;
|
||||
}
|
||||
|
||||
export function compileBroadcast(event) {
|
||||
if (!event || typeof event !== "object" || Array.isArray(event)) throw new TypeError("event must be an object");
|
||||
for (const field of ["broadcast_id", "action", "current_state", "issuer", "source_layer", "channel_id", "purpose", "claim_layer", "payload_ref", "payload_digest", "requested_effect"]) required(event, field);
|
||||
if (!ACTIONS.has(event.action)) throw new TypeError("unsupported action");
|
||||
if (!STATES.has(event.current_state)) throw new TypeError("unsupported current_state");
|
||||
if (!SOURCES.has(event.source_layer)) throw new TypeError("unsupported source_layer");
|
||||
if (!CLAIMS.has(event.claim_layer)) throw new TypeError("unsupported claim_layer");
|
||||
if (!Array.isArray(event.audience) || event.audience.length === 0 || event.audience.some((value) => typeof value !== "string" || value.length === 0)) throw new TypeError("audience must contain target ids");
|
||||
|
||||
let next = event.current_state;
|
||||
let result = "NO_EXTERNAL_EFFECT";
|
||||
let nextStep = "NONE";
|
||||
const boundaries = [];
|
||||
const evidence = Array.isArray(event.evidence) ? event.evidence : [];
|
||||
const directIssuer = event.source_layer === "HUMAN_DIRECT_LANGUAGE" || event.source_layer === "PERSONA_COMMIT";
|
||||
|
||||
if (event.action === "DRAFT") {
|
||||
next = "DRAFTED";
|
||||
result = "LANGUAGE_DRAFT_ONLY";
|
||||
nextStep = "ISSUER_REVIEW";
|
||||
boundaries.push("DRAFT_IS_NOT_BROADCAST");
|
||||
}
|
||||
if (event.action === "CONFIRM_LANGUAGE") {
|
||||
if (!directIssuer) {
|
||||
next = "REJECTED";
|
||||
nextStep = "REQUIRE_DIRECT_ISSUER_CONFIRMATION";
|
||||
} else {
|
||||
next = "LANGUAGE_CONFIRMED";
|
||||
result = "LANGUAGE_STATE_ONLY";
|
||||
nextStep = "CHECK_DISPATCH_AUTHORIZATION";
|
||||
}
|
||||
boundaries.push("LANGUAGE_CONFIRMATION_IS_NOT_DISPATCH");
|
||||
}
|
||||
if (event.action === "CHECK_DISPATCH") {
|
||||
if (event.current_state !== "LANGUAGE_CONFIRMED" || !authorized(event.authorization)) {
|
||||
next = event.current_state;
|
||||
result = "PENDING_AUTHORIZATION";
|
||||
nextStep = "OBTAIN_CURRENT_SCOPED_DISPATCH_AUTHORIZATION";
|
||||
} else {
|
||||
next = "DISPATCH_ELIGIBLE";
|
||||
result = "DISPATCH_ELIGIBLE_NOT_SENT";
|
||||
nextStep = "SEND_THROUGH_AUTHORIZED_ADAPTER";
|
||||
}
|
||||
}
|
||||
if (event.action === "DISPATCH") {
|
||||
const sent = event.audience.every((target) => proofFor(evidence, target, "DISPATCHED_TO_TARGET_ROUTE"));
|
||||
if (event.current_state !== "DISPATCH_ELIGIBLE" || !authorized(event.authorization) || !sent) {
|
||||
next = event.current_state;
|
||||
result = "NO_VERIFIED_DISPATCH";
|
||||
nextStep = "CAPTURE_PER_TARGET_DISPATCH_RECEIPT";
|
||||
} else {
|
||||
next = "DISPATCHED";
|
||||
result = "DISPATCH_VERIFIED_ONLY";
|
||||
nextStep = "WAIT_FOR_PER_TARGET_DELIVERY";
|
||||
}
|
||||
boundaries.push("DISPATCH_IS_NOT_DELIVERY");
|
||||
}
|
||||
if (event.action === "REPORT_DELIVERY") {
|
||||
const delivered = event.audience.every((target) => proofFor(evidence, target, "DELIVERED_TO_TARGET"));
|
||||
if (!delivered) {
|
||||
result = "DELIVERY_UNVERIFIED";
|
||||
nextStep = "CAPTURE_PER_TARGET_DELIVERY_RECEIPT";
|
||||
} else {
|
||||
next = "DELIVERED";
|
||||
result = "DELIVERY_VERIFIED_ONLY";
|
||||
nextStep = "WAIT_FOR_INDEPENDENT_TARGET_ACCEPTANCE_IF_REQUIRED";
|
||||
}
|
||||
boundaries.push("DELIVERY_IS_NOT_TARGET_ACCEPTANCE");
|
||||
}
|
||||
if (event.action === "TARGET_ACCEPT") {
|
||||
const accepted = event.audience.every((target) => proofFor(evidence, target, "TARGET_ACCEPTED"));
|
||||
if (!accepted) {
|
||||
result = "TARGET_ACCEPTANCE_UNVERIFIED";
|
||||
nextStep = "OBTAIN_INDEPENDENT_TARGET_ACCEPTANCE";
|
||||
} else {
|
||||
next = "TARGET_ACCEPTED";
|
||||
result = "TARGET_ACCEPTANCE_RECORDED";
|
||||
nextStep = "VERIFY_REQUESTED_EFFECT_SEPARATELY";
|
||||
}
|
||||
boundaries.push("TARGET_ACCEPTANCE_IS_NOT_REALITY_EFFECT");
|
||||
}
|
||||
if (event.action === "VERIFY_EFFECT") {
|
||||
const verified = event.audience.every((target) => proofFor(evidence, target, event.requested_effect));
|
||||
if (!verified || event.claim_layer !== "REALITY_CLAIM") {
|
||||
result = "REQUESTED_EFFECT_UNVERIFIED";
|
||||
nextStep = "PROVIDE_SCOPED_EXTERNAL_EFFECT_RECEIPTS";
|
||||
} else {
|
||||
next = "REALITY_VERIFIED";
|
||||
result = "REQUESTED_EFFECT_VERIFIED";
|
||||
nextStep = "CLOSE_WITH_SCOPED_READBACK";
|
||||
}
|
||||
}
|
||||
if (event.action === "CORRECT") {
|
||||
if (typeof event.supersedes !== "string" || event.supersedes.length === 0) {
|
||||
result = "CORRECTION_PENDING_ADDRESSABLE_TARGET";
|
||||
nextStep = "NAME_PRIOR_BROADCAST_ID";
|
||||
} else {
|
||||
next = "SUPERSEDED";
|
||||
result = "PRIOR_BROADCAST_SUPERSEDED_IN_LANGUAGE_RECORD";
|
||||
nextStep = "ISSUE_NEW_DRAFT_AND_RETEST";
|
||||
}
|
||||
}
|
||||
if (event.action === "REJECT") {
|
||||
next = "REJECTED";
|
||||
result = "BROADCAST_REJECTED";
|
||||
}
|
||||
if (event.source_layer === "MODEL_RESPONSE") boundaries.push("MODEL_RESPONSE_IS_NOT_BROADCAST_EVIDENCE");
|
||||
if (event.claim_layer === "LANGUAGE_SIMULATION") boundaries.push("SIMULATION_CANNOT_VERIFY_EXTERNAL_EFFECT");
|
||||
boundaries.push("BROADCAST_DOES_NOT_GRANT_IDENTITY_RELATIONSHIP_OR_AUTHORITY");
|
||||
|
||||
const receipt = {
|
||||
schema: "guanghu.broadcast-receipt/v1",
|
||||
contract_id: "GH-BROADCAST-0001",
|
||||
broadcast_id: event.broadcast_id,
|
||||
issuer: event.issuer,
|
||||
channel_id: event.channel_id,
|
||||
audience: [...event.audience],
|
||||
purpose: event.purpose,
|
||||
payload: { ref: event.payload_ref, digest: event.payload_digest },
|
||||
requested_effect: event.requested_effect,
|
||||
state: { before: event.current_state, after: next },
|
||||
result,
|
||||
evidence,
|
||||
boundaries: [...new Set(boundaries)],
|
||||
supersedes: event.action === "CORRECT" && event.supersedes ? [event.supersedes] : [],
|
||||
next_step: nextStep,
|
||||
};
|
||||
return { ...receipt, receipt_id: idFor(receipt) };
|
||||
}
|
||||
Loading…
Reference in a new issue