@sellable/install
Version:
One-command installer for Sellable MCP in Claude Code, Codex, and Hermes
3,204 lines • 109 kB
JavaScript
import {
createHash,
createPrivateKey,
createPublicKey,
randomUUID,
sign,
verify,
} from "node:crypto";
import {
chmodSync,
closeSync,
existsSync,
fsyncSync,
lstatSync,
mkdirSync,
openSync,
readFileSync,
readdirSync,
realpathSync,
renameSync,
rmSync,
writeFileSync,
} from "node:fs";
import {
basename,
dirname,
isAbsolute,
join,
relative,
resolve,
} from "node:path";
import { readSkillsProofObservation } from "./fly-skills-bridge.mjs";
import {
commitRetainedProfilePromotion,
computeAgentProfileDigest,
deriveContainedProfileId,
finalizeRetainedProfilePromotion,
materializeAgentProfile,
recoverInterruptedProfilePromotion,
} from "./profile-materializer.mjs";
import { runBoundedChildProcess } from "./provisioning-adapter.mjs";
import {
applyRuntimeLifecycle,
projectRuntimeDriftTuple,
reconcileRuntimeRefresh,
} from "./runtime-reconciler.mjs";
export const HOST_WORKER_LIFECYCLE = Object.freeze([
"RECONCILE",
"CLAIM",
"HEARTBEAT",
"CONSUME_SECRET",
"WRITE_REQUEST",
"APPLY_ADAPTER",
"READ_RECEIPT",
"COMPLETE",
"CLEANUP",
]);
export const HOST_WORKER_BROKER_PORTS = Object.freeze([
"claim",
"heartbeat",
"consumeSecret",
"complete",
"getOperation",
]);
export const HOST_WORKER_ADAPTER_PORTS = Object.freeze([
"requiresSecret",
"reconcile",
"apply",
"readReceipt",
]);
const SAFE_ID = /^[A-Za-z0-9_-]{1,128}$/;
const SHA256 = /^[a-f0-9]{64}$/;
const SECRET_PATTERN =
/sat_[A-Za-z0-9_-]+|xox[bap]-[A-Za-z0-9-]+|asec\.v1\.|authorization[_-]?code|access[_-]?token|refresh[_-]?token/i;
const STATE_FILE = "worker-state.json";
export function attachSkillsProofObservation(observed, profileRoot) {
const skills = readSkillsProofObservation(profileRoot);
return skills ? { ...observed, skills } : observed;
}
function stableJson(value) {
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
if (value && typeof value === "object") {
return `{${Object.keys(value)
.sort()
.map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`)
.join(",")}}`;
}
return JSON.stringify(value);
}
export function canonicalHostWorkerDigest(value) {
return createHash("sha256").update(stableJson(value)).digest("hex");
}
function isInside(root, target) {
const path = relative(root, target);
return path === "" || (!path.startsWith("..") && !isAbsolute(path));
}
function realPrivateDirectory(pathValue) {
try {
if (!isAbsolute(pathValue) || !existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isDirectory() ||
(link.mode & 0o077) !== 0
) {
return null;
}
return realpathSync(pathValue);
} catch {
return null;
}
}
function workerSigningAuthority(config) {
const configuredPath = resolve(config?.privateKeyPath ?? "");
const root = realPrivateDirectory(dirname(configuredPath));
const privateKeyPath = root
? join(root, basename(configuredPath))
: configuredPath;
if (!root || !existsSync(privateKeyPath))
throw new Error("worker signing key confinement failed");
const link = lstatSync(privateKeyPath);
if (link.isSymbolicLink() || !link.isFile() || (link.mode & 0o077) !== 0) {
throw new Error("worker signing key rejected");
}
const privateKey = createPrivateKey(readFileSync(privateKeyPath, "utf8"));
if (privateKey.asymmetricKeyType !== "ed25519")
throw new Error("worker signing key type rejected");
const publicKey = createPublicKey(privateKey);
if (publicKey.asymmetricKeyType !== "ed25519")
throw new Error("worker public key type rejected");
const publicKeyPem = publicKey
.export({ type: "spki", format: "pem" })
.toString();
const publicKeyHash = createHash("sha256").update(publicKeyPem).digest("hex");
if (
config.publicKeyHash !== undefined &&
(!SHA256.test(config.publicKeyHash) ||
config.publicKeyHash !== publicKeyHash)
)
throw new Error("worker enrolled public key mismatch");
return { privateKey, publicKey, publicKeyPem, publicKeyHash };
}
function exactPorts(value, names) {
return value && names.every((name) => typeof value[name] === "function");
}
export function validateHostWorkerConfig(config) {
if (!config || typeof config !== "object" || Array.isArray(config)) {
return { ok: false, code: "invalid_worker_config" };
}
for (const key of ["enrollmentId", "hostId", "workerId"]) {
if (!SAFE_ID.test(config[key] ?? "")) {
return { ok: false, code: "invalid_worker_identity", field: key };
}
}
if (
!Number.isSafeInteger(config.signerGeneration) ||
config.signerGeneration < 1 ||
!SHA256.test(config.enrollmentFingerprint ?? "") ||
!realPrivateDirectory(config.requestRoot) ||
!realPrivateDirectory(config.stateRoot) ||
!Number.isSafeInteger(config.leaseSeconds) ||
config.leaseSeconds < 15 ||
config.leaseSeconds > 120 ||
!Number.isSafeInteger(config.poll?.minDelayMs) ||
!Number.isSafeInteger(config.poll?.maxDelayMs) ||
typeof config.poll?.jitterRatio !== "number" ||
config.poll.minDelayMs < 1 ||
config.poll.maxDelayMs < config.poll.minDelayMs ||
config.poll.maxDelayMs > 60_000 ||
config.poll.jitterRatio < 0 ||
config.poll.jitterRatio > 0.5
) {
return { ok: false, code: "invalid_worker_config" };
}
try {
workerSigningAuthority(config);
} catch {
return { ok: false, code: "invalid_worker_signing_key" };
}
return { ok: true, config };
}
function atomicPrivateJson(pathValue, value) {
const parent = dirname(pathValue);
const temp = join(
parent,
`.${basename(pathValue)}.${process.pid}.${randomUUID()}.tmp`
);
const bytes = `${JSON.stringify(value)}\n`;
if (SECRET_PATTERN.test(bytes))
throw new Error("secret material rejected from durable state");
writeFileSync(temp, bytes, { mode: 0o600, flag: "wx" });
chmodSync(temp, 0o600);
const descriptor = openSync(temp, "r");
try {
fsyncSync(descriptor);
} finally {
closeSync(descriptor);
}
renameSync(temp, pathValue);
const parentDescriptor = openSync(parent, "r");
try {
fsyncSync(parentDescriptor);
} finally {
closeSync(parentDescriptor);
}
}
function readState(config) {
const pathValue = join(realpathSync(config.stateRoot), STATE_FILE);
try {
const link = lstatSync(pathValue);
if (link.isSymbolicLink() || !link.isFile() || (link.mode & 0o077) !== 0)
return null;
const parsed = JSON.parse(readFileSync(pathValue, "utf8"));
return parsed && typeof parsed === "object" ? parsed : null;
} catch {
return null;
}
}
function writeState(config, state) {
atomicPrivateJson(join(realpathSync(config.stateRoot), STATE_FILE), {
producer: "sellable-agent-host-worker",
subject: `worker:${config.workerId}`,
...state,
});
}
function startLeaseHeartbeat({ broker, identity, leaseSeconds, scheduler }) {
const clock = scheduler ?? {
schedule(callback, intervalMs) {
return setInterval(callback, intervalMs);
},
cancel(handle) {
clearInterval(handle);
},
};
if (
typeof clock.schedule !== "function" ||
typeof clock.cancel !== "function"
) {
throw new Error("lease heartbeat scheduler rejected");
}
let stopped = false;
let lost = false;
let pending = Promise.resolve();
const tick = () => {
if (stopped || lost) return pending;
pending = pending.then(async () => {
if (stopped || lost) return;
try {
const renewed = await broker.heartbeat({ ...identity, leaseSeconds });
if (!renewed) lost = true;
} catch {
lost = true;
}
});
return pending;
};
const handle = clock.schedule(
tick,
Math.max(1_000, Math.floor((leaseSeconds * 1_000) / 3))
);
return {
async current() {
await pending;
return !lost;
},
async stop() {
if (!stopped) {
stopped = true;
clock.cancel(handle);
}
await pending;
return !lost;
},
};
}
function removeRequest(pathValue, requestRoot) {
try {
const realRoot = realpathSync(requestRoot);
const resolved = resolve(pathValue);
if (dirname(resolved) !== realRoot || !isInside(realRoot, resolved))
return false;
if (!existsSync(resolved)) return true;
const link = lstatSync(resolved);
if (link.isSymbolicLink() || !link.isFile()) return false;
rmSync(resolved, { force: true });
return true;
} catch {
return false;
}
}
function cleanupRequests(config, preservePath = null) {
const root = realpathSync(config.requestRoot);
for (const name of readdirSync(root)) {
const pathValue = join(root, name);
if (preservePath && resolve(preservePath) === pathValue) continue;
removeRequest(pathValue, root);
}
}
function operationIdentity(activeClaim, config) {
return {
operationId: activeClaim.operation.id,
workspaceId: activeClaim.operation.workspaceId,
agentId: activeClaim.operation.agentId,
hostId: config.hostId,
workerEnrollmentId: config.enrollmentId,
workerId: config.workerId,
fence: activeClaim.operation.fence,
targetRevisionId: activeClaim.operation.targetRevisionId,
};
}
function effectId(activeClaim) {
return `sahe_${canonicalHostWorkerDigest({
operationId: activeClaim.operation.id,
workspaceId: activeClaim.operation.workspaceId,
agentId: activeClaim.operation.agentId,
targetRevisionId: activeClaim.operation.targetRevisionId,
})}`;
}
function validateClaim(activeClaim, config, now) {
const operation = activeClaim?.operation;
const revision = activeClaim?.revision;
const kind = validateTrustedAgentKindClaim(activeClaim);
if (!kind.ok) return kind;
if (
!operation ||
!revision ||
!SAFE_ID.test(operation.id ?? "") ||
!SAFE_ID.test(operation.workspaceId ?? "") ||
!SAFE_ID.test(operation.agentId ?? "") ||
!SAFE_ID.test(operation.profileId ?? "") ||
operation.profileId !==
deriveContainedProfileId(
operation.workspaceId,
operation.agentId,
config.hostId
) ||
!SAFE_ID.test(operation.targetRevisionId ?? "") ||
operation.targetRevisionId !== revision.id ||
!Number.isSafeInteger(operation.lifecycleGeneration) ||
operation.lifecycleGeneration < 1 ||
!/^[1-9][0-9]{0,19}$/.test(operation.fence ?? "") ||
!SHA256.test(revision.manifestHash ?? "") ||
new Date(operation.deadlineAt).getTime() <= now.getTime()
) {
return { ok: false, code: "invalid_claim" };
}
if (!exactObject(activeClaim.secretEnvelopes, ["mcpService", "slackBot"])) {
return { ok: false, code: "invalid_secret_envelopes" };
}
for (const [slot, envelope] of Object.entries(activeClaim.secretEnvelopes)) {
if (!envelope) continue;
const expectedPurpose =
slot === "mcpService" ? "service-credential" : "slack-bot";
const expectedProvider = slot === "mcpService" ? "sellable" : "slack";
if (
!SAFE_ID.test(envelope.id ?? "") ||
envelope.purpose !== expectedPurpose ||
envelope.provider !== expectedProvider ||
envelope.workspaceId !== operation.workspaceId ||
envelope.agentId !== operation.agentId ||
envelope.operationId !== operation.id ||
envelope.hostId !== config.hostId ||
envelope.workerEnrollmentId !== config.enrollmentId ||
envelope.workerId !== config.workerId ||
envelope.fence !== operation.fence ||
!Number.isSafeInteger(envelope.generation) ||
envelope.generation < 1 ||
!/^[a-f0-9]{16,64}$/.test(envelope.fingerprint ?? "") ||
new Date(envelope.expiresAt).getTime() <= now.getTime()
)
return { ok: false, code: "invalid_secret_envelope", slot };
}
const desired = compileClaimToProfileDesired(activeClaim, config);
if (!desired.ok) return { ok: false, code: "invalid_runtime_contract" };
return { ok: true };
}
export function validateTrustedAgentKindClaim(activeClaim) {
const present = Object.prototype.hasOwnProperty.call(
activeClaim ?? {},
"agentKind"
);
const generation = activeClaim?.adminRuntimeGeneration;
if (!present) {
return generation === undefined
? { ok: true, agentKind: "CUSTOMER" }
: { ok: false, code: "customer_admin_generation_rejected" };
}
if (
activeClaim.agentKind !== "ADMIN" ||
generation?.agentKind !== "ADMIN" ||
!["PREPARING", "PROVING", "ACTIVE", "DEMOTING"].includes(
generation?.state
) ||
generation?.workspaceId !== activeClaim.operation?.workspaceId ||
generation?.agentId !== activeClaim.operation?.agentId ||
generation?.fence !== activeClaim.operation?.fence
)
return { ok: false, code: "admin_runtime_generation_claim_rejected" };
return { ok: true, agentKind: "ADMIN", generation };
}
function requiredSecretSlots(activeClaim) {
if (["INSTANTIATE", "RESTORE"].includes(activeClaim.operation.action))
return ["mcpService", "slackBot"];
if (activeClaim.operation.action === "ROTATE_CREDENTIAL")
return ["mcpService"];
return [];
}
function existingRequestForState(state, activeClaim, config, currentEffectId) {
try {
if (
state?.effectId !== currentEffectId ||
state?.operationId !== activeClaim.operation.id ||
state?.fence !== activeClaim.operation.fence ||
typeof state.requestFile !== "string"
)
return null;
const realRoot = realpathSync(config.requestRoot);
const pathValue = resolve(state.requestFile);
if (dirname(pathValue) !== realRoot || !existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isFile() ||
(link.mode & 0o777) !== 0o600
)
return null;
const parsed = JSON.parse(readFileSync(pathValue, "utf8"));
if (
parsed.operationId !== activeClaim.operation.id ||
parsed.fence !== activeClaim.operation.fence
)
return null;
let present = 0;
for (const slot of requiredSecretSlots(activeClaim)) {
const envelope = activeClaim.secretEnvelopes[slot];
const prefix = slot === "mcpService" ? "mcpService" : "slackBot";
const secretKey =
slot === "mcpService" ? "serviceCredential" : "slackBotCredential";
if (parsed[secretKey] === undefined) continue;
present += 1;
if (
!envelope ||
parsed[`${prefix}EnvelopeId`] !== envelope.id ||
parsed[`${prefix}Generation`] !== envelope.generation ||
typeof parsed[secretKey] !== "string" ||
!parsed[secretKey]
)
return null;
}
if (present === 0) return null;
return pathValue;
} catch {
return null;
}
}
function writeRequest(config, activeClaim, currentEffectId, secrets) {
const requestRoot = realpathSync(config.requestRoot);
const pathValue = join(requestRoot, `${currentEffectId}.request.json`);
const temp = join(requestRoot, `.${currentEffectId}.${randomUUID()}.tmp`);
const payload = {
producer: "sellable-agent-host-worker",
operationId: activeClaim.operation.id,
workspaceId: activeClaim.operation.workspaceId,
agentId: activeClaim.operation.agentId,
revisionId: activeClaim.operation.targetRevisionId,
fence: activeClaim.operation.fence,
...(secrets.mcpService
? {
mcpServiceEnvelopeId: activeClaim.secretEnvelopes.mcpService.id,
mcpServiceGeneration: secrets.mcpService.generation,
serviceCredential: secrets.mcpService.secret,
}
: {}),
...(secrets.slackBot
? {
slackBotEnvelopeId: activeClaim.secretEnvelopes.slackBot.id,
slackBotGeneration: secrets.slackBot.generation,
slackBotCredential: secrets.slackBot.secret,
}
: {}),
};
writeFileSync(temp, `${JSON.stringify(payload)}\n`, {
mode: 0o600,
flag: "wx",
});
chmodSync(temp, 0o600);
const fileDescriptor = openSync(temp, "r");
try {
fsyncSync(fileDescriptor);
} finally {
closeSync(fileDescriptor);
}
renameSync(temp, pathValue);
const parentDescriptor = openSync(requestRoot, "r");
try {
fsyncSync(parentDescriptor);
} finally {
closeSync(parentDescriptor);
}
return pathValue;
}
function readRequestSecrets(requestFile) {
if (!requestFile) return {};
const parsed = JSON.parse(readFileSync(requestFile, "utf8"));
return {
...(parsed.serviceCredential
? {
mcpService: {
generation: parsed.mcpServiceGeneration,
secret: parsed.serviceCredential,
},
}
: {}),
...(parsed.slackBotCredential
? {
slackBot: {
generation: parsed.slackBotGeneration,
secret: parsed.slackBotCredential,
},
}
: {}),
};
}
function claimHasSecrets(activeClaim) {
return requiredSecretSlots(activeClaim).length > 0;
}
function validReceipt(receipt, activeClaim, config) {
if (!receipt || typeof receipt !== "object" || Array.isArray(receipt))
return false;
const serialized = JSON.stringify(receipt);
const identity = operationIdentity(activeClaim, config);
const receiptKeys = [
"operationId",
"workspaceId",
"agentId",
"hostId",
"workerEnrollmentId",
"workerId",
"fence",
"targetRevisionId",
"status",
"secretDisposition",
"observedLifecycle",
"observedRevisionId",
"signerGeneration",
"signedDigest",
"runtimeHashes",
"conditions",
"errorClass",
"auditIds",
];
const runtimeHashKeys = ["package", "config", "content", "process"];
return (
serialized.length <= 16 * 1024 &&
!SECRET_PATTERN.test(serialized) &&
Object.keys(receipt).sort().join("\0") === receiptKeys.sort().join("\0") &&
receipt.runtimeHashes &&
Object.keys(receipt.runtimeHashes).sort().join("\0") ===
runtimeHashKeys.sort().join("\0") &&
Object.values(receipt.runtimeHashes).every(
(value) => value === null || SHA256.test(value)
) &&
Array.isArray(receipt.conditions) &&
receipt.conditions.every(
(condition) =>
condition &&
Object.keys(condition).sort().join("\0") ===
["code", "status"].sort().join("\0") &&
/^[A-Z][A-Z0-9_]{0,63}$/.test(condition.code) &&
["TRUE", "FALSE", "UNKNOWN"].includes(condition.status)
) &&
Array.isArray(receipt.auditIds) &&
receipt.auditIds.every((value) => SAFE_ID.test(value)) &&
Object.entries(identity).every(([key, value]) => receipt[key] === value) &&
["SUCCEEDED", "FAILED", "UNCERTAIN", "BLOCKED"].includes(receipt.status) &&
[
"NOT_PRESENT",
"NOT_CONSUMED",
"REDELIVERABLE",
"INSTALLED",
"UNCERTAIN",
].includes(receipt.secretDisposition) &&
SHA256.test(receipt.signedDigest ?? "") &&
receipt.signerGeneration === config.signerGeneration &&
(receipt.status === "SUCCEEDED"
? receipt.secretDisposition ===
(claimHasSecrets(activeClaim) ? "INSTALLED" : "NOT_PRESENT") &&
receipt.observedRevisionId === activeClaim.operation.targetRevisionId
: receipt.secretDisposition !== "INSTALLED")
);
}
function validDurableUncertainReceipt(receipt, state, config) {
if (!receipt || typeof receipt !== "object" || Array.isArray(receipt))
return false;
const serialized = JSON.stringify(receipt);
const receiptKeys = [
"operationId",
"workspaceId",
"agentId",
"hostId",
"workerEnrollmentId",
"workerId",
"fence",
"targetRevisionId",
"status",
"secretDisposition",
"observedLifecycle",
"observedRevisionId",
"signerGeneration",
"signedDigest",
"runtimeHashes",
"conditions",
"errorClass",
"auditIds",
];
const runtimeHashKeys = ["package", "config", "content", "process"];
const { signedDigest, ...body } = receipt;
return (
["LEASE_LOST", "LEASE_UNCERTAIN"].includes(state?.status) &&
SAFE_ID.test(state?.effectId ?? "") &&
serialized.length <= 16 * 1024 &&
!SECRET_PATTERN.test(serialized) &&
Object.keys(receipt).sort().join("\0") === receiptKeys.sort().join("\0") &&
receipt.operationId === state.operationId &&
receipt.fence === state.fence &&
receipt.hostId === config.hostId &&
receipt.workerEnrollmentId === config.enrollmentId &&
receipt.workerId === config.workerId &&
receipt.status === "UNCERTAIN" &&
receipt.secretDisposition === "UNCERTAIN" &&
receipt.observedLifecycle === "DEGRADED" &&
receipt.observedRevisionId === null &&
receipt.signerGeneration === config.signerGeneration &&
receipt.errorClass !== "NONE" &&
SAFE_ID.test(receipt.operationId ?? "") &&
SAFE_ID.test(receipt.workspaceId ?? "") &&
SAFE_ID.test(receipt.agentId ?? "") &&
(receipt.targetRevisionId === null ||
SAFE_ID.test(receipt.targetRevisionId)) &&
receipt.runtimeHashes &&
Object.keys(receipt.runtimeHashes).sort().join("\0") ===
runtimeHashKeys.sort().join("\0") &&
Object.values(receipt.runtimeHashes).every(
(value) => value === null || SHA256.test(value)
) &&
Array.isArray(receipt.conditions) &&
receipt.conditions.length > 0 &&
receipt.conditions.every(
(condition) =>
condition &&
Object.keys(condition).sort().join("\0") ===
["code", "status"].sort().join("\0") &&
/^[A-Z][A-Z0-9_]{0,63}$/.test(condition.code) &&
["TRUE", "FALSE", "UNKNOWN"].includes(condition.status)
) &&
Array.isArray(receipt.auditIds) &&
receipt.auditIds.length > 0 &&
receipt.auditIds.every((value) => SAFE_ID.test(value)) &&
SHA256.test(signedDigest ?? "") &&
signedDigest === canonicalHostWorkerDigest(body)
);
}
function readDurableUncertainReceipt(config, state) {
try {
if (!SAFE_ID.test(state?.effectId ?? "")) return null;
const pathValue = confinedReceiptPath(config, state.effectId);
if (!existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isFile() ||
(link.mode & 0o777) !== 0o600
)
return null;
const receipt = JSON.parse(readFileSync(pathValue, "utf8"));
return validDurableUncertainReceipt(receipt, state, config)
? receipt
: null;
} catch {
return null;
}
}
async function callCheckpoint(checkpoint, name) {
if (checkpoint) await checkpoint(name);
}
export async function runHostWorkerCycle(input = {}) {
const checked = validateHostWorkerConfig(input.config);
if (!checked.ok)
return { ok: false, status: "INVALID_CONFIG", code: checked.code };
const { config, broker, adapter } = input;
if (
!exactPorts(broker, HOST_WORKER_BROKER_PORTS) ||
!exactPorts(adapter, HOST_WORKER_ADAPTER_PORTS)
) {
return { ok: false, status: "INVALID_PORT", code: "worker_port_missing" };
}
const now = input.now ?? new Date();
let state = readState(config);
let leaseHeartbeat = null;
const recoveryState = state;
const preservedRequest =
state?.status === "REQUEST_WRITTEN" || state?.status === "APPLYING"
? state.requestFile
: null;
cleanupRequests(config, preservedRequest);
try {
if (state?.status === "COMPLETED" && state.operationId) {
const remote = await broker.getOperation({
operationId: state.operationId,
});
if (remote?.status === "SUCCEEDED" && remote.fence === state.fence) {
cleanupRequests(config);
return {
ok: true,
status: "ALREADY_COMPLETED",
operationId: state.operationId,
fence: state.fence,
};
}
}
const durableUncertainty = readDurableUncertainReceipt(config, state);
if (durableUncertainty) {
let completion;
try {
completion = await broker.complete(durableUncertainty);
} catch {
return {
ok: false,
status: "UNCERTAINTY_PENDING",
code: "broker_unavailable",
operationId: state.operationId,
fence: state.fence,
};
}
if (completion?.accepted) {
cleanupRequests(config);
writeState(config, {
...state,
status: "UNCERTAINTY_RECORDED",
requestFile: undefined,
});
return {
ok: true,
status: "UNCERTAINTY_RECORDED",
operationId: state.operationId,
fence: state.fence,
};
}
return {
ok: false,
status: "UNCERTAINTY_PENDING",
code: completion?.code ?? "completion_rejected",
operationId: state.operationId,
fence: state.fence,
};
}
let activeClaim;
try {
activeClaim = await broker.claim({ leaseSeconds: config.leaseSeconds });
} catch {
const observationId = `obs_${canonicalHostWorkerDigest({
class: "BROKER_UNAVAILABLE",
workerId: config.workerId,
previousObservationId: state?.observationId ?? null,
})}`;
const strategyFingerprint = canonicalHostWorkerDigest({
hypothesis:
"broker unavailable; bounded backoff then re-observe claim surface",
primitive: "wait_then_claim",
target: config.hostId,
observationId,
});
writeState(config, {
status: "BROKER_UNAVAILABLE",
observationId,
strategyFingerprint,
});
return {
ok: false,
status: "BROKER_UNAVAILABLE",
observationId,
strategyFingerprint,
};
}
if (!activeClaim) {
cleanupRequests(config);
return { ok: true, status: "IDLE" };
}
const valid = validateClaim(activeClaim, config, now);
if (!valid.ok) {
cleanupRequests(config);
return { ok: false, status: "CLAIM_REJECTED", code: valid.code };
}
const currentEffectId = effectId(activeClaim);
const previousObservationId = state?.observationId ?? null;
const strategyFingerprint = canonicalHostWorkerDigest({
hypothesis:
"claimed operation requires exact-effect reconciliation before mutation",
primitive: "reconcile_then_apply",
target: currentEffectId,
observationId: previousObservationId,
});
state = {
status: "CLAIMED",
operationId: activeClaim.operation.id,
effectId: currentEffectId,
fence: activeClaim.operation.fence,
strategyFingerprint,
observationId: previousObservationId,
};
writeState(config, state);
await callCheckpoint(input.checkpoint, "after-claim");
const identity = operationIdentity(activeClaim, config);
const renewed = await broker.heartbeat({
...identity,
leaseSeconds: config.leaseSeconds,
});
if (!renewed) {
cleanupRequests(config);
writeState(config, {
...state,
status: "LEASE_LOST",
requestFile: undefined,
});
return {
ok: false,
status: "LEASE_LOST",
operationId: identity.operationId,
fence: identity.fence,
};
}
leaseHeartbeat = startLeaseHeartbeat({
broker,
identity,
leaseSeconds: config.leaseSeconds,
scheduler: input.heartbeatScheduler,
});
const requireCurrentLease = async () => {
if (await leaseHeartbeat.current()) return;
const error = new Error("periodic lease heartbeat lost");
error.code = "LEASE_UNCERTAIN";
throw error;
};
const reconciled = await adapter.reconcile({
activeClaim,
effectId: currentEffectId,
});
await requireCurrentLease();
const secretSlots = await adapter.requiresSecret({
activeClaim,
effectId: currentEffectId,
reconciled,
});
await requireCurrentLease();
if (
!Array.isArray(secretSlots) ||
JSON.stringify(secretSlots) !==
JSON.stringify(requiredSecretSlots(activeClaim))
)
throw new Error("adapter secret predicate invalid");
let receipt = await adapter.readReceipt({
activeClaim,
effectId: currentEffectId,
});
let requestFile = existingRequestForState(
recoveryState,
activeClaim,
config,
currentEffectId
);
if (!requestFile && preservedRequest)
removeRequest(preservedRequest, config.requestRoot);
if (!validReceipt(receipt, activeClaim, config)) {
receipt = null;
if (secretSlots.length > 0) {
const missingSlot = secretSlots.find(
(slot) => !activeClaim.secretEnvelopes[slot]
);
if (missingSlot) {
cleanupRequests(config);
return {
ok: false,
status: "SECRET_REQUIRED",
code: `${missingSlot}_envelope_missing`,
};
}
const secrets = readRequestSecrets(requestFile);
for (const slot of secretSlots) {
if (secrets[slot]) continue;
const envelope = activeClaim.secretEnvelopes[slot];
if (!envelope) {
cleanupRequests(config);
return {
ok: false,
status: "SECRET_REQUIRED",
code: `${slot}_envelope_missing`,
};
}
const secretResult = await broker.consumeSecret({
...identity,
envelopeId: envelope.id,
claimId: canonicalHostWorkerDigest({
currentEffectId,
fence: identity.fence,
slot,
}).slice(0, 32),
});
await requireCurrentLease();
const secretFingerprint =
typeof secretResult?.secret === "string"
? createHash("sha256")
.update(secretResult.secret)
.digest("hex")
.slice(0, 16)
: null;
if (
!secretResult?.ok ||
typeof secretResult.secret !== "string" ||
secretResult.generation !== envelope.generation ||
secretFingerprint !== envelope.fingerprint
) {
cleanupRequests(config);
writeState(config, {
...state,
status: "SECRET_UNCERTAIN",
requestFile: undefined,
});
return {
ok: false,
status: "SECRET_UNCERTAIN",
code: secretResult?.code ?? "secret_consume_failed",
};
}
secrets[slot] = secretResult;
requestFile = writeRequest(
config,
activeClaim,
currentEffectId,
secrets
);
writeState(config, {
...state,
status: "REQUEST_WRITTEN",
requestFile,
});
await callCheckpoint(input.checkpoint, `after-unwrap-${slot}`);
}
await callCheckpoint(input.checkpoint, "after-unwrap");
}
if (secretSlots.length === 0 && requestFile) {
removeRequest(requestFile, config.requestRoot);
requestFile = null;
}
await callCheckpoint(input.checkpoint, "before-adapter");
writeState(config, {
...state,
status: "APPLYING",
requestFile,
reconciledStatus: reconciled?.status ?? "UNKNOWN",
});
await adapter.apply({
activeClaim,
requestFile,
effectId: currentEffectId,
reconciled,
checkpoint: (name) => callCheckpoint(input.checkpoint, name),
});
await requireCurrentLease();
receipt = await adapter.readReceipt({
activeClaim,
effectId: currentEffectId,
});
await requireCurrentLease();
}
if (!validReceipt(receipt, activeClaim, config)) {
cleanupRequests(config);
writeState(config, {
...state,
status: "RECEIPT_INVALID",
requestFile: undefined,
});
return { ok: false, status: "RECEIPT_INVALID" };
}
writeState(config, { ...state, status: "RECEIPT_DURABLE", requestFile });
await callCheckpoint(input.checkpoint, "after-receipt");
if (!(await leaseHeartbeat.stop())) {
const error = new Error("periodic lease heartbeat lost");
error.code = "LEASE_UNCERTAIN";
throw error;
}
leaseHeartbeat = null;
const current = await broker.heartbeat({
...identity,
leaseSeconds: config.leaseSeconds,
});
if (!current) {
cleanupRequests(config);
writeState(config, {
...state,
status: "LEASE_LOST",
requestFile: undefined,
});
return {
ok: false,
status: "LEASE_LOST",
operationId: identity.operationId,
fence: identity.fence,
};
}
const completion = await broker.complete(receipt);
if (!completion?.accepted) {
cleanupRequests(config);
writeState(config, {
...state,
status: "LEASE_LOST",
requestFile: undefined,
});
return {
ok: false,
status: "LEASE_LOST",
code: completion?.code ?? "completion_rejected",
};
}
cleanupRequests(config);
writeState(config, {
...state,
status: "COMPLETED",
requestFile: undefined,
});
return {
ok: true,
status: "COMPLETED",
operationId: identity.operationId,
fence: identity.fence,
};
} catch (error) {
if (error?.code === "LEASE_UNCERTAIN") {
cleanupRequests(config);
writeState(config, {
...state,
status: "LEASE_UNCERTAIN",
requestFile: undefined,
});
return {
ok: false,
status: "LEASE_UNCERTAIN",
code: "periodic_lease_lost",
operationId: state?.operationId ?? null,
fence: state?.fence ?? null,
resumePredicate: "reconcile_exact_effect_before_retry",
};
}
if (error?.code === "SIMULATED_CRASH") {
const current = readState(config) ?? state ?? {};
writeState(config, {
...current,
status: current.status ?? "CRASHED",
crashSeam: String(error.message).replace(/^.* at /, ""),
});
return { ok: false, status: "CRASHED", code: "simulated_crash" };
}
cleanupRequests(config);
const observationId = `obs_${canonicalHostWorkerDigest({
class: "HOST_RUNTIME",
operationId: state?.operationId ?? null,
effectId: state?.effectId ?? null,
})}`;
writeState(config, {
...(state ?? {}),
status: "FAILED",
errorClass: "HOST_RUNTIME",
observationId,
requestFile: undefined,
});
return {
ok: false,
status: "FAILED",
code: "host_runtime_failed",
observationId,
};
} finally {
if (leaseHeartbeat) await leaseHeartbeat.stop();
}
}
function safeObservedFile(pathValue, { executable = false, ownerUid } = {}) {
const link = lstatSync(pathValue);
if (link.isSymbolicLink() || !link.isFile())
throw new Error("unsafe observed file");
const mode = link.mode & 0o777;
if (
!Number.isSafeInteger(ownerUid) ||
ownerUid < 0 ||
link.uid !== ownerUid ||
(mode & 0o022) !== 0 ||
(executable && (mode & 0o111) === 0)
) {
throw new Error("unsafe observed mode");
}
return { bytes: readFileSync(pathValue), stat: link };
}
export function observeInstalledWorkerService(input) {
try {
const trustedRootUid =
input.disposableFixture === true ? input.expectedRootUid : 0;
if (
!Number.isSafeInteger(trustedRootUid) ||
trustedRootUid < 0 ||
!Number.isSafeInteger(input.expectedWorkerUid) ||
input.expectedWorkerUid < 1 ||
typeof input.expectedWorkerUser !== "string" ||
!SAFE_ID.test(input.expectedWorkerUser) ||
typeof input.resolveUser !== "function" ||
input.resolveUser(input.expectedWorkerUid) !== input.expectedWorkerUser
)
return { ok: false, code: "service_identity_invalid" };
const executable = safeObservedFile(input.executablePath, {
executable: true,
ownerUid: trustedRootUid,
});
const runScript = safeObservedFile(input.runScriptPath, {
executable: true,
ownerUid: trustedRootUid,
});
const packageFile = safeObservedFile(input.packagePath, {
ownerUid: trustedRootUid,
});
const entrypoint = safeObservedFile(input.entrypointPath, {
ownerUid: trustedRootUid,
});
const nodeExecutable = safeObservedFile(input.nodeExecutablePath, {
executable: true,
ownerUid: trustedRootUid,
});
const enrollment = safeObservedFile(input.enrollmentPath, {
ownerUid: trustedRootUid,
});
const pidFile = safeObservedFile(input.pidPath, {
ownerUid: trustedRootUid,
});
const enrollmentFingerprint = enrollment.bytes.toString("utf8").trim();
const pidText = pidFile.bytes.toString("utf8").trim();
if (
!SHA256.test(enrollmentFingerprint) ||
!/^[1-9][0-9]{0,9}$/.test(pidText) ||
!isAbsolute(input.configPath)
) {
return { ok: false, code: "service_identity_invalid" };
}
const pid = Number(pidText);
const statText = readFileSync(
join(input.procRoot, pidText, "stat"),
"utf8"
).trim();
const statusText = readFileSync(
join(input.procRoot, pidText, "status"),
"utf8"
);
const uidMatch = statusText.match(
/^Uid:\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*$/m
);
const processUids = uidMatch ? uidMatch.slice(1).map(Number) : [];
const processUid = processUids[0] ?? null;
const observedExecutable = realpathSync(
join(input.procRoot, pidText, "exe")
);
const expectedNodeExecutable = realpathSync(input.nodeExecutablePath);
const cmdline = readFileSync(join(input.procRoot, pidText, "cmdline"))
.toString("utf8")
.split("\0")
.filter(Boolean);
const expectedCommand = [
input.nodeExecutablePath,
input.entrypointPath,
"--config",
input.configPath,
];
const closeParen = statText.lastIndexOf(") ");
if (closeParen < 0 || !statText.startsWith(`${pid} (`)) {
return { ok: false, code: "process_identity_invalid" };
}
const processFields = statText.slice(closeParen + 2).split(/\s+/);
const processStartTicks = processFields[19];
const bootId = readFileSync(input.bootIdPath, "utf8").trim();
if (
!/^[0-9]+$/.test(processStartTicks ?? "") ||
!bootId ||
bootId.length > 128 ||
processUids.length !== 4 ||
processUids.some((uid) => uid !== input.expectedWorkerUid) ||
observedExecutable !== expectedNodeExecutable ||
JSON.stringify(cmdline) !== JSON.stringify(expectedCommand)
) {
return { ok: false, code: "process_identity_invalid" };
}
return {
ok: true,
health: "READY",
serviceUser: input.expectedWorkerUser,
enrollmentFingerprint,
pid,
processUid,
processExecutable: observedExecutable,
processStartTicks,
bootId,
digests: {
executable: createHash("sha256").update(executable.bytes).digest("hex"),
entrypoint: createHash("sha256").update(entrypoint.bytes).digest("hex"),
nodeExecutable: createHash("sha256")
.update(nodeExecutable.bytes)
.digest("hex"),
runScript: createHash("sha256").update(runScript.bytes).digest("hex"),
package: createHash("sha256").update(packageFile.bytes).digest("hex"),
},
};
} catch {
return { ok: false, code: "service_observation_failed" };
}
}
function parseMainArguments(argv) {
if (argv.length !== 2 || argv[0] !== "--config" || !isAbsolute(argv[1]))
return null;
return argv[1];
}
function createWorkerPromotionJournal(config) {
const { privateKey, publicKey } = workerSigningAuthority(config);
return {
signerGeneration: config.signerGeneration,
sign(body) {
return sign(null, Buffer.from(stableJson(body)), privateKey).toString(
"base64url"
);
},
verify(body, signature) {
try {
return verify(
null,
Buffer.from(stableJson(body)),
publicKey,
Buffer.from(signature, "base64url")
);
} catch {
return false;
}
},
};
}
export function buildSignedWorkerAuthorization({
config,
verb,
body,
now = new Date(),
}) {
const { privateKey, publicKeyPem } = workerSigningAuthority(config);
const claims = {
enrollmentId: config.enrollmentId,
hostId: config.hostId,
workerId: config.workerId,
audience: "sellable-agent-worker/v1",
keyGeneration: config.signerGeneration,
verb,
operationId: body.operationId ?? null,
workspaceId: body.workspaceId ?? null,
agentId: body.agentId ?? null,
fence: body.fence ?? null,
targetRevisionId: body.targetRevisionId ?? null,
bodyDigest: canonicalHostWorkerDigest(body),
nonce: randomUUID(),
issuedAt: now.toISOString(),
expiresAt: new Date(now.getTime() + 60_000).toISOString(),
};
const signature = sign(
null,
Buffer.from(stableJson(claims)),
privateKey
).toString("base64url");
return `Worker ${Buffer.from(JSON.stringify({ claims, publicKeyPem, signature })).toString("base64url")}`;
}
export function createHttpWorkerBroker(config, fetchImpl = fetch) {
workerSigningAuthority(config);
const endpoint = String(config.controlPlaneUrl ?? "").replace(/\/$/, "");
if (!/^https:\/\//.test(endpoint))
throw new Error("https control plane required");
const post = async (verb, path, body) => {
const authorization = buildSignedWorkerAuthorization({
config,
verb,
body,
});
const response = await fetchImpl(`${endpoint}${path}`, {
method: "POST",
headers: { authorization, "content-type": "application/json" },
body: JSON.stringify(body),
signal: AbortSignal.timeout(15_000),
});
const value = await response.json();
if (!response.ok)
return {
ok: false,
code: value.error ?? value.code ?? "broker_rejected",
};
return value;
};
return {
async claim(body) {
return (
(await post("claim", "/api/v3/sellable-agent/worker/claim", body))
.claim ?? null
);
},
async heartbeat(body) {
return (
(
await post(
"heartbeat",
"/api/v3/sellable-agent/worker/heartbeat",
body
)
).renewed === true
);
},
async consumeSecret(body) {
const value = await post(
"secret-consume",
"/api/v3/sellable-agent/worker/secret-consume",
body
);
return value.ok === false ? value : { ok: true, ...value };
},
async complete(body) {
return post("complete", "/api/v3/sellable-agent/worker/complete", body);
},
async getOperation() {
return null;
},
};
}
function confinedReceiptPath(config, effectId) {
const stateRoot = realpathSync(config.stateRoot);
const receiptRoot = join(stateRoot, "receipts");
if (!existsSync(receiptRoot))
mkdirSync(receiptRoot, { recursive: true, mode: 0o700 });
const realReceiptRoot = realpathSync(receiptRoot);
const pathValue = join(realReceiptRoot, `${effectId}.json`);
if (dirname(pathValue) !== realReceiptRoot)
throw new Error("receipt confinement failed");
return pathValue;
}
function exactObject(value, keys) {
return Boolean(
value &&
typeof value === "object" &&
!Array.isArray(value) &&
Object.keys(value).sort().join("\0") === [...keys].sort().join("\0")
);
}
function safeArtifactContent(artifacts, type) {
const selected = artifacts
.filter((artifact) => artifact.type === type)
.sort((left, right) => left.logicalPath.localeCompare(right.logicalPath));
if (
selected.length === 0 ||
selected.some((artifact) => typeof artifact.safeContent !== "string")
) {
return null;
}
for (const artifact of selected) {
if (
Buffer.byteLength(artifact.safeContent) !== artifact.sizeBytes ||
createHash("sha256").update(artifact.safeContent).digest("hex") !==
artifact.contentHash ||
SECRET_PATTERN.test(artifact.safeContent)
)
return null;
}
return selected.map((artifact) => artifact.safeContent).join("\n");
}
/**
* Compile only the real Plan 02 AgentWorkerClaim DTO plus installer-owned pins.
* Plan 04 must populate the installation-scoped Slack identity contract; absence
* is an explicit fail-closed dependency, never an invented runtime identity.
*/
export function compileClaimToProfileDesired(activeClaim, config) {
try {
const operation = activeClaim?.operation;
const revision = activeClaim?.revision;
const manifest = revision?.manifest;
if (
!exactObject(manifest, [
"version",
"compilerVersion",
"agent",
"slack",
"service",
"artifacts",
]) ||
manifest.version !== 1 ||
manifest.compilerVersion !== "sellable-agent/v1" ||
revision.compilerVersion !== manifest.compilerVersion ||
revision.id !== operation.targetRevisionId ||
!SAFE_ID.test(operation.profileId ?? "") ||
operation.profileId !==
deriveContainedProfileId(
operation.workspaceId,
operation.agentId,
config.hostId
) ||
!exactObject(manifest.agent, [
"workspaceId",
"agentId",
"slug",
"name",
"role",
"desiredLifecycle",
"setupGeneration",
"configGeneration",
]) ||
manifest.agent.workspaceId !== operation.workspaceId ||
manifest.agent.agentId !== operation.agentId ||
manifest.agent.setupGeneration !== operation.setupGeneration ||
manifest.agent.configGeneration !== operation.configGeneration ||
!Number.isSafeInteger(operation.lifecycleGeneration) ||
operation.lifecycleGeneration < 1 ||
!exactObject(manifest.slack, [
"installationId",
"selectedBindingIds",
"defaultBindingId",
]) ||
!Array.isArray(manifest.slack.selectedBindingIds) ||
!manifest.slack.selectedBindingIds.includes(
manifest.slack.defaultBindingId
) ||
!exactObject(manifest.service, [
"principalId",
"policyHash",
"issuerReady",
]) ||
manifest.service.issuerReady !== true ||
!SHA256.test(manifest.service.policyHash ?? "") ||
!Array.isArray(manifest.artifacts) ||
!Array.isArray(revision.artifacts)
)
return { ok: false, code: "claim_runtime_manifest_invalid" };
const projectedArtifacts = revision.artifacts.map(
({ safeContent: _safeContent, ...artifact }) => artifact
);
if (stableJson(projectedArtifacts) !== stableJson(manifest.artifacts)) {
return { ok: false, code: "claim_artifact_identity_invalid" };
}
const soul = safeArtifactContent(revision.artifacts, "SOUL");
const skill = safeArtifactContent(revision.artifacts, "SKILL");
if (soul === null || skill === null)
return { ok: false, code: "claim_safe_content_missing" };
const pinned = config.profileRuntimeContract;
const runtime = activeClaim.runtimeContract;
const slack = runtime?.slack;
const runtimeService = runtime?.service;
const policy = pinned?.policies?.[manifest.service.policyHash];
const credentialIdentity = activeClaim.secretEnvelopes?.mcpService ?? {
generation: runtimeService?.credentialGeneration,
fingerprint: runtimeService?.credentialFingerprint,
};
const selectedBindingIds = slack?.selectedBindings?.map(
(binding) => binding.id
);
const channelIds = slack?.selectedBindings
?.map((binding) => binding.channelId)
.sort();
const defaultBinding = slack?.selectedBindings?.find(
(binding) => binding.id === slack.defaultBindingId
);
if (
!pinned ||
!runtime ||
!slack ||
!runtimeService ||
!policy ||
!exactObject(runtime, ["slack", "service"]) ||
!exactObject(slack, [
"installationId",
"generation",
"appId",
"teamId",
"botUserId",
"scopes",
"credentialFingerprint",
"selectedBindings",
"defaultBindingId",
"memberAllowlist",
"hashes",
]) ||
!exactObject(runtimeService, [
"principalId",
"policyHash",
"credentialGeneration",
"credentialFingerprint",
]) ||
pinned.hermesCli !== "hermes" ||
pinned.hermesVersion !== "0.18.0" ||
pinned.installerPackage !== "@sellable/install@0.1.804" ||
pinned.mcpPackage !== "@sellable/mcp@0.1.957" ||
!Array.isArray(policy.toolInclude) ||
policy.toolInclude.length === 0 ||
!Number.isSafeInteger(slack.generation) ||
slack.generation < 1 ||
!/^A[A-Z0-9]{8,20}$/.test(slack.appId ?? "") ||
!/^T[A-Z0-9]{8,20}$/.test(slack.teamId ?? "") ||
!/^[UW][A-Z0-9]{8,20}$/.test(slack.botUserId ?? "") ||
!Array.isArray(slack.scopes) ||
slack.scopes.length === 0 ||
stableJson(slack.scopes) !==
stableJson([...new Set(slack.scopes)].sort()) ||
!Array.isArray(slack.selectedBindings) ||
slack.selectedBindings.some(
(binding) =>
!exactObject(binding, [
"id",
"channelId",
"channelName",
"isDefaultVerification",
])
) ||
stableJson(selectedBindingIds) !==
stableJson([...manifest.slack.selectedBindingIds].sort()) ||
slack.installationId !== manifest.slack.installationId ||
slack.defaultBindingId !== manifest.slack.defaultBindingId ||
!Array.isArray(channelIds) ||
channelIds.length === 0 ||
!defaultBinding ||
!Array.isArray(slack.memberAllowlist) ||
slack.memberAllowlist.length === 0 ||
runtimeService.principalId !== manifest.service.principalId ||
runtimeService.policyHash !== manifest.service.policyHash ||
!Number.isSafeInteger(runtimeService.credentialGeneration) ||
runtimeService.credentialGeneration < 1 ||
!/^[a-f0-9]{16}$/.test(runtimeService.credentialFingerprint ?? "") ||
!Number.isSafeInteger(credentialIdentity?.generation) ||
credentialIdentity.generation < 1 ||
!/^[a-f0-9]{16}$/.test(credentialIdentity?.fingerprint ?? "") ||
credentialIdentity.generation !== runtimeService.credentialGeneration ||
credentialIdentity.fingerprint !== runtimeService.credentialFingerprint ||
(activeClaim.secretEnvelopes?.slackBot &&
(activeClaim.secretEnvelopes.slackBot.installationId !==
slack.installationId ||
activeClaim.secretEnvelopes.slackBot.generation !==
slack.generation ||
activeClaim.secretEnvelopes.slackBot.fingerprint !==
slack.credentialFingerprint))
)
return { ok: false, code: "plan04_runtime_contract_missing" };
const slackHashes = slack.hashes;
if (
!exactObject(slackHashes, [
"installation",
"app",
"team",
"bot",
"channels",
"defaultChannel",
"memberAllowlist",
]) ||
Object.values(slackHashes).some((value) => !SHA256.test(value)) ||
!SHA256.test(pinned.providerFingerprint ?? "")
) {
return { ok: false, code: "pinned_runtime_identity_invalid" };
}
if (
createHash("sha256").update(stableJson(channelIds)).digest("hex") !==
slackHashes.channels ||
createHash("sha256").update(defaultBinding.channelId).digest("hex") !==
slackHashes.defaultChannel ||
createHash("sha256")
.update(stableJson(slack.memberAllowlist))
.digest("hex") !== slackHashes.memberAllowlist ||
createHash("sha256").update(slack.appId).digest("hex") !==
slackHashes.app ||
createHash("sha256").update(slack.teamId).digest("hex") !==
slackHashes.team ||
createHash("sha256").update(slack.botUserId).digest("hex") !==
slackHashes.bot ||
canonicalHostWorkerDigest({
appId: slack.appId,
botUserId: slack.botUserId,
generation: slack.generation,
installationId: slack.installationId,
scopes: slack.scopes,
selectedBindings: slack.selectedBindings,
teamId: slack.teamId,
}) !== slackHashes.installation
)
return { ok: false, code: "pinned_runtime_channel_identity_invalid" };
if (
typeof pinned.providerReference !== "string" ||
typeof pinned.xappReference !== "string" ||
!/^[a-f0-9]{16}$/.test(pinned.xappFingerprint ?? "") ||
!/^[a-f0-9]{16}$/.test(slack.credentialFingerprint ?? "")
)
return { ok: false, code: "pinned_runtime_secret_reference_invalid" };
return {
ok: true,
desired: {
workspaceId: operation.workspaceId,
agentId: operation.agentId,
hostId: config.hostId,
workerId: config.workerId,
installationId: manifest.slack.installationId,
slackGeneration: slack.generation,
fence: operation.fence,
revisionId: operation.targetRevisionId,
revisionSequence: operation.lifecycleGeneration,
hermesCli: pinned.hermesCli,
hermesVersion: pinned.hermesVersion,
installerPackage: pinned.installerPackage,
mcpPackage: pinned.mcpPackage,
workspaceLockId: operation.workspaceId,
toolInclude: [...policy.toolInclude].sort(),
policyHash: manifest.service.policyHash,
slackManifestHash: slackHashes.installation,
slackAppHash: slackHashes.app,
slackTeamHash: slackHashes.team,
slackBotHash: slackHashes.bot,
slackChannelHash: slackHashes.channels,
slackDefaultChannelHash: slackHashes.defaultChannel,
slackMemberAllowlistHash: slackHashes.memberAllowlist,
slackChannelIds: [...channelIds],
slackDefaultChannelId: defaultBinding.channelId,
slackMemberAllowlist: [...slack.memberAllowlist],
soul,
soulHash: createHash("sha256").update(soul).digest("hex"),
skill,
skillsHash: createHash("sha256").update(skill).digest("hex"),
providerReference: pinned.providerReference,
providerFingerprint: pinned.providerFingerprint,
serviceCredentialReference: `secret://agent/service/g${credentialIdentity.generation}`,
serviceCredentialFingerprint: credentialIdentity.fingerprint,
serviceCredentialGeneration: credentialIdentity.generation,
xappReference: pinned.xappReference,
xappFingerprint: pinned.xappFingerprint,
xoxbReference: `secret://slack/install/${slack.installationId}/g${slack.generation}`,
xoxbCiphertextFingerprint: slack.credentialFingerprint,
},
};
} catch {
return { ok: false, code: "claim_profile_compile_failed" };
}
}
function confinedRuntimeStatePath(config, activeClaim) {
const stateRoot = realpathSync(config.stateRoot);
const runtimeRoot = join(stateRoot, "agent-runtime");
if (!existsSync(runtimeRoot))
mkdirSync(runtimeRoot, { recursive: true, mode: 0o700 });
const realRuntimeRoot = realpathSync(runtimeRoot);
const name = `${activeClaim.operation.workspaceId}-${activeClaim.operation.agentId}.json`;
const pathValue = join(realRuntimeRoot, name);
if (
dirname(pathValue) !== realRuntimeRoot ||
!SAFE_ID.test(activeClaim.operation.workspaceId) ||
!SAFE_ID.test(activeClaim.operation.agentId)
) {
throw new Error("runtime state confinement failed");
}
return pathValue;
}
function readRuntimeState(config, activeClaim) {
try {
const pathValue = confinedRuntimeStatePath(config, activeClaim);
if (!existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isFile() ||
(link.mode & 0o777) !== 0o600
)
return null;
return JSON.parse(readFileSync(pathValue, "utf8"));
} catch {
return null;
}
}
function persistRuntimeState(config, activeClaim, state) {
atomicPrivateJson(confinedRuntimeStatePath(config, activeClaim), state);
}
function serviceCredentialFor(desired, secret) {
return {
secret,
fingerprint: desired.serviceCredentialFingerprint,
generation: desired.serviceCredentialGeneration,
binding: {
workspaceId: desired.workspaceId,
agentId: desired.agentId,
installationId: desired.installationId,
generation: desired.serviceCredentialGeneration,
hostId: desired.hostId,
workerId: desired.workerId,
fence: desired.fence,
servicePurpose: "mcp-service",
},
};
}
function runtimeTuple(desired, observation, operation) {
const tuple = independentlyObservedRuntimeTuple(observation, "ON");
if (
tuple.revisionId !== desired.revisionId ||
tuple.revisionSequence !== desired.revisionSequence
)
throw new Error("initial runtime tuple revision rejected");
return tuple;
}
function provisionedRuntimeTuple(desired, outcome) {
const observation = outcome?.observation;
const computed = computeAgentProfileDigest(desired);
if (
!computed.ok ||
outcome?.status !== "PROVISIONED" ||
observation?.process !== null ||
observation?.revisionId !== desired.revisionId ||
observation?.revisionSequence !== desired.revisionSequence ||
observation?.hashes?.config !== computed.fileHashes["config.yaml"] ||
observation?.hashes?.mcp !== computed.fileHashes["sellable/mcp.json"] ||
observation?.hashes?.content !== computed.profileDigest ||
observation?.hashes?.nonSoulContent !== computed.nonSoulContentHash ||
observation?.hashes?.policy !== desired.policyHash ||
observation?.hashes?.skills !== desired.skillsHash ||
observation?.hashes?.provider !== desired.providerFingerprint ||
!SHA256.test(observation?.hashes?.package ?? "") ||
outcome?.receipt?.profileDigest !== computed.profileDigest
)
throw new Error("provisioned runtime tuple rejected");
return {
revisionId: desired.revisionId,
revisionSequence: desired.revisionSequence,
lifecycle: "OFF",
packageHash: observation.hashes.package,
configHash: computed.fileHashes["config.yaml"],
mcpHash: computed.fileHashes["sellable/mcp.json"],
policyHash: desired.policyHash,
toolsHash: canonicalHostWorkerDigest([...desired.toolInclude].sort()),
skillsHash: desired.skillsHash,
providerFingerprint: desired.providerFingerprint,
serviceCredentialGeneration: desired.serviceCredentialGeneration,
slackManifestHash: desired.slackManifestHash,
slackAppHash: desired.slackAppHash,
slackTeamHash: desired.slackTeamHash,
slackBotHash: desired.slackBotHash,
slackChannelHash: desired.slackChannelHash,
slackDefaultChannelHash: desired.slackDefaultChannelHash,
slackMemberAllowlistHash: desired.slackMemberAllowlistHash,
slackChannelIds: [...desired.slackChannelIds],
slackDefaultChannelId: desired.slackDefaultChannelId,
slackMemberAllowlist: [...desired.slackMemberAllowlist],
slackGeneration: desired.slackGeneration,
contentHash: computed.profileDigest,
nonSoulContentHash: computed.nonSoulContentHash,
soulHash: desired.soulHash,
processHash: null,
};
}
function approvedRuntimeTuple(desired, operation, currentState) {
const computed = computeAgentProfileDigest(desired);
if (!computed.ok) throw new Error("approved profile digest rejected");
const sameRevision =
currentState.observedTuple?.revisionId === desired.revisionId &&
currentState.observedTuple?.revisionSequence === desired.revisionSequence;
const contentHash = sameRevision
? currentState.observedTuple?.contentHash
: computed.profileDigest;
if (
!SHA256.test(contentHash ?? "") ||
!SHA256.test(computed.nonSoulContentHash ?? "")
)
throw new Error("approved content digest rejected");
return {
revisionId: desired.revisionId,
revisionSequence: desired.revisionSequence,
lifecycle: currentState.observedLifecycle,
packageHash: currentState.observedTuple.packageHash,
configHash: computed.fileHashes["config.yaml"],
mcpHash: computed.fileHashes["sellable/mcp.json"],
policyHash: desired.policyHash,
toolsHash: canonicalHostWorkerDigest(desired.toolInclude),
skillsHash: desired.skillsHash,
providerFingerprint: desired.providerFingerprint,
serviceCredentialGeneration: desired.serviceCredentialGeneration,
slackManifestHash: desired.slackManifestHash,
slackAppHash: desired.slackAppHash,
slackTeamHash: desired.slackTeamHash,
slackBotHash: desired.slackBotHash,
slackChannelHash: desired.slackChannelHash,
slackDefaultChannelHash: desired.slackDefaultChannelHash,
slackMemberAllowlistHash: desired.slackMemberAllowlistHash,
slackChannelIds: [...desired.slackChannelIds],
slackDefaultChannelId: desired.slackDefaultChannelId,
slackMemberAllowlist: [...desired.slackMemberAllowlist],
slackGeneration: desired.slackGeneration,
contentHash,
nonSoulContentHash: computed.nonSoulContentHash,
soulHash: desired.soulHash,
processHash: currentState.observedTuple.processHash,
};
}
function tupleRuntimeHashes(tuple) {
return {
package: tuple.packageHash,
config: tuple.configHash,
content: tuple.contentHash,
process: tuple.processHash ?? null,
};
}
function independentlyObservedRuntimeTuple(observed, lifecycle) {
if (
!observed ||
!Number.isSafeInteger(observed.revisionSequence) ||
observed.revisionSequence < 1 ||
!["ON", "OFF", "ARCHIVED"].includes(lifecycle) ||
!Array.isArray(observed.tools) ||
!Array.isArray(observed.slack?.channelIds) ||
observed.slack.channelIds.length < 1 ||
observed.slack.channelIds.length > 100 ||
observed.slack.channelIds.some(
(value) => !/^C[A-Z0-9]{8,20}$/.test(value)
) ||
new Set(observed.slack.channelIds).size !==
observed.slack.channelIds.length ||
!/^C[A-Z0-9]{8,20}$/.test(observed.slack?.defaultChannelId ?? "") ||
!Array.isArray(observed.slack?.memberIds) ||
observed.slack.memberIds.length < 1 ||
observed.slack.memberIds.length > 1_000 ||
observed.slack.memberIds.some(
(value) => !/^[UW][A-Z0-9]{8,20}$/.test(value)
) ||
new Set(observed.slack.memberIds).size !== observed.slack.memberIds.length
)
throw new Error("independent runtime tuple rejected");
return {
revisionId: observed.revisionId,
revisionSequence: observed.revisionSequence,
lifecycle,
packageHash: observed.hashes.package,
configHash: observed.hashes.config,
mcpHash: observed.hashes.mcp,
policyHash: observed.hashes.policy,
toolsHash: canonicalHostWorkerDigest([...observed.tools].sort()),
skillsHash: observed.hashes.skills,
providerFingerprint: observed.hashes.provider,
serviceCredentialGeneration: observed.serviceCredential.generation,
slackManifestHash: observed.hashes.slackManifest,
slackAppHash: observed.slack.app,
slackTeamHash: observed.slack.team,
slackBotHash: observed.slack.bot,
slackChannelHash: observed.slack.channels,
slackDefaultChannelHash: observed.slack.defaultChannel,
slackMemberAllowlistHash: observed.slack.memberAllowlist,
slackChannelIds: [...observed.slack.channelIds],
slackDefaultChannelId: observed.slack.defaultChannelId,
slackMemberAllowlist: [...observed.slack.memberIds],
slackGeneration: observed.slack.generation,
contentHash: observed.hashes.content,
nonSoulContentHash: observed.hashes.nonSoulContent,
soulHash: observed.hashes.soul,
processHash: canonicalHostWorkerDigest(observed.process),
};
}
function initialRuntimeState(activeClaim, desired, outcome) {
const tuple =
outcome.status === "PROVISIONED"
? provisionedRuntimeTuple(desired, outcome)
: runtimeTuple(desired, outcome.observation, activeClaim.operation);
return {
desiredRevisionId: desired.revisionId,
desiredRevisionSequence: activeClaim.operation.lifecycleGeneration,
observedRevisionId: desired.revisionId,
requestedLifecycle: outcome.status === "PROVISIONED" ? "OFF" : "ON",
observedLifecycle: outcome.status === "PROVISIONED" ? "OFF" : "ON",
acceptedFence: activeClaim.operation.fence,
credentialGeneration: desired.serviceCredentialGeneration,
routeFenced: false,
outputFenced: false,
dispatchEnabled: outcome.status !== "PROVISIONED",
secretsPresent: true,
profileDigest: outcome.receipt.profileDigest,
archivedCredentialGeneration: null,
archivedProfileDigest: null,
receipts: {},
desiredTuple: tuple,
observedTuple: tuple,
previousKnownGoodTuple: tuple,
runtimeHashes: {
package: outcome.observation.hashes.package,
config: outcome.observation.hashes.config,
content: outcome.observation.hashes.content,
process: outcome.observation.process
? canonicalHostWorkerDigest(outcome.observation.process)
: null,
},
};
}
function lifecycleOperation(activeClaim, runtimeState, desired) {
return {
id: activeClaim.operation.id,
eventId: activeClaim.operation.id,
action: activeClaim.operation.action,
fence: activeClaim.operation.fence,
targetRevisionId: activeClaim.operation.targetRevisionId,
targetRevisionSequence:
desired?.revisionSequence ??
runtimeState.observedTuple?.revisionSequence ??
runtimeState.desiredRevisionSequence,
credentialGeneration:
desired?.serviceCredentialGeneration ?? runtimeState.credentialGeneration,
profileDigest: desired?.profileDigest ?? runtimeState.profileDigest,
};
}
function localCompletionReceipt({
activeClaim,
config,
outcome,
effectId,
secretConsumed,
}) {
const identity = operationIdentity(activeClaim, config);
const success = outcome?.ok === true;
const redeliverable =
!success && secretConsumed && outcome?.redeliverable === true;
const uncertain =
!success &&
!redeliverable &&
(secretConsumed || outcome?.status === "UNCERTAIN");
const observation = outcome?.observation ?? null;
const body = {
...identity,
status: success
? "SUCCEEDED"
: redeliverable || uncertain
? "UNCERTAIN"
: "FAILED",
secretDisposition: success
? secretConsumed
? "INSTALLED"
: "NOT_PRESENT"
: redeliverable
? "REDELIVERABLE"
: secretConsumed
? "UNCERTAIN"
: "NOT_PRESENT",
observedLifecycle: success
? (outcome.observedLifecycle ?? "ON")
: "DEGRADED",
observedRevisionId: success ? activeClaim.operation.targetRevisionId : null,
signerGeneration: config.signerGeneration,
runtimeHashes: {
package:
observation?.hashes?.package ?? outcome?.runtimeHashes?.package ?? null,
config:
observation?.hashes?.config ?? outcome?.runtimeHashes?.config ?? null,
content:
observation?.hashes?.content ?? outcome?.runtimeHashes?.content ?? null,
process: observation?.process
? canonicalHostWorkerDigest(observation.process)
: (outcome?.runtimeHashes?.process ?? null),
},
conditions: [
{
code: success
? "READY"
: redeliverable
? "DELIVERY_ROLLED_BACK"
: uncertain
? "RUNTIME_UNCERTAIN"
: "PROVISIONING_FAILED",
status:
success || redeliverable ? "TRUE" : uncertain ? "UNKNOWN" : "FALSE",
},
],
errorClass: success
? "NONE"
: (outcome?.code ?? outcome?.status ?? "HOST_RUNTIME"),
auditIds: [effectId],
};
return { ...body, signedDigest: canonicalHostWorkerDigest(body) };
}
function readBoundSecret(pathValue) {
const root = privateRootForAdapter(dirname(pathValue));
if (!root || dirname(resolve(pathValue)) !== root)
throw new Error("secret source confinement failed");
const link = lstatSync(pathValue);
if (link.isSymbolicLink() || !link.isFile() || (link.mode & 0o077) !== 0) {
throw new Error("secret source mode rejected");
}
return readFileSync(pathValue, "utf8").trim();
}
async function invokePinnedRuntimeHelper(config, request) {
const requestRoot = realPrivateDirectory(config.helperRequestRoot);
if (!requestRoot) throw new Error("runtime helper request root rejected");
const helper =
config.runtimeHelperPath ?? "/usr/local/bin/sellable-agent-runtime-helper";
if (helper !== "/usr/local/bin/sellable-agent-runtime-helper")
throw new Error("runtime helper pin rejected");
const pathValue = join(requestRoot, `helper-${randomUUID()}.json`);
atomicPrivateJson(pathValue, request);
try {
const result = await runBoundedChildProcess({
command: "/usr/bin/sudo",
args: ["-n", helper, "--request", pathValue],
env: { PATH: "/usr/local/bin:/usr/bin:/bin" },
shell: false,
timeoutMs: 30_000,
maxOutputBytes: 32 * 1024,
});
if (
result.exitCode !== 0 ||
result.timedOut ||
result.outputLimitExceeded ||
SECRET_PATTERN.test(result.stdout) ||
SECRET_PATTERN.test(result.stderr)
)
throw new Error("runtime helper invocation failed");
const lines = result.stdout.trim().split(/\r?\n/).filter(Boolean);
if (lines.length !== 1) throw new Error("runtime helper receipt rejected");
const receipt = JSON.parse(lines[0]);
if (!receipt?.ok || SECRET_PATTERN.test(JSON.stringify(receipt)))
throw new Error("runtime helper receipt rejected");
return receipt;
} finally {
removeRequest(pathValue, requestRoot);
}
}
export function createLocalPinnedActionPorts(config, dependencies = {}) {
const ownershipReceipts = new Map();
let containmentReceipt = null;
let context = null;
let refreshPrepared = null;
let refreshRollbackExpected = null;
let refreshClassificationObservation = null;
if (
dependencies &&
(typeof dependencies !== "object" ||
Array.isArray(dependencies) ||
Object.keys(dependencies).some(
(key) => !["invokeRuntimeHelper", "fetchImpl"].includes(key)
) ||
(dependencies.invokeRuntimeHelper &&
typeof dependencies.invokeRuntimeHelper !== "function") ||
(dependencies.fetchImpl && typeof dependencies.fetchImpl !== "function"))
)
throw new Error("local action port dependencies rejected");
const helper = (request) =>
dependencies.invokeRuntimeHelper
? dependencies.invokeRuntimeHelper(request)
: invokePinnedRuntimeHelper(config, request);
const helperIdentity = () => ({
profileId: context.profileId,
operationId: context.activeClaim.operation.id,
fence: context.activeClaim.operation.fence,
});
const controlRuntime = async (control) => {
if (control !== "DOWN")
await helper({ action: "VERIFY_HERMES_BRIDGE", ...helperIdentity() });
return helper({ action: "CONTROL_RUNTIME", ...helperIdentity(), control });
};
const observeRuntimeLifecycle = (lifecycle) =>
helper({
action: "OBSERVE_RUNTIME_LIFECYCLE",
...helperIdentity(),
lifecycle,
});
const readDurableLifecycleEvidence = (name) => {
const stateRoot = realpathSync(config.stateRoot);
const pathValue = join(stateRoot, name);
if (dirname(pathValue) !== stateRoot)
throw new Error("lifecycle evidence path rejected");
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isFile() ||
(link.mode & 0o777) !== 0o600 ||
link.uid !== config.workerUid ||
link.gid !== config.workerGid
)
throw new Error("lifecycle evidence file rejected");
return JSON.parse(readFileSync(pathValue, "utf8"));
};
const ports = {
bind(value) {
context = value;
refreshClassificationObservation = null;
},
materializer: {
promotionJournal: createWorkerPromotionJournal(config),
hostAppSecret: {
async resolveHostSecret(request) {
const contract = config.profileRuntimeContract;
if (
request.reference !== contract?.xappReference ||
request.expectedFingerprint !== contract?.xappFingerprint
)
throw new Error("host app secret binding rejected");
const secret = readBoundSecret(contract.xappSecretFile);
return {
secret,
fingerprint: createHash("sha256")
.update(secret)
.digest("hex")
.slice(0, 16),
binding: {
workspaceId: request.workspaceId,
agentId: request.agentId,
installationId: request.installationId,
generation: request.generation,
hostId: request.hostId,
workerId: request.workerId,
fence: request.fence,
servicePurpose: request.servicePurpose,
},
};
},
},
workspaceBotSecret: {
async decryptWorkspaceSecret(request) {
const secret = context?.payload?.slackBotCredential;
if (typeof secret !== "string" || !secret.startsWith("xoxb-"))
throw new Error("slack bot request secret missing");
return {
secret,
fingerprint: createHash("sha256")
.update(secret)
.digest("hex")
.slice(0, 16),
generation: request.generation,
binding: {
workspaceId: request.workspaceId,
agentId: request.agentId,
installationId: request.installationId,
generation: request.generation,
hostId: request.hostId,
workerId: request.workerId,
fence: request.fence,
servicePurpose: request.servicePurpose,
},
};
},
},
credential: {
async install(request) {
if (!context?.requestFile)
throw new Error("credential source request missing");
const receipt = await helper({
action: "INSTALL_MCP_CREDENTIAL",
...helperIdentity(),
sourceRequestFile: context.requestFile,
generation: request.serviceCredential.generation,
fingerprint: request.serviceCredential.fingerprint,
});
return receipt;
},
async cleanup(request) {
return helper({
action: "CLEAN_PROFILE_SECRETS",
...helperIdentity(),
profileId: request.profileId,
});
},
},
gateway: {
async start(request) {
if (
request?.profileId !== context.profileId ||
!SHA256.test(request?.evidence?.profileDigest ?? "")
)
throw new Error("runtime service environment binding rejected");
await helper({
action: "INSTALL_RUNTIME_SERVICE_ENV",
...helperIdentity(),
revisionId: request.evidence.revisionId,
profileDigest: request.evidence.profileDigest,
});
await helper({
action: "INSTALL_PROVIDER_CREDENTIAL",
...helperIdentity(),
fingerprint: context.desired.providerFingerprint,
});
await helper({
action: "INSTALL_HERMES_BRIDGE",
...helperIdentity(),
});
await controlRuntime("UP");
},
async stop() {
await controlRuntime("DOWN");
},
async observe() {
const receipt = await helper({
action: "OBSERVE_RUNTIME",
...helperIdentity(),
});
const {
profileDigest: _profileDigest,
tools: _tools,
revisionSequence: _revisionSequence,
...observation
} = receipt.observation;
return observation;
},
},
containment: {
async probe(request) {
containmentReceipt = await helper({
action: "PROBE_CONTAINMENT",
...helperIdentity(),
profileRoot: request.profileRoot,
revisionId: context.desired.revisionId,
});
return containmentReceipt;
},
},
mcp: {
async discoverTools() {
if (!containmentReceipt?.ok)
throw new Error("runtime MCP proof missing");
return containmentReceipt.tools;
},
async safeRead({ workspaceId }) {
return containmentReceipt?.safeRead === true &&
containmentReceipt.workspaceId === workspaceId
? { ok: true, workspaceId }
: { ok: false, code: "runtime_mcp_probe_missing" };
},
},
ownership: {
async apply(request) {
const receipt = await helper({
action: "CHOWN_PROFILE",
...helperIdentity(),
profileRoot: request.profileRoot,
revisionId: request.revisionId,
profileDigest: request.profileDigest,
});
ownershipReceipts.set(resolve(request.profileRoot), receipt);
return receipt;
},
async observe(request) {
const receipt = ownershipReceipts.get(resolve(request.profileRoot));
return receipt
? { ok: true, entries: receipt.entries }
: { ok: false, entries: [] };
},
async remove(request) {
ownershipReceipts.delete(resolve(request.profileRoot));
return helper({
action: "REMOVE_PROFILE",
...helperIdentity(),
slot: request.slot,
revisionId: request.revisionId,
});
},
},
},
refresh: {},
lifecycle: {},
};
const restart = () => controlRuntime("RESTART");
const rawRuntimeObservation = async ({ drift = false } = {}) => {
const observed = (
await helper({
action: drift ? "OBSERVE_RUNTIME_DRIFT" : "OBSERVE_RUNTIME",
...helperIdentity(),
})
).observation;
if (
observed?.profileId !== context.profileId ||
observed.workspaceId !== context.desired.workspaceId ||
observed.agentId !== context.desired.agentId ||
!SAFE_ID.test(observed.revisionId ?? "") ||
!Number.isSafeInteger(observed.revisionSequence) ||
!Array.isArray(observed.tools) ||
observed.tools.length === 0 ||
!observed.process?.ready ||
!Number.isSafeInteger(observed.process.pid) ||
observed.process.pid < 2 ||
!/^[1-9][0-9]{0,31}$/.test(observed.process.startTicks ?? "") ||
observed.process.serviceUser !== "sellable-agent-runtime" ||
observed.process.uid !== config.runtimeUid
)
throw new Error("runtime observation identity rejected");
return attachSkillsProofObservation(
observed,
join(realpathSync(config.profilesRoot), context.profileId)
);
};
const ensureRefreshTarget = async () => {
if (refreshPrepared) return;
const recovery = await recoverInterruptedProfilePromotion({
desired: context.desired,
operationId: context.activeClaim.operation.id,
effectId: context.effectId,
profilesRoot: config.profilesRoot,
runtimeSecretsRoot: config.runtimeSecretsRoot,
runtimeIdentity: {
user: "sellable-agent-runtime",
uid: config.runtimeUid,
gid: config.runtimeGid,
},
ports: ports.materializer,
});
if (!recovery.ok) throw new Error("interrupted refresh recovery unproven");
const prior =
refreshClassificationObservation ?? (await rawRuntimeObservation());
refreshClassificationObservation = null;
const {
profileDigest: _profileDigest,
tools: _tools,
...priorMaterializerObservation
} = prior;
const result = await materializeAgentProfile({
desired: context.desired,
operationId: context.activeClaim.operation.id,
effectId: context.effectId,
profilesRoot: config.profilesRoot,
runtimeSecretsRoot: config.runtimeSecretsRoot,
mcpCredentialRoot: config.runtimeMcpSecretsRoot,
runtimeIdentity: {
user: "sellable-agent-runtime",
uid: config.runtimeUid,
gid: config.runtimeGid,
},
reuseInstalledSecrets: prior,
priorKnownGoodObservation: priorMaterializerObservation,
retainPriorGood: true,
prepareOnly: true,
ports: ports.materializer,
});
if (
!result.ok ||
result.status !== "PREPARED" ||
result.receipt?.revisionId !== context.desired.revisionId ||
!SHA256.test(result.receipt?.profileDigest ?? "")
)
throw new Error(
`approved refresh profile rejected ${result.status ?? "unknown"}:${result.code ?? "none"}`
);
refreshPrepared = {
prior,
profileId: context.profileId,
profileRoot: join(realpathSync(config.profilesRoot), context.profileId),
backupRoot: join(
realpathSync(config.profilesRoot),
`${context.profileId}.rollback-prior-good`
),
};
await helper({
action: "INSTALL_RUNTIME_SERVICE_ENV",
...helperIdentity(),
revisionId: result.receipt.revisionId,
profileDigest: result.receipt.profileDigest,
});
await helper({
action: "INSTALL_PROVIDER_CREDENTIAL",
...helperIdentity(),
fingerprint: context.desired.providerFingerprint,
});
await helper({ action: "INSTALL_HERMES_BRIDGE", ...helperIdentity() });
};
const refreshThen = (effect) => async (input) => {
await ensureRefreshTarget();
return effect(input);
};
Object.assign(ports.refresh, {
reloadMcp: refreshThen(restart),
reloadSkills: refreshThen(restart),
reloadEnvironmentOrRestart: refreshThen(restart),
restartGateway: refreshThen(restart),
restartProfileSession: refreshThen(restart),
reprovisionProfile: refreshThen(restart),
async observe({ desired, target, classification = false }) {
const observed = await rawRuntimeObservation({ drift: classification });
const expected = target ?? desired ?? refreshRollbackExpected;
if (!expected || observed.revisionId !== expected.revisionId) {
throw new Error("observed runtime revision rejected");
}
const tuple = independentlyObservedRuntimeTuple(
observed,
expected.lifecycle
);
if (classification) refreshClassificationObservation = observed;
if (refreshPrepared) {
const containment = await helper({
action: "PROBE_CONTAINMENT",
...helperIdentity(),
profileRoot: refreshPrepared.profileRoot,
revisionId: observed.revisionId,
});
if (
!containment?.ok ||
containment.safeRead !== true ||
containment.workspaceId !== observed.workspaceId ||
stableJson(containment.tools) !== stableJson(observed.tools) ||
[
"siblingReadDenied",
"workerReadDenied",
"adminReadDenied",
"providerBytesDenied",
"hostMountDenied",
"dockerDenied",
"unexpectedToolDenied",
"wrongWorkspaceDispatchDenied",
].some((key) => containment[key] !== true)
)
throw new Error("refreshed runtime containment proof rejected");
}
if (
refreshPrepared &&
stableJson(projectRuntimeDriftTuple(tuple)) ===
stableJson(projectRuntimeDriftTuple(expected))
) {
const prepared = refreshPrepared;
const committed = commitRetainedProfilePromotion({
profilesRoot: config.profilesRoot,
desired: context.desired,
operationId: context.activeClaim.operation.id,
effectId: context.effectId,
ports: ports.materializer,
targetObservation: observed,
});
if (!committed.ok) throw new Error("refresh promotion commit unproven");
refreshPrepared = null;
try {
if (existsSync(prepared.backupRoot))
await ports.materializer.ownership.remove({
profileId: prepared.profileId,
profileRoot: prepared.backupRoot,
slot: "BACKUP",
revisionId: context.desired.revisionId,
fence: context.desired.fence,
});
const finalized = finalizeRetainedProfilePromotion({
profilesRoot: config.profilesRoot,
desired: context.desired,
operationId: context.activeClaim.operation.id,
effectId: context.effectId,
ports: ports.materializer,
});
if (!finalized.ok)
throw new Error("refresh promotion finalize unproven");
} catch {
// The durable COMMITTED marker makes backup retirement restart-convergent.
}
}
if (
refreshRollbackExpected &&
stableJson(projectRuntimeDriftTuple(tuple)) ===
stableJson(projectRuntimeDriftTuple(refreshRollbackExpected))
)
refreshRollbackExpected = null;
return tuple;
},
async rollback() {
if (!refreshPrepared) throw new Error("prepared refresh rollback absent");
await controlRuntime("DOWN");
await ports.materializer.ownership.remove({
profileId: refreshPrepared.profileId,
profileRoot: refreshPrepared.profileRoot,
slot: "ACTIVE",
revisionId: context.desired.revisionId,
fence: context.desired.fence,
});
renameSync(refreshPrepared.backupRoot, refreshPrepared.profileRoot);
const manifest = JSON.parse(
readFileSync(
join(refreshPrepared.profileRoot, "agent-profile.json"),
"utf8"
)
);
await ports.materializer.gateway.start({
profileId: refreshPrepared.profileId,
profileRoot: refreshPrepared.profileRoot,
identity: {
user: "sellable-agent-runtime",
uid: config.runtimeUid,
gid: config.runtimeGid,
},
evidence: {
revisionId: manifest.revisionId,
profileDigest: manifest.profileDigest,
xappFingerprint: refreshPrepared.prior.slack.xappFingerprint,
xoxbFingerprint: refreshPrepared.prior.slack.xoxbFingerprint,
serviceCredentialFingerprint:
refreshPrepared.prior.serviceCredential.fingerprint,
serviceCredentialGeneration:
refreshPrepared.prior.serviceCredential.generation,
},
});
refreshRollbackExpected = independentlyObservedRuntimeTuple(
refreshPrepared.prior,
"ON"
);
refreshPrepared = null;
},
});
Object.assign(ports.lifecycle, {
async fenceDispatch() {
// Lifecycle authority is the service itself. Stopping it closes dispatch
// without introducing a second file-backed switch that can strand an
// otherwise healthy runtime.
await controlRuntime("DOWN");
},
async fenceRouteOutput() {
await controlRuntime("DOWN");
},
async drain() {
await controlRuntime("DOWN");
const observed = { drained: true, remaining: 0 };
atomicPrivateJson(
join(
realpathSync(config.stateRoot),
`drain-${context.activeClaim.operation.id}.json`
),
{
operationId: context.activeClaim.operation.id,
fence: context.activeClaim.operation.fence,
drained: true,
remaining: 0,
}
);
return observed;
},
async startGateway() {
await controlRuntime("UP");
await observeRuntimeLifecycle("ON");
},
async stopGateway() {
const lifecycle =
context.activeClaim.operation.action === "ARCHIVE"
? "ARCHIVING"
: "OFF";
await controlRuntime("DOWN");
await observeRuntimeLifecycle(lifecycle);
},
async proveNoDispatch() {
const lifecycle =
context.activeClaim.operation.action === "ARCHIVE" ? "ARCHIVED" : "OFF";
const observed = await observeRuntimeLifecycle(lifecycle);
return {
noDispatch: observed.process.ready === false,
};
},
async observeGateway(input) {
const lifecycle = input.rollback
? (input.lifecycle ?? input.observedLifecycle)
: context.activeClaim.operation.action === "ARCHIVE"
? "ARCHIVED"
: context.activeClaim.operation.action === "DISABLE_GATEWAY"
? "OFF"
: "ON";
const observed = await observeRuntimeLifecycle(lifecycle);
const result = {
lifecycle: observed.lifecycle,
revisionId: observed.revisionId,
credentialGeneration: observed.credentialGeneration,
profileDigest: observed.profileDigest,
secretsPresent: observed.secretsPresent,
process: observed.process,
runtimeObservation: observed.runtimeObservation,
};
if (lifecycle === "ON" && observed.runtimeObservation) {
result.runtimeTuple = independentlyObservedRuntimeTuple(
observed.runtimeObservation,
"ON"
);
}
return result;
},
async cleanSecrets() {
await helper({ action: "CLEAN_PROFILE_SECRETS", ...helperIdentity() });
},
async acknowledgeRevocation({ operation }) {
atomicPrivateJson(
join(realpathSync(config.stateRoot), `revocation-${operation.id}.json`),
{
acknowledged: true,
operationId: operation.id,
fence: operation.fence,
}
);
return { acknowledged: true };
},
async rehydrate({ desired, serviceCredential }) {
const result = await materializeAgentProfile({
desired,
operationId: context.activeClaim.operation.id,
effectId: context.effectId,
profilesRoot: config.profilesRoot,
runtimeSecretsRoot: config.runtimeSecretsRoot,
runtimeIdentity: {
user: "sellable-agent-runtime",
uid: config.runtimeUid,
gid: config.runtimeGid,
},
serviceCredential,
ports: ports.materializer,
});
if (!result.ok) throw new Error("rehydrate rejected");
return {
runtimeTuple: independentlyObservedRuntimeTuple(
result.observation,
"ON"
),
};
},
async rollback({ priorState }) {
if (priorState.observedLifecycle === "ON") await controlRuntime("UP");
else await controlRuntime("DOWN");
await observeRuntimeLifecycle(priorState.observedLifecycle);
},
async reconcileArchive({ operation }) {
try {
const evidence = {};
const confirmedSteps = [];
// Older progress receipts name this step FENCE_ROUTE_OUTPUT. Its
// concrete proof is now the stopped service, not a gates.json file.
// Preserve the step identity so an in-flight archive can resume across
// this runtime upgrade.
let stopped;
try {
stopped = await observeRuntimeLifecycle("ARCHIVING");
} catch {
try {
stopped = await observeRuntimeLifecycle("ARCHIVED");
} catch {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest({ service: "not_stopped" })}`,
confirmedSteps,
};
}
}
evidence.service = {
lifecycle: stopped.lifecycle,
processReady: stopped.process?.ready,
};
if (stopped.process?.ready !== false) {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest(evidence)}`,
confirmedSteps,
};
}
confirmedSteps.push("FENCE_ROUTE_OUTPUT");
let drain;
try {
drain = readDurableLifecycleEvidence(`drain-${operation.id}.json`);
} catch {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest(evidence)}`,
confirmedSteps,
};
}
if (
drain.operationId !== operation.id ||
drain.fence !== operation.fence ||
!drain.drained ||
drain.remaining !== 0
)
throw new Error("archive drain evidence rejected");
evidence.drain = drain;
confirmedSteps.push("DRAIN");
let observed;
try {
observed = await observeRuntimeLifecycle("ARCHIVING");
} catch {
try {
observed = await observeRuntimeLifecycle("ARCHIVED");
} catch {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest(evidence)}`,
confirmedSteps,
};
}
}
evidence.stopped = observed;
confirmedSteps.push("STOP_GATEWAY");
if (
observed.lifecycle !== "ARCHIVED" ||
observed.secretsPresent !== false
) {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest(evidence)}`,
confirmedSteps,
};
}
confirmedSteps.push("CLEAN_SECRETS");
let revoke;
try {
revoke = readDurableLifecycleEvidence(
`revocation-${operation.id}.json`
);
} catch {
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest(evidence)}`,
confirmedSteps,
};
}
if (
revoke.operationId !== operation.id ||
revoke.fence !== operation.fence ||
!revoke.acknowledged
)
throw new Error("archive revocation evidence rejected");
evidence.revoke = revoke;
confirmedSteps.push("ACK_REVOKE", "OBSERVE_ARCHIVED");
return {
ok: true,
observationId: `archive_${canonicalHostWorkerDigest({ operation, evidence })}`,
confirmedSteps,
};
} catch {
return { ok: false };
}
},
async persistProgress({ state }) {
persistRuntimeState(config, context.activeClaim, state);
return { persisted: true };
},
});
return ports;
}
export function createPinnedHostWorkerAdapter(config, suppliedPorts) {
const actionPorts = suppliedPorts ?? createLocalPinnedActionPorts(config);
return {
async requiresSecret({ activeClaim }) {
return requiredSecretSlots(activeClaim);
},
async reconcile({ activeClaim, effectId }) {
const receiptPath = confinedReceiptPath(config, effectId);
if (existsSync(receiptPath)) return { status: "RECEIPT", effectId };
const profileId = deriveContainedProfileId(
activeClaim.operation.workspaceId,
activeClaim.operation.agentId,
config.hostId
);
const profilesRoot = privateRootForAdapter(config.profilesRoot);
return profilesRoot &&
existsSync(join(profilesRoot, profileId, "agent-profile.json"))
? { status: "PROMOTED", effectId }
: { status: "ABSENT", effectId };
},
async apply({ activeClaim, requestFile, effectId }) {
const secretConsumed = typeof requestFile === "string";
let outcome;
try {
const action = activeClaim.operation.action;
const compiled = compileClaimToProfileDesired(activeClaim, config);
if (!compiled.ok) {
outcome = {
ok: false,
status: "DESIRED_REJECTED",
code: compiled.code,
};
} else {
const desired = compiled.desired;
const payload = requestFile
? JSON.parse(readFileSync(requestFile, "utf8"))
: null;
if (
secretConsumed &&
(payload.operationId !== activeClaim.operation.id ||
payload.fence !== activeClaim.operation.fence)
) {
throw new Error("request binding invalid");
}
for (const slot of requiredSecretSlots(activeClaim)) {
const envelope = activeClaim.secretEnvelopes[slot];
const secretKey =
slot === "mcpService"
? "serviceCredential"
: "slackBotCredential";
const prefix = slot === "mcpService" ? "mcpService" : "slackBot";
const secret = payload?.[secretKey];
if (
!envelope ||
payload?.[`${prefix}EnvelopeId`] !== envelope.id ||
payload?.[`${prefix}Generation`] !== envelope.generation ||
typeof secret !== "string" ||
(slot === "mcpService"
? !secret.startsWith("sat_")
: !secret.startsWith("xoxb-")) ||
createHash("sha256").update(secret).digest("hex").slice(0, 16) !==
envelope.fingerprint
)
throw new Error("request binding invalid");
}
const materialize = (options = {}) =>
materializeAgentProfile({
desired,
operationId: activeClaim.operation.id,
effectId,
profilesRoot: config.profilesRoot,
runtimeSecretsRoot: config.runtimeSecretsRoot,
runtimeIdentity: {
user: "sellable-agent-runtime",
uid: config.runtimeUid,
gid: config.runtimeGid,
},
serviceCredential: serviceCredentialFor(
desired,
payload?.serviceCredential
),
ports: actionPorts.materializer,
...options,
});
const currentState = readRuntimeState(config, activeClaim);
actionPorts.bind?.({
activeClaim,
desired,
currentState,
profileId: deriveContainedProfileId(
desired.workspaceId,
desired.agentId,
desired.hostId
),
requestFile,
payload,
effectId,
});
if (action === "INSTANTIATE") {
outcome = await materialize({ provisionOnly: true });
if (!outcome.ok && secretConsumed) {
const profileId = deriveContainedProfileId(
desired.workspaceId,
desired.agentId,
desired.hostId
);
outcome = {
...outcome,
redeliverable:
!existsSync(join(config.runtimeSecretsRoot, profileId)) &&
!existsSync(join(config.runtimeMcpSecretsRoot, profileId)),
};
}
if (outcome.ok)
persistRuntimeState(
config,
activeClaim,
initialRuntimeState(activeClaim, desired, outcome)
);
} else if (action === "ROTATE_CREDENTIAL") {
if (
!currentState ||
desired.serviceCredentialGeneration <=
currentState.credentialGeneration
) {
outcome = {
ok: false,
status: "SUCCESSOR_REQUIRED",
code: "SUCCESSOR_REQUIRED",
};
} else {
outcome = await materialize();
if (outcome.ok)
persistRuntimeState(config, activeClaim, {
...initialRuntimeState(activeClaim, desired, outcome),
receipts: currentState.receipts,
});
}
} else if (action === "REFRESH") {
if (!currentState) {
outcome = {
ok: false,
status: "STATE_REJECTED",
code: "STATE_REJECTED",
};
} else {
const approvedTarget = approvedRuntimeTuple(
desired,
activeClaim.operation,
currentState
);
let liveObserved;
try {
liveObserved = await actionPorts.refresh.observe({
operation: {
id: activeClaim.operation.id,
fence: activeClaim.operation.fence,
},
target: currentState.observedTuple,
classification: true,
});
if (!projectRuntimeDriftTuple(liveObserved))
throw new Error("live refresh observation rejected");
} catch {
liveObserved = {
...currentState.observedTuple,
packageHash: canonicalHostWorkerDigest({
invalidLiveObservation: true,
operationId: activeClaim.operation.id,
fence: activeClaim.operation.fence,
}),
processHash: null,
};
}
outcome = await reconcileRuntimeRefresh({
desired: approvedTarget,
approvedDesired: approvedTarget,
observed: liveObserved,
previousKnownGood: currentState.previousKnownGoodTuple,
operation: {
id: activeClaim.operation.id,
fence: activeClaim.operation.fence,
},
ports: actionPorts.refresh,
});
if (outcome.ok)
persistRuntimeState(config, activeClaim, {
...currentState,
desiredRevisionId: desired.revisionId,
desiredRevisionSequence:
activeClaim.operation.lifecycleGeneration,
observedRevisionId: desired.revisionId,
credentialGeneration: desired.serviceCredentialGeneration,
profileDigest: approvedTarget.contentHash,
acceptedFence: activeClaim.operation.fence,
desiredTuple: outcome.observed,
observedTuple: outcome.observed,
previousKnownGoodTuple: outcome.observed,
runtimeHashes: tupleRuntimeHashes(outcome.observed),
});
outcome = {
...outcome,
observedLifecycle:
outcome.observed?.lifecycle ?? currentState.observedLifecycle,
runtimeHashes: outcome.ok
? tupleRuntimeHashes(outcome.observed)
: currentState.runtimeHashes,
};
}
} else if (
[
"ENABLE_GATEWAY",
"DISABLE_GATEWAY",
"ARCHIVE",
"RESTORE",
].includes(action)
) {
if (!currentState) {
outcome = {
ok: false,
status: "STATE_REJECTED",
code: "STATE_REJECTED",
};
} else {
const restoring = action === "RESTORE";
const computedProfile = computeAgentProfileDigest(desired);
if (!computedProfile.ok)
throw new Error("profile digest rejected");
const operation = lifecycleOperation(activeClaim, currentState, {
serviceCredentialGeneration: restoring
? desired.serviceCredentialGeneration
: currentState.credentialGeneration,
profileDigest: restoring
? computedProfile.profileDigest
: currentState.profileDigest,
revisionSequence: restoring
? desired.revisionSequence
: currentState.observedTuple?.revisionSequence,
});
if (restoring) {
operation.targetRuntimeTuple = approvedRuntimeTuple(
desired,
activeClaim.operation,
{
...currentState,
observedLifecycle: "ON",
}
);
}
const lifecyclePorts = restoring
? {
...actionPorts.lifecycle,
rehydrate: (input) =>
actionPorts.lifecycle.rehydrate({
...input,
desired,
serviceCredential: serviceCredentialFor(
desired,
payload?.serviceCredential
),
}),
}
: actionPorts.lifecycle;
outcome = await applyRuntimeLifecycle({
state: currentState,
operation,
ports: lifecyclePorts,
});
if (outcome.state)
persistRuntimeState(config, activeClaim, outcome.state);
outcome = {
...outcome,
observedLifecycle:
outcome.state?.observedLifecycle ??
currentState.observedLifecycle,
runtimeHashes:
restoring && outcome.ok
? (outcome.state?.runtimeHashes ?? null)
: currentState.runtimeHashes,
};
}
} else {
outcome = {
ok: false,
status: "ACTION_REJECTED",
code: "ACTION_REJECTED",
};
}
}
} catch {
outcome = { ok: false, status: "UNCERTAIN", code: "HOST_RUNTIME" };
}
if (outcome?.redeliverable === true && requestFile) {
if (!removeRequest(requestFile, config.requestRoot)) {
outcome = {
...outcome,
redeliverable: false,
status: "UNCERTAIN",
code: "REQUEST_CLEANUP_UNCERTAIN",
};
}
}
const completion = localCompletionReceipt({
activeClaim,
config,
outcome,
effectId,
secretConsumed,
});
atomicPrivateJson(confinedReceiptPath(config, effectId), completion);
return { ok: outcome.ok === true, status: outcome.status };
},
async readReceipt({ effectId }) {
const pathValue = confinedReceiptPath(config, effectId);
if (!existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
if (
link.isSymbolicLink() ||
!link.isFile() ||
(link.mode & 0o777) !== 0o600
)
return null;
return JSON.parse(readFileSync(pathValue, "utf8"));
},
};
}
function privateRootForAdapter(pathValue) {
try {
if (!isAbsolute(pathValue) || !existsSync(pathValue)) return null;
const link = lstatSync(pathValue);
const mode = link.mode & 0o777;
if (
link.isSymbolicLink() ||
!link.isDirectory() ||
(mode & 0o700) !== 0o700 ||
(mode & 0o066) !== 0
)
return null;
return realpathSync(pathValue);
} catch {
return null;
}
}
export function planNextHostWorkerPoll({
poll,
previous = { failures: 0, idleCycles: 0 },
result,
random = Math.random,
}) {
const state = result?.ok
? {
failures: 0,
idleCycles:
result.status === "IDLE"
? Math.min((previous.idleCycles ?? 0) + 1, 8)
: 0,
}
: {
failures: Math.min((previous.failures ?? 0) + 1, 8),
idleCycles: 0,
};
const exponent =
state.failures > 0 ? state.failures : Math.max(0, state.idleCycles - 1);
const base = Math.min(poll.maxDelayMs, poll.minDelayMs * 2 ** exponent);
const jitter = Math.floor(base * poll.jitterRatio * random());
return { state, delayMs: base + jitter };
}
export async function runHostWorkerMain({
argv,
adapter,
fetchImpl,
sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
}) {
try {
const configPath = parseMainArguments(argv ?? []);
if (!configPath)
return { ok: false, code: "usage: --config /absolute/path" };
const link = lstatSync(configPath);
if (link.isSymbolicLink() || !link.isFile() || (link.mode & 0o022) !== 0) {
return { ok: false, code: "worker_config_confinement_failed" };
}
const config = JSON.parse(readFileSync(configPath, "utf8"));
const checked = validateHostWorkerConfig(config);
if (!checked.ok) return { ok: false, code: checked.code };
const selectedAdapter = adapter ?? createPinnedHostWorkerAdapter(config);
const broker = createHttpWorkerBroker(config, fetchImpl);
let pollState = { failures: 0, idleCycles: 0 };
while (true) {
const result = await runHostWorkerCycle({
config,
broker,
adapter: selectedAdapter,
});
const next = planNextHostWorkerPoll({
poll: config.poll,
previous: pollState,
result,
});
pollState = next.state;
await sleep(next.delayMs);
}
} catch {
return { ok: false, code: "host_worker_start_failed" };
}
}