@amaster.ai/employee-runtime-connector 0.1.0-beta.31 → 0.1.0-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/amaster-runtime-daemon.mjs +1033 -201
- package/dist/amaster-runtime.mjs +1 -1
- package/package.json +1 -1
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// MirrorX runtime connector daemon bundle.
|
|
3
3
|
|
|
4
4
|
// src/amaster-runtime-daemon.mjs
|
|
5
|
-
import { createHash as
|
|
6
|
-
import { chmodSync as
|
|
5
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
6
|
+
import { chmodSync as chmodSync5, copyFileSync as copyFileSync3, existsSync as existsSync10, lstatSync as lstatSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync8, readdirSync as readdirSync8, realpathSync as realpathSync3, renameSync as renameSync3, rmSync as rmSync6, statSync as statSync7, symlinkSync as symlinkSync3, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
|
|
7
7
|
import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3 } from "node:os";
|
|
8
|
-
import { basename as basename6, delimiter as delimiter2, dirname as
|
|
8
|
+
import { basename as basename6, delimiter as delimiter2, dirname as dirname7, extname as extname2, isAbsolute as isAbsolute7, join as join11, relative as relative7, resolve as resolve10 } from "node:path";
|
|
9
9
|
import { spawn, spawnSync as spawnSync5 } from "node:child_process";
|
|
10
10
|
|
|
11
11
|
// src/amaster-runtime-daemon/common.mjs
|
|
@@ -388,7 +388,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
388
388
|
}
|
|
389
389
|
return ptr;
|
|
390
390
|
}
|
|
391
|
-
function skipUntil(str, ptr,
|
|
391
|
+
function skipUntil(str, ptr, sep2, end, banNewLines = false) {
|
|
392
392
|
if (!end) {
|
|
393
393
|
ptr = indexOfNewline(str, ptr);
|
|
394
394
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -397,7 +397,7 @@ function skipUntil(str, ptr, sep, end, banNewLines = false) {
|
|
|
397
397
|
let c = str[i];
|
|
398
398
|
if (c === "#") {
|
|
399
399
|
i = indexOfNewline(str, i);
|
|
400
|
-
} else if (c ===
|
|
400
|
+
} else if (c === sep2) {
|
|
401
401
|
return i + 1;
|
|
402
402
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
403
403
|
return i;
|
|
@@ -1572,6 +1572,17 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1572
1572
|
const SUPPORTED_SERVER_NAME2 = "amaster";
|
|
1573
1573
|
const MINIMUM_PI_VERSION = [0, 73, 1];
|
|
1574
1574
|
const MINIMUM_MCP_ADAPTER_VERSION = [2, 6, 1];
|
|
1575
|
+
const MANAGED_BROWSER_USE_PACKAGE = "@amaster.ai/pi-browser-use";
|
|
1576
|
+
const MANAGED_BROWSER_USE_PLUGIN = "browser-use";
|
|
1577
|
+
const MANAGED_BROWSER_USE_BOOLEAN_SETTINGS = [
|
|
1578
|
+
"headless",
|
|
1579
|
+
"categoryNetwork",
|
|
1580
|
+
"categoryEmulation",
|
|
1581
|
+
"categoryPerformance",
|
|
1582
|
+
"experimentalVision",
|
|
1583
|
+
"experimentalScreencast",
|
|
1584
|
+
"experimentalMemory"
|
|
1585
|
+
];
|
|
1575
1586
|
const REQUIRED_AUTHORITY_HEADERS2 = [
|
|
1576
1587
|
"x-amaster-company-id",
|
|
1577
1588
|
"x-amaster-agent-id",
|
|
@@ -1637,14 +1648,20 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1637
1648
|
const PROFILE_MARKER2 = ".amaster-managed-pi-profile.json";
|
|
1638
1649
|
const SESSION_ROLLOUT_MARKER2 = ".amaster-pi-session-rollout.json";
|
|
1639
1650
|
const DEFAULT_SESSION_ROLLOUT_TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
1640
|
-
function
|
|
1651
|
+
function record3(value) {
|
|
1641
1652
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1642
1653
|
}
|
|
1654
|
+
function npmPackageName(source) {
|
|
1655
|
+
if (typeof source !== "string" || !source.startsWith("npm:")) return null;
|
|
1656
|
+
const spec = source.slice("npm:".length);
|
|
1657
|
+
const versionSeparator = spec.startsWith("@") ? spec.indexOf("@", 1) : spec.indexOf("@");
|
|
1658
|
+
return (versionSeparator === -1 ? spec : spec.slice(0, versionSeparator)) || null;
|
|
1659
|
+
}
|
|
1643
1660
|
function nonEmpty2(value, label) {
|
|
1644
1661
|
if (typeof value !== "string" || value.trim() === "") throw new Error(`pi_managed_mcp_invalid: ${label} is required`);
|
|
1645
1662
|
return value.trim();
|
|
1646
1663
|
}
|
|
1647
|
-
function
|
|
1664
|
+
function within3(candidate, root) {
|
|
1648
1665
|
const rel = relative2(root, candidate);
|
|
1649
1666
|
return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
|
|
1650
1667
|
}
|
|
@@ -1687,7 +1704,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1687
1704
|
return matches[0];
|
|
1688
1705
|
}
|
|
1689
1706
|
function restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority) {
|
|
1690
|
-
const session =
|
|
1707
|
+
const session = record3(input.nativeSession);
|
|
1691
1708
|
if (session.mode !== "governed_action_approval" || session.required !== true) return null;
|
|
1692
1709
|
const sessionId = nonEmpty2(session.sessionId, "nativeSession.sessionId");
|
|
1693
1710
|
const sourceRunId = nonEmpty2(session.sourceRunId, "nativeSession.sourceRunId");
|
|
@@ -1711,11 +1728,11 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1711
1728
|
throw new Error("pi_managed_mcp_session_rollout_authority_mismatch: source rollout does not match the approved continuation");
|
|
1712
1729
|
}
|
|
1713
1730
|
const sourceRollout = resolve2(cacheRoot, nonEmpty2(marker.rolloutRelativePath, "rolloutRelativePath"));
|
|
1714
|
-
if (!
|
|
1731
|
+
if (!within3(sourceRollout, cacheRoot) || lstatSync2(sourceRollout).isSymbolicLink() || !lstatSync2(sourceRollout).isFile()) {
|
|
1715
1732
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: source rollout path is invalid");
|
|
1716
1733
|
}
|
|
1717
1734
|
const targetRollout = resolve2(sessionsRoot, marker.rolloutRelativePath);
|
|
1718
|
-
if (!
|
|
1735
|
+
if (!within3(targetRollout, sessionsRoot)) {
|
|
1719
1736
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: target rollout path is invalid");
|
|
1720
1737
|
}
|
|
1721
1738
|
mkdirSync2(dirname2(targetRollout), { recursive: true, mode: 448 });
|
|
@@ -1737,8 +1754,8 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1737
1754
|
return tuple.join(".");
|
|
1738
1755
|
}
|
|
1739
1756
|
function validateAuthority2(input) {
|
|
1740
|
-
const runtimeAuth =
|
|
1741
|
-
const gateway =
|
|
1757
|
+
const runtimeAuth = record3(input.runtimeAuth);
|
|
1758
|
+
const gateway = record3(runtimeAuth.governedMcp);
|
|
1742
1759
|
const runId = nonEmpty2(input.runId, "runId");
|
|
1743
1760
|
if (runtimeAuth.runId !== runId) throw new Error("pi_managed_mcp_owner_mismatch: command runId does not match runtime authority");
|
|
1744
1761
|
if (gateway.schemaVersion !== SUPPORTED_SCHEMA_VERSION2) throw new Error("pi_managed_mcp_invalid: unsupported schema version");
|
|
@@ -1754,7 +1771,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1754
1771
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() + 3e4) {
|
|
1755
1772
|
throw new Error("pi_managed_mcp_session_expired: Gateway session must remain valid through spawn preflight");
|
|
1756
1773
|
}
|
|
1757
|
-
const headers =
|
|
1774
|
+
const headers = record3(gateway.headers);
|
|
1758
1775
|
for (const name of REQUIRED_AUTHORITY_HEADERS2) nonEmpty2(headers[name], `headers.${name}`);
|
|
1759
1776
|
const allowedHeaderNames = /* @__PURE__ */ new Set([...REQUIRED_AUTHORITY_HEADERS2, ...runtimeAuth.issueId ? ["x-amaster-issue-id"] : []]);
|
|
1760
1777
|
if (Object.keys(headers).some((name) => !allowedHeaderNames.has(name)) || Object.keys(headers).length !== allowedHeaderNames.size) {
|
|
@@ -1783,7 +1800,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1783
1800
|
return output;
|
|
1784
1801
|
}
|
|
1785
1802
|
function assertInvocationIsolation2(input) {
|
|
1786
|
-
for (const name of Object.keys(
|
|
1803
|
+
for (const name of Object.keys(record3(input.commandEnv))) {
|
|
1787
1804
|
if (FORBIDDEN_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_override_blocked: ${name}`);
|
|
1788
1805
|
if (!ALLOWED_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_injection_blocked: ${name}`);
|
|
1789
1806
|
}
|
|
@@ -1815,7 +1832,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1815
1832
|
const value = safeProxyValue2(baseEnv?.[name], name);
|
|
1816
1833
|
if (value) env[name] = value;
|
|
1817
1834
|
}
|
|
1818
|
-
return { ...env, ...
|
|
1835
|
+
return { ...env, ...record3(commandEnv) };
|
|
1819
1836
|
}
|
|
1820
1837
|
function projectMcpConfigHasContent(filePath) {
|
|
1821
1838
|
if (!existsSync2(filePath)) return false;
|
|
@@ -1825,14 +1842,14 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1825
1842
|
} catch {
|
|
1826
1843
|
return true;
|
|
1827
1844
|
}
|
|
1828
|
-
const config =
|
|
1829
|
-
return Object.keys(
|
|
1845
|
+
const config = record3(parsed);
|
|
1846
|
+
return Object.keys(record3(config.mcpServers)).length > 0 || Object.keys(record3(config.servers)).length > 0 || Array.isArray(config.imports) && config.imports.length > 0;
|
|
1830
1847
|
}
|
|
1831
1848
|
function assertNoProjectMcpOverride(cwd, runDir) {
|
|
1832
1849
|
let cursor = resolve2(cwd);
|
|
1833
1850
|
const boundary = resolve2(runDir);
|
|
1834
|
-
if (!
|
|
1835
|
-
while (
|
|
1851
|
+
if (!within3(cursor, boundary)) throw new Error("pi_managed_mcp_owner_mismatch: cwd is outside the managed run");
|
|
1852
|
+
while (within3(cursor, boundary)) {
|
|
1836
1853
|
for (const relativePath of [".mcp.json", join3(".pi", "mcp.json")]) {
|
|
1837
1854
|
const configPath = join3(cursor, relativePath);
|
|
1838
1855
|
if (projectMcpConfigHasContent(configPath)) throw new Error(`pi_managed_mcp_project_override_blocked: ${configPath}`);
|
|
@@ -1841,6 +1858,50 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1841
1858
|
cursor = dirname2(cursor);
|
|
1842
1859
|
}
|
|
1843
1860
|
}
|
|
1861
|
+
function selectManagedBrowserUse(sourceSettings, npmSource) {
|
|
1862
|
+
const plugin = record3(record3(sourceSettings.plugins)[MANAGED_BROWSER_USE_PLUGIN]);
|
|
1863
|
+
if (plugin.enabled !== true || plugin.package !== MANAGED_BROWSER_USE_PACKAGE) return null;
|
|
1864
|
+
const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_BROWSER_USE_PACKAGE) : null;
|
|
1865
|
+
if (typeof packageSpec !== "string") return null;
|
|
1866
|
+
const packagePath = join3(npmSource, "node_modules", ...MANAGED_BROWSER_USE_PACKAGE.split("/"), "package.json");
|
|
1867
|
+
if (!existsSync2(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
|
|
1868
|
+
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package is unavailable`);
|
|
1869
|
+
}
|
|
1870
|
+
let packageMetadata;
|
|
1871
|
+
try {
|
|
1872
|
+
packageMetadata = JSON.parse(readFileSync2(packagePath, "utf8"));
|
|
1873
|
+
} catch {
|
|
1874
|
+
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package metadata is invalid`);
|
|
1875
|
+
}
|
|
1876
|
+
if (packageMetadata.name !== MANAGED_BROWSER_USE_PACKAGE) {
|
|
1877
|
+
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package identity mismatch`);
|
|
1878
|
+
}
|
|
1879
|
+
const sourceConfig = record3(sourceSettings["pi-browser-use"]);
|
|
1880
|
+
const config = {};
|
|
1881
|
+
for (const key of MANAGED_BROWSER_USE_BOOLEAN_SETTINGS) {
|
|
1882
|
+
if (typeof sourceConfig[key] === "boolean") config[key] = sourceConfig[key];
|
|
1883
|
+
}
|
|
1884
|
+
if (typeof sourceConfig.viewport === "string" && /^\d{2,5}x\d{2,5}$/.test(sourceConfig.viewport)) {
|
|
1885
|
+
config.viewport = sourceConfig.viewport;
|
|
1886
|
+
}
|
|
1887
|
+
if (typeof sourceConfig.channel === "string" && ["stable", "beta", "dev", "canary"].includes(sourceConfig.channel)) {
|
|
1888
|
+
config.channel = sourceConfig.channel;
|
|
1889
|
+
}
|
|
1890
|
+
return {
|
|
1891
|
+
packageSpec,
|
|
1892
|
+
plugin: {
|
|
1893
|
+
enabled: true,
|
|
1894
|
+
package: MANAGED_BROWSER_USE_PACKAGE
|
|
1895
|
+
},
|
|
1896
|
+
config: {
|
|
1897
|
+
...config,
|
|
1898
|
+
categoryExtensions: false,
|
|
1899
|
+
usageStatistics: false,
|
|
1900
|
+
performanceCrux: false,
|
|
1901
|
+
redactNetworkHeaders: true
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1844
1905
|
function seedPiRuntime(sourceHome, agentDir) {
|
|
1845
1906
|
const source = resolve2(nonEmpty2(sourceHome, "sourcePiHome"));
|
|
1846
1907
|
const npmSource = join3(source, "npm");
|
|
@@ -1859,15 +1920,22 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1859
1920
|
let sourceSettings = {};
|
|
1860
1921
|
if (existsSync2(settingsSource)) {
|
|
1861
1922
|
try {
|
|
1862
|
-
sourceSettings =
|
|
1923
|
+
sourceSettings = record3(JSON.parse(readFileSync2(settingsSource, "utf8")));
|
|
1863
1924
|
} catch {
|
|
1864
1925
|
throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
|
|
1865
1926
|
}
|
|
1866
1927
|
}
|
|
1928
|
+
const browserUse = selectManagedBrowserUse(sourceSettings, npmSource);
|
|
1867
1929
|
const settings = {
|
|
1868
1930
|
...typeof sourceSettings.defaultProvider === "string" ? { defaultProvider: sourceSettings.defaultProvider } : {},
|
|
1869
1931
|
...typeof sourceSettings.defaultModel === "string" ? { defaultModel: sourceSettings.defaultModel } : {},
|
|
1870
|
-
packages: ["npm:pi-mcp-adapter"]
|
|
1932
|
+
packages: ["npm:pi-mcp-adapter", ...browserUse ? [browserUse.packageSpec] : []],
|
|
1933
|
+
...browserUse ? {
|
|
1934
|
+
plugins: {
|
|
1935
|
+
[MANAGED_BROWSER_USE_PLUGIN]: browserUse.plugin
|
|
1936
|
+
},
|
|
1937
|
+
"pi-browser-use": browserUse.config
|
|
1938
|
+
} : {}
|
|
1871
1939
|
};
|
|
1872
1940
|
writePrivateFile2(join3(agentDir, "settings.json"), `${JSON.stringify(settings, null, 2)}
|
|
1873
1941
|
`);
|
|
@@ -1915,7 +1983,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
1915
1983
|
const { gateway, gatewayUrl, sessionToken, headers, runId } = validateAuthority2(input);
|
|
1916
1984
|
const runDir = resolve2(nonEmpty2(input.runDir, "runDir"));
|
|
1917
1985
|
const executorHome = resolve2(nonEmpty2(input.executorHome, "executorHome"));
|
|
1918
|
-
if (!
|
|
1986
|
+
if (!within3(executorHome, join3(runDir, "executors"))) throw new Error("pi_managed_mcp_owner_mismatch: executorHome is outside the managed run");
|
|
1919
1987
|
assertNoProjectMcpOverride(nonEmpty2(input.cwd, "cwd"), runDir);
|
|
1920
1988
|
const profileRoot = join3(executorHome, "managed-mcp");
|
|
1921
1989
|
if (existsSync2(profileRoot)) throw new Error(`pi_managed_mcp_profile_exists: ${profileRoot}`);
|
|
@@ -1930,7 +1998,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
1930
1998
|
const owner = Object.freeze({ commandId: input.commandId, runId });
|
|
1931
1999
|
writePrivateFile2(markerPath, `${JSON.stringify({ version: 1, ...owner, profileRoot })}
|
|
1932
2000
|
`);
|
|
1933
|
-
const runtimeAuth =
|
|
2001
|
+
const runtimeAuth = record3(input.runtimeAuth);
|
|
1934
2002
|
const authority = Object.freeze({
|
|
1935
2003
|
companyId: nonEmpty2(runtimeAuth.companyId, "runtimeAuth.companyId"),
|
|
1936
2004
|
agentId: nonEmpty2(runtimeAuth.agentId, "runtimeAuth.agentId"),
|
|
@@ -2084,7 +2152,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2084
2152
|
const profileRoot = dirname2(markerPath);
|
|
2085
2153
|
try {
|
|
2086
2154
|
const marker = JSON.parse(readFileSync2(markerPath, "utf8"));
|
|
2087
|
-
if (!
|
|
2155
|
+
if (!within3(profileRoot, root) || marker?.profileRoot !== profileRoot) throw new Error("ownership marker root mismatch");
|
|
2088
2156
|
cleanupManagedPiMcpProfile2({ profileRoot }, { commandId: marker.commandId, runId: marker.runId });
|
|
2089
2157
|
removedProfiles += 1;
|
|
2090
2158
|
} catch (error) {
|
|
@@ -2099,7 +2167,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2099
2167
|
const markerStat = lstatSync2(markerPath);
|
|
2100
2168
|
const cacheStat = lstatSync2(cacheRoot);
|
|
2101
2169
|
const marker = JSON.parse(readFileSync2(markerPath, "utf8"));
|
|
2102
|
-
if (!
|
|
2170
|
+
if (!within3(cacheRoot, root) || basename2(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || marker?.cacheRoot !== cacheRoot) throw new Error("session rollout ownership marker mismatch");
|
|
2103
2171
|
const preservedAtMs = typeof marker.preservedAt === "string" ? Date.parse(marker.preservedAt) : Number.NaN;
|
|
2104
2172
|
const markerAgeMs = nowMs - (Number.isFinite(preservedAtMs) ? preservedAtMs : markerStat.mtimeMs);
|
|
2105
2173
|
if (markerAgeMs < rolloutTtlMs) continue;
|
|
@@ -2193,8 +2261,8 @@ function resultOutboxFileName(commandId, now = Date.now()) {
|
|
|
2193
2261
|
return `${now}-${safeCommandId}.json`;
|
|
2194
2262
|
}
|
|
2195
2263
|
function isValidResultOutboxEntry(entry) {
|
|
2196
|
-
const
|
|
2197
|
-
return
|
|
2264
|
+
const record3 = asRecord(entry);
|
|
2265
|
+
return record3.version === 1 && Boolean(readString(record3.path)) && Object.keys(asRecord(record3.payload)).length > 0;
|
|
2198
2266
|
}
|
|
2199
2267
|
function resultOutboxEntryAgeMs(entry, nowMs) {
|
|
2200
2268
|
const createdAt = Date.parse(readString(entry.createdAt) ?? "");
|
|
@@ -2272,8 +2340,8 @@ function governedReadSection(context) {
|
|
|
2272
2340
|
const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
|
|
2273
2341
|
if (reads.length === 0) return { content: "", provenance: [] };
|
|
2274
2342
|
const normalized = reads.map((entry, index) => {
|
|
2275
|
-
const
|
|
2276
|
-
const receipt = asRecord(
|
|
2343
|
+
const record3 = asRecord(entry);
|
|
2344
|
+
const receipt = asRecord(record3.receipt);
|
|
2277
2345
|
const provider = readString(receipt.provider) ?? readString(receipt.transport);
|
|
2278
2346
|
const operation = readString(receipt.operation);
|
|
2279
2347
|
const observedAt = readString(receipt.retrievedAt) ?? readString(receipt.observedAt);
|
|
@@ -2283,7 +2351,7 @@ function governedReadSection(context) {
|
|
|
2283
2351
|
throw new Error(`governed_read_context_provenance_invalid: entry ${index} requires provider, operation, observedAt, and source`);
|
|
2284
2352
|
}
|
|
2285
2353
|
return {
|
|
2286
|
-
content:
|
|
2354
|
+
content: record3.content,
|
|
2287
2355
|
receipt: {
|
|
2288
2356
|
provider,
|
|
2289
2357
|
operation,
|
|
@@ -2311,6 +2379,7 @@ function fixedRules(input, includeIssueLine) {
|
|
|
2311
2379
|
"## AMaster Runtime Connector Task",
|
|
2312
2380
|
"You are executing a task dispatched by MirrorX from the central control plane.",
|
|
2313
2381
|
"Work only inside the declared workspace. Make concrete progress and finish with a concise result summary.",
|
|
2382
|
+
"Before changing the task status to done, audit every explicit requirement in the task against the final evidence. A successful tool or document write proves delivery, not acceptance: inspect the delivered content for required sections, diagrams, tables, and factual constraints. Do not leave stale in-progress wording such as \u201Ccurrent run\u201D in a terminal deliverable; rewrite it to the final observed state. Do not list finalization itself as remaining or next work in a terminal deliverable. If any requirement is missing or cannot be verified, do not mark done. To request review, use create_interaction with kind request_confirmation and payload.resolutionMode review; never call update_parent with status in_review. Otherwise keep the issue todo or blocked with the exact gap and next owner.",
|
|
2314
2383
|
"Do not install operating-system or user-global packages, and do not use host package managers such as brew, apt, yum, or global pip/npm installs. Use tools already available or workspace-local dependencies or virtual environments. If a required renderer or evaluator is unavailable, keep the source artifact, record the exact verification gap, and do not mutate the host.",
|
|
2315
2384
|
`- command id: ${input.commandId}`,
|
|
2316
2385
|
`- run id: ${input.runId ?? "unknown"}`,
|
|
@@ -2731,6 +2800,23 @@ function buildConfig(env = process.env, flags = {}) {
|
|
|
2731
2800
|
flags.executorMaxRssMb ?? env.AMASTER_EXECUTOR_MAX_RSS_MB,
|
|
2732
2801
|
0
|
|
2733
2802
|
),
|
|
2803
|
+
piChildUidBase: parseNonNegativeInteger(
|
|
2804
|
+
flags.piChildUidBase ?? env.AMASTER_PI_CHILD_UID_BASE,
|
|
2805
|
+
0
|
|
2806
|
+
),
|
|
2807
|
+
piChildUidSpan: parsePositiveInteger(
|
|
2808
|
+
flags.piChildUidSpan ?? env.AMASTER_PI_CHILD_UID_SPAN,
|
|
2809
|
+
3e4
|
|
2810
|
+
),
|
|
2811
|
+
piRuntimeSeedRoot: String(
|
|
2812
|
+
flags.piRuntimeSeedRoot ?? env.PI_RUNTIME_SEED_DIR ?? ""
|
|
2813
|
+
).trim(),
|
|
2814
|
+
piRuntimeOverlayRoot: String(
|
|
2815
|
+
flags.piRuntimeOverlayRoot ?? env.AMASTER_PI_RUNTIME_OVERLAY_DIR ?? ""
|
|
2816
|
+
).trim(),
|
|
2817
|
+
piRuntimeEffectivePolicyFile: String(
|
|
2818
|
+
flags.piRuntimeEffectivePolicyFile ?? env.AMASTER_PI_RUNTIME_EFFECTIVE_POLICY_FILE ?? ""
|
|
2819
|
+
).trim(),
|
|
2734
2820
|
artifactVerifierCommands: splitList(
|
|
2735
2821
|
flags.artifactVerifierCommands ?? env.AMASTER_ARTIFACT_VERIFIER_COMMANDS ?? ""
|
|
2736
2822
|
),
|
|
@@ -2805,10 +2891,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
2805
2891
|
const text = JSON.stringify(compactExecutorJsonValue(event, stringMaxChars));
|
|
2806
2892
|
if (text.length <= 15e3) return text;
|
|
2807
2893
|
}
|
|
2808
|
-
const
|
|
2809
|
-
const item = tcAsRecord(
|
|
2894
|
+
const record3 = tcAsRecord(event);
|
|
2895
|
+
const item = tcAsRecord(record3.item);
|
|
2810
2896
|
return JSON.stringify({
|
|
2811
|
-
type: tcReadString(
|
|
2897
|
+
type: tcReadString(record3.type) ?? "executor.event",
|
|
2812
2898
|
item: item.type ? {
|
|
2813
2899
|
id: tcReadString(item.id),
|
|
2814
2900
|
type: tcReadString(item.type),
|
|
@@ -2821,10 +2907,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
2821
2907
|
});
|
|
2822
2908
|
}
|
|
2823
2909
|
function summarizeTokenUsage(usage) {
|
|
2824
|
-
const
|
|
2825
|
-
const inputTokens = tcReadNumber(
|
|
2826
|
-
const cachedInputTokens = tcReadNumber(
|
|
2827
|
-
const outputTokens = tcReadNumber(
|
|
2910
|
+
const record3 = tcAsRecord(usage);
|
|
2911
|
+
const inputTokens = tcReadNumber(record3.input_tokens ?? record3.inputTokens, 0);
|
|
2912
|
+
const cachedInputTokens = tcReadNumber(record3.cached_input_tokens ?? record3.cachedInputTokens, 0);
|
|
2913
|
+
const outputTokens = tcReadNumber(record3.output_tokens ?? record3.outputTokens, 0);
|
|
2828
2914
|
const parts = [];
|
|
2829
2915
|
if (inputTokens > 0) parts.push(`\u8F93\u5165 ${inputTokens}`);
|
|
2830
2916
|
if (cachedInputTokens > 0) parts.push(`\u7F13\u5B58 ${cachedInputTokens}`);
|
|
@@ -3079,8 +3165,8 @@ function summarizeClaudeEvent(event) {
|
|
|
3079
3165
|
return null;
|
|
3080
3166
|
}
|
|
3081
3167
|
function tcPiMessageText(message) {
|
|
3082
|
-
const
|
|
3083
|
-
const content =
|
|
3168
|
+
const record3 = tcAsRecord(message);
|
|
3169
|
+
const content = record3.content;
|
|
3084
3170
|
if (typeof content === "string" && content.trim().length > 0) return content.trim();
|
|
3085
3171
|
if (!Array.isArray(content)) return "";
|
|
3086
3172
|
return content.map((entry) => {
|
|
@@ -3094,14 +3180,14 @@ function tcPiAssistantMessageEventText(assistantMessageEvent) {
|
|
|
3094
3180
|
return tcReadString(event.content) ?? "";
|
|
3095
3181
|
}
|
|
3096
3182
|
function tcPiMessageStopReason(message) {
|
|
3097
|
-
const
|
|
3098
|
-
return tcReadString(
|
|
3183
|
+
const record3 = tcAsRecord(message);
|
|
3184
|
+
return tcReadString(record3.stopReason ?? record3.stop_reason);
|
|
3099
3185
|
}
|
|
3100
3186
|
function tcPiMessageErrorText(message) {
|
|
3101
|
-
const
|
|
3102
|
-
const explicitError = tcReadString(
|
|
3187
|
+
const record3 = tcAsRecord(message);
|
|
3188
|
+
const explicitError = tcReadString(record3.errorMessage ?? record3.error_message)?.trim();
|
|
3103
3189
|
if (explicitError) return explicitError;
|
|
3104
|
-
const stopReason = tcPiMessageStopReason(
|
|
3190
|
+
const stopReason = tcPiMessageStopReason(record3);
|
|
3105
3191
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
3106
3192
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
3107
3193
|
}
|
|
@@ -3521,13 +3607,13 @@ function parseClaudeStreamJson(stdout) {
|
|
|
3521
3607
|
}
|
|
3522
3608
|
function openCodeErrorText(value) {
|
|
3523
3609
|
if (typeof value === "string") return value;
|
|
3524
|
-
const
|
|
3525
|
-
const message = readString(
|
|
3610
|
+
const record3 = asRecord(value);
|
|
3611
|
+
const message = readString(record3.message);
|
|
3526
3612
|
if (message) return message;
|
|
3527
|
-
const data = asRecord(
|
|
3613
|
+
const data = asRecord(record3.data);
|
|
3528
3614
|
const nestedMessage = readString(data.message);
|
|
3529
3615
|
if (nestedMessage) return nestedMessage;
|
|
3530
|
-
return readString(
|
|
3616
|
+
return readString(record3.name) ?? readString(record3.code) ?? "";
|
|
3531
3617
|
}
|
|
3532
3618
|
function parseOpenCodeJsonl(stdout) {
|
|
3533
3619
|
let sessionId = null;
|
|
@@ -3565,8 +3651,8 @@ function parseOpenCodeJsonl(stdout) {
|
|
|
3565
3651
|
return { sessionId, summary, usage, errorMessage };
|
|
3566
3652
|
}
|
|
3567
3653
|
function piMessageText(message) {
|
|
3568
|
-
const
|
|
3569
|
-
const content =
|
|
3654
|
+
const record3 = asRecord(message);
|
|
3655
|
+
const content = record3.content;
|
|
3570
3656
|
if (typeof content === "string") return content.trim();
|
|
3571
3657
|
if (!Array.isArray(content)) return "";
|
|
3572
3658
|
return content.map((entry) => {
|
|
@@ -3591,10 +3677,10 @@ function piTextValue(value) {
|
|
|
3591
3677
|
return typeof value === "string" && value.length > 0 ? value : "";
|
|
3592
3678
|
}
|
|
3593
3679
|
function piAssistantEventText(assistantEvent) {
|
|
3594
|
-
const
|
|
3595
|
-
const type = readString(
|
|
3596
|
-
if (type === "text_delta") return piTextValue(
|
|
3597
|
-
if (type === "text_end") return piTextValue(
|
|
3680
|
+
const record3 = asRecord(assistantEvent);
|
|
3681
|
+
const type = readString(record3.type);
|
|
3682
|
+
if (type === "text_delta") return piTextValue(record3.delta);
|
|
3683
|
+
if (type === "text_end") return piTextValue(record3.content);
|
|
3598
3684
|
return "";
|
|
3599
3685
|
}
|
|
3600
3686
|
function piMessageUsage(message) {
|
|
@@ -3615,14 +3701,14 @@ function assignPiUsage(target, source) {
|
|
|
3615
3701
|
if (source.costUsd > 0) target.costUsd = source.costUsd;
|
|
3616
3702
|
}
|
|
3617
3703
|
function piMessageStopReason(message) {
|
|
3618
|
-
const
|
|
3619
|
-
return readString(
|
|
3704
|
+
const record3 = asRecord(message);
|
|
3705
|
+
return readString(record3.stopReason ?? record3.stop_reason);
|
|
3620
3706
|
}
|
|
3621
3707
|
function piMessageErrorText(message) {
|
|
3622
|
-
const
|
|
3623
|
-
const explicitError = readString(
|
|
3708
|
+
const record3 = asRecord(message);
|
|
3709
|
+
const explicitError = readString(record3.errorMessage ?? record3.error_message)?.trim();
|
|
3624
3710
|
if (explicitError) return explicitError;
|
|
3625
|
-
const stopReason = piMessageStopReason(
|
|
3711
|
+
const stopReason = piMessageStopReason(record3);
|
|
3626
3712
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
3627
3713
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
3628
3714
|
}
|
|
@@ -3889,7 +3975,7 @@ async function postRuntimeConnectorJsonWithRetry(config, path, payload, options
|
|
|
3889
3975
|
} catch (error) {
|
|
3890
3976
|
lastError = error;
|
|
3891
3977
|
if (attempt >= maxAttempts || !retryableRuntimeConnectorPost(error)) throw error;
|
|
3892
|
-
if (delayMs > 0) await new Promise((
|
|
3978
|
+
if (delayMs > 0) await new Promise((resolve11) => setTimeout(resolve11, delayMs));
|
|
3893
3979
|
}
|
|
3894
3980
|
}
|
|
3895
3981
|
throw lastError;
|
|
@@ -4475,11 +4561,574 @@ function summarizeAmasterRuntimeVersionDrift(input = {}) {
|
|
|
4475
4561
|
};
|
|
4476
4562
|
}
|
|
4477
4563
|
|
|
4564
|
+
// src/amaster-runtime-daemon/pi-child-isolation.mjs
|
|
4565
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
4566
|
+
import {
|
|
4567
|
+
chmodSync as chmodSync3,
|
|
4568
|
+
chownSync,
|
|
4569
|
+
lchownSync,
|
|
4570
|
+
lstatSync as lstatSync4,
|
|
4571
|
+
readdirSync as readdirSync5
|
|
4572
|
+
} from "node:fs";
|
|
4573
|
+
import { resolve as resolve7, sep } from "node:path";
|
|
4574
|
+
function defaultHashRunId(runId) {
|
|
4575
|
+
return Number.parseInt(createHash5("sha256").update(runId).digest("hex").slice(0, 8), 16);
|
|
4576
|
+
}
|
|
4577
|
+
function positiveInteger(value, label) {
|
|
4578
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
4579
|
+
throw new Error(`pi_child_isolation_invalid_${label}`);
|
|
4580
|
+
}
|
|
4581
|
+
return value;
|
|
4582
|
+
}
|
|
4583
|
+
function isWithin(path, root) {
|
|
4584
|
+
const normalizedPath = resolve7(path);
|
|
4585
|
+
const normalizedRoot = resolve7(root);
|
|
4586
|
+
return normalizedPath === normalizedRoot || normalizedPath.startsWith(`${normalizedRoot}${sep}`);
|
|
4587
|
+
}
|
|
4588
|
+
function isolatePiChildPath(path, uid, gid) {
|
|
4589
|
+
const resolvedPath = resolve7(path);
|
|
4590
|
+
const visit = (entryPath) => {
|
|
4591
|
+
const stat = lstatSync4(entryPath);
|
|
4592
|
+
if (stat.isSymbolicLink()) {
|
|
4593
|
+
lchownSync(entryPath, uid, gid);
|
|
4594
|
+
return;
|
|
4595
|
+
}
|
|
4596
|
+
chownSync(entryPath, uid, gid);
|
|
4597
|
+
if (stat.isDirectory()) {
|
|
4598
|
+
chmodSync3(entryPath, 448);
|
|
4599
|
+
for (const entry of readdirSync5(entryPath)) {
|
|
4600
|
+
visit(resolve7(entryPath, entry));
|
|
4601
|
+
}
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4604
|
+
chmodSync3(entryPath, 384 | stat.mode & 73);
|
|
4605
|
+
};
|
|
4606
|
+
visit(resolvedPath);
|
|
4607
|
+
}
|
|
4608
|
+
function createPiChildIdentityAllocator(input = {}) {
|
|
4609
|
+
const uidBase = positiveInteger(input.uidBase ?? 2e4, "uid_base");
|
|
4610
|
+
const uidSpan = positiveInteger(input.uidSpan ?? 3e4, "uid_span");
|
|
4611
|
+
const hashRunId = input.hashRunId ?? defaultHashRunId;
|
|
4612
|
+
const runAssignments = /* @__PURE__ */ new Map();
|
|
4613
|
+
const uidAssignments = /* @__PURE__ */ new Map();
|
|
4614
|
+
return {
|
|
4615
|
+
acquire(runId) {
|
|
4616
|
+
if (typeof runId !== "string" || runId.trim().length === 0) {
|
|
4617
|
+
throw new Error("pi_child_isolation_run_id_required");
|
|
4618
|
+
}
|
|
4619
|
+
const normalizedRunId = runId.trim();
|
|
4620
|
+
const existing = runAssignments.get(normalizedRunId);
|
|
4621
|
+
if (existing) return { ...existing };
|
|
4622
|
+
const initialOffset = Math.abs(hashRunId(normalizedRunId)) % uidSpan;
|
|
4623
|
+
for (let attempt = 0; attempt < uidSpan; attempt += 1) {
|
|
4624
|
+
const uid = uidBase + (initialOffset + attempt) % uidSpan;
|
|
4625
|
+
if (uidAssignments.has(uid)) continue;
|
|
4626
|
+
const assignment = { uid, gid: uid };
|
|
4627
|
+
runAssignments.set(normalizedRunId, assignment);
|
|
4628
|
+
uidAssignments.set(uid, normalizedRunId);
|
|
4629
|
+
return { ...assignment };
|
|
4630
|
+
}
|
|
4631
|
+
throw new Error("pi_child_isolation_uid_pool_exhausted");
|
|
4632
|
+
},
|
|
4633
|
+
release(runId) {
|
|
4634
|
+
const assignment = runAssignments.get(runId);
|
|
4635
|
+
if (!assignment) return false;
|
|
4636
|
+
runAssignments.delete(runId);
|
|
4637
|
+
uidAssignments.delete(assignment.uid);
|
|
4638
|
+
return true;
|
|
4639
|
+
},
|
|
4640
|
+
activeAssignments() {
|
|
4641
|
+
return Array.from(runAssignments, ([runId, assignment]) => ({ runId, ...assignment }));
|
|
4642
|
+
}
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4645
|
+
function piChildIsolationProfileRoot(input) {
|
|
4646
|
+
const managedProfileRoot = input.managedMcpProfile?.profileRoot;
|
|
4647
|
+
if (typeof managedProfileRoot === "string" && managedProfileRoot.trim() !== "") {
|
|
4648
|
+
return managedProfileRoot;
|
|
4649
|
+
}
|
|
4650
|
+
return input.executorHome;
|
|
4651
|
+
}
|
|
4652
|
+
function requireTrustedPiChildAllocator(allocator, trustedRuntimeEnabled) {
|
|
4653
|
+
if (trustedRuntimeEnabled && !allocator) {
|
|
4654
|
+
throw new Error("pi_trusted_runtime_child_isolation_required");
|
|
4655
|
+
}
|
|
4656
|
+
return allocator;
|
|
4657
|
+
}
|
|
4658
|
+
function preparePiChildIsolation(input) {
|
|
4659
|
+
if (input.effectiveUid !== 0) {
|
|
4660
|
+
throw new Error("pi_child_isolation_root_parent_required");
|
|
4661
|
+
}
|
|
4662
|
+
if (!isWithin(input.profileRoot, input.allowedRoot) || !isWithin(input.workspaceRoot, input.allowedRoot)) {
|
|
4663
|
+
throw new Error("pi_child_isolation_path_outside_run_root");
|
|
4664
|
+
}
|
|
4665
|
+
const assignment = input.allocator.acquire(input.runId);
|
|
4666
|
+
const isolatePath = input.isolatePath ?? isolatePiChildPath;
|
|
4667
|
+
try {
|
|
4668
|
+
for (const path of [resolve7(input.profileRoot), resolve7(input.workspaceRoot)]) {
|
|
4669
|
+
isolatePath(path, assignment.uid, assignment.gid);
|
|
4670
|
+
}
|
|
4671
|
+
} catch (error) {
|
|
4672
|
+
input.allocator.release(input.runId);
|
|
4673
|
+
throw error;
|
|
4674
|
+
}
|
|
4675
|
+
return {
|
|
4676
|
+
spawn: { uid: assignment.uid, gid: assignment.gid },
|
|
4677
|
+
attestation: {
|
|
4678
|
+
schemaVersion: "amaster.pi-child-isolation.v1",
|
|
4679
|
+
commandId: input.commandId,
|
|
4680
|
+
runId: input.runId,
|
|
4681
|
+
identity: `dynamic-uid:${assignment.uid}`,
|
|
4682
|
+
profileRoot: resolve7(input.profileRoot),
|
|
4683
|
+
workspaceRoot: resolve7(input.workspaceRoot)
|
|
4684
|
+
},
|
|
4685
|
+
release: () => input.allocator.release(input.runId)
|
|
4686
|
+
};
|
|
4687
|
+
}
|
|
4688
|
+
|
|
4689
|
+
// src/amaster-runtime-daemon/pi-trusted-runtime-profile.mjs
|
|
4690
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
4691
|
+
import {
|
|
4692
|
+
chmodSync as chmodSync4,
|
|
4693
|
+
copyFileSync as copyFileSync2,
|
|
4694
|
+
existsSync as existsSync8,
|
|
4695
|
+
lstatSync as lstatSync5,
|
|
4696
|
+
mkdirSync as mkdirSync5,
|
|
4697
|
+
readFileSync as readFileSync6,
|
|
4698
|
+
readdirSync as readdirSync6,
|
|
4699
|
+
rmSync as rmSync5,
|
|
4700
|
+
symlinkSync as symlinkSync2,
|
|
4701
|
+
writeFileSync as writeFileSync5
|
|
4702
|
+
} from "node:fs";
|
|
4703
|
+
import { dirname as dirname6, isAbsolute as isAbsolute5, join as join9, relative as relative5, resolve as resolve8 } from "node:path";
|
|
4704
|
+
var ASSERTION_VERSION = "2026-07-25.v1";
|
|
4705
|
+
var SHA256 = /^[a-f0-9]{64}$/;
|
|
4706
|
+
var COPY_ENTRIES = ["SYSTEM.md", "policy", "skills", "agents", "bundles", "extensions"];
|
|
4707
|
+
var JSON_ENTRIES = ["settings.json", "models.json"];
|
|
4708
|
+
var SECRET_KEY = /(authorization|cookie|api[_-]?key|password|secret|token)$/i;
|
|
4709
|
+
var SECRET_VALUE = /(?:authorization|cookie|api[_-]?key|password|secret|token)\s*[:=]\s*(?:bearer\s+)?[^\s"',;]+|bearer\s+[^\s"',;]+/i;
|
|
4710
|
+
var MAX_AUDIT_BYTES = 1024 * 1024;
|
|
4711
|
+
var MAX_AUDIT_EVENTS = 2e3;
|
|
4712
|
+
function requiredString2(value, field) {
|
|
4713
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
4714
|
+
throw new Error(`pi_trusted_runtime_assertion_invalid:${field}`);
|
|
4715
|
+
}
|
|
4716
|
+
return value.trim();
|
|
4717
|
+
}
|
|
4718
|
+
function requiredDigest(value, field) {
|
|
4719
|
+
const digest = requiredString2(value, field);
|
|
4720
|
+
if (!SHA256.test(digest)) throw new Error(`pi_trusted_runtime_assertion_invalid:${field}`);
|
|
4721
|
+
return digest;
|
|
4722
|
+
}
|
|
4723
|
+
function sha256File(path, label) {
|
|
4724
|
+
const stat = lstatSync5(path);
|
|
4725
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4726
|
+
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4727
|
+
}
|
|
4728
|
+
return createHash6("sha256").update(readFileSync6(path)).digest("hex");
|
|
4729
|
+
}
|
|
4730
|
+
function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
|
|
4731
|
+
if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
|
|
4732
|
+
throw new Error(`pi_trusted_runtime_source_invalid:${label}_files`);
|
|
4733
|
+
}
|
|
4734
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4735
|
+
for (const entry of manifest.files) {
|
|
4736
|
+
const relativePath = requiredString2(entry?.path, `${label}.files.path`);
|
|
4737
|
+
const expectedDigest = requiredDigest(entry?.sha256, `${label}.files.sha256`);
|
|
4738
|
+
const filePath = resolve8(root, relativePath);
|
|
4739
|
+
if (!within2(filePath, root) || seen.has(relativePath)) {
|
|
4740
|
+
throw new Error(`pi_trusted_runtime_source_invalid:${label}_files`);
|
|
4741
|
+
}
|
|
4742
|
+
seen.add(relativePath);
|
|
4743
|
+
if (sha256File(filePath, `${label}_file`) !== expectedDigest) {
|
|
4744
|
+
throw new Error(`pi_trusted_runtime_source_digest_mismatch:${label}:${relativePath}`);
|
|
4745
|
+
}
|
|
4746
|
+
}
|
|
4747
|
+
if (!enforceComplete) return;
|
|
4748
|
+
const ignored = new Set(ignoredPaths);
|
|
4749
|
+
const visit = (directory) => {
|
|
4750
|
+
for (const entry of readdirSync6(directory)) {
|
|
4751
|
+
const filePath = join9(directory, entry);
|
|
4752
|
+
const relativePath = relative5(root, filePath);
|
|
4753
|
+
if (ignored.has(relativePath)) continue;
|
|
4754
|
+
const stat = lstatSync5(filePath);
|
|
4755
|
+
if (stat.isSymbolicLink()) {
|
|
4756
|
+
throw new Error(`pi_trusted_runtime_source_unsafe:${label}_file`);
|
|
4757
|
+
}
|
|
4758
|
+
if (stat.isDirectory()) {
|
|
4759
|
+
visit(filePath);
|
|
4760
|
+
} else if (!stat.isFile() || !seen.has(relativePath)) {
|
|
4761
|
+
throw new Error(`pi_trusted_runtime_source_invalid:${label}_files`);
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
};
|
|
4765
|
+
visit(root);
|
|
4766
|
+
}
|
|
4767
|
+
function record2(value) {
|
|
4768
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
4769
|
+
}
|
|
4770
|
+
function within2(candidate, root) {
|
|
4771
|
+
const rel = relative5(root, candidate);
|
|
4772
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
|
|
4773
|
+
}
|
|
4774
|
+
function readJsonFile(path, label, fallback = {}) {
|
|
4775
|
+
if (!existsSync8(path)) return fallback;
|
|
4776
|
+
const stat = lstatSync5(path);
|
|
4777
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4778
|
+
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4779
|
+
}
|
|
4780
|
+
try {
|
|
4781
|
+
return JSON.parse(readFileSync6(path, "utf8"));
|
|
4782
|
+
} catch {
|
|
4783
|
+
throw new Error(`pi_trusted_runtime_source_invalid:${label}`);
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
function deepMerge(base, overlay) {
|
|
4787
|
+
if (!base || typeof base !== "object" || Array.isArray(base)) return structuredClone(overlay);
|
|
4788
|
+
if (!overlay || typeof overlay !== "object" || Array.isArray(overlay)) return structuredClone(overlay);
|
|
4789
|
+
const merged = { ...structuredClone(base) };
|
|
4790
|
+
for (const [key, value] of Object.entries(overlay)) {
|
|
4791
|
+
merged[key] = key in merged ? deepMerge(merged[key], value) : structuredClone(value);
|
|
4792
|
+
}
|
|
4793
|
+
return merged;
|
|
4794
|
+
}
|
|
4795
|
+
function assertNoPersistentSecrets(value, path = []) {
|
|
4796
|
+
if (Array.isArray(value)) {
|
|
4797
|
+
value.forEach((entry, index) => assertNoPersistentSecrets(entry, [...path, String(index)]));
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
if (!value || typeof value !== "object") return;
|
|
4801
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
4802
|
+
if (SECRET_KEY.test(key) && typeof entry === "string" && entry.length > 0 && !/^\$\{[A-Z_][A-Z0-9_]*\}$/.test(entry)) {
|
|
4803
|
+
throw new Error(`pi_trusted_runtime_persistent_secret_blocked:${[...path, key].join(".")}`);
|
|
4804
|
+
}
|
|
4805
|
+
assertNoPersistentSecrets(entry, [...path, key]);
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
function copyTreeNoLinks(source, target) {
|
|
4809
|
+
const stat = lstatSync5(source);
|
|
4810
|
+
if (stat.isSymbolicLink()) throw new Error("pi_trusted_runtime_source_symlink_blocked");
|
|
4811
|
+
if (stat.isDirectory()) {
|
|
4812
|
+
mkdirSync5(target, { recursive: true, mode: 448 });
|
|
4813
|
+
chmodSync4(target, 448);
|
|
4814
|
+
for (const entry of readdirSync6(source)) {
|
|
4815
|
+
copyTreeNoLinks(join9(source, entry), join9(target, entry));
|
|
4816
|
+
}
|
|
4817
|
+
return;
|
|
4818
|
+
}
|
|
4819
|
+
if (!stat.isFile()) throw new Error("pi_trusted_runtime_source_type_blocked");
|
|
4820
|
+
mkdirSync5(dirname6(target), { recursive: true, mode: 448 });
|
|
4821
|
+
copyFileSync2(source, target);
|
|
4822
|
+
chmodSync4(target, 384 | stat.mode & 73);
|
|
4823
|
+
}
|
|
4824
|
+
function mergeMcp(seedRoot, overlayRoot, governedConfig) {
|
|
4825
|
+
const seed = record2(readJsonFile(join9(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
|
|
4826
|
+
const overlay = record2(readJsonFile(join9(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
|
|
4827
|
+
assertNoPersistentSecrets(seed, ["seed", "mcp.json"]);
|
|
4828
|
+
assertNoPersistentSecrets(overlay, ["overlay", "mcp.json"]);
|
|
4829
|
+
const seedServers = record2(seed.mcpServers);
|
|
4830
|
+
const overlayServers = record2(overlay.mcpServers);
|
|
4831
|
+
if ("amaster" in seedServers || "amaster" in overlayServers) {
|
|
4832
|
+
throw new Error("pi_trusted_runtime_reserved_mcp_override:amaster");
|
|
4833
|
+
}
|
|
4834
|
+
const governed = record2(record2(governedConfig).mcpServers).amaster;
|
|
4835
|
+
if (!governed) throw new Error("pi_trusted_runtime_governed_mcp_missing");
|
|
4836
|
+
return {
|
|
4837
|
+
...deepMerge(seed, overlay),
|
|
4838
|
+
mcpServers: {
|
|
4839
|
+
...deepMerge(seedServers, overlayServers),
|
|
4840
|
+
amaster: governed
|
|
4841
|
+
}
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
function packageName(spec) {
|
|
4845
|
+
if (typeof spec !== "string" || !spec.startsWith("npm:")) return null;
|
|
4846
|
+
const value = spec.slice(4);
|
|
4847
|
+
const separator = value.startsWith("@") ? value.indexOf("@", 1) : value.indexOf("@");
|
|
4848
|
+
return separator < 0 ? value : value.slice(0, separator);
|
|
4849
|
+
}
|
|
4850
|
+
function assertEnabledPackagesAvailable(settings, npmRoot) {
|
|
4851
|
+
const requiredNames = new Set(
|
|
4852
|
+
(Array.isArray(settings.packages) ? settings.packages : []).map(packageName).filter(Boolean)
|
|
4853
|
+
);
|
|
4854
|
+
for (const plugin of Object.values(record2(settings.plugins))) {
|
|
4855
|
+
const config = record2(plugin);
|
|
4856
|
+
if (config.enabled === true && typeof config.package === "string") {
|
|
4857
|
+
requiredNames.add(config.package);
|
|
4858
|
+
}
|
|
4859
|
+
}
|
|
4860
|
+
for (const name of requiredNames) {
|
|
4861
|
+
const metadataPath = join9(npmRoot, "node_modules", ...name.split("/"), "package.json");
|
|
4862
|
+
const metadata = readJsonFile(metadataPath, `package:${name}`, null);
|
|
4863
|
+
if (!metadata || metadata.name !== name) {
|
|
4864
|
+
throw new Error(`pi_trusted_runtime_package_unavailable:${name}`);
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
function materializeTrustedPiRuntimeProfile(input) {
|
|
4869
|
+
const seedRoot = resolve8(requiredString2(input.seedRoot, "seedRoot"));
|
|
4870
|
+
const overlayRoot = resolve8(requiredString2(input.overlayRoot, "overlayRoot"));
|
|
4871
|
+
const profileRoot = resolve8(requiredString2(input.profileRoot, "profileRoot"));
|
|
4872
|
+
const agentDir = resolve8(requiredString2(input.agentDir, "agentDir"));
|
|
4873
|
+
if (!within2(agentDir, profileRoot)) throw new Error("pi_trusted_runtime_profile_path_escape");
|
|
4874
|
+
for (const [root, label] of [[seedRoot, "seed_root"], [overlayRoot, "overlay_root"]]) {
|
|
4875
|
+
const stat = lstatSync5(root);
|
|
4876
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
4877
|
+
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
for (const entry of COPY_ENTRIES) {
|
|
4881
|
+
const target = join9(agentDir, entry);
|
|
4882
|
+
rmSync5(target, { recursive: true, force: true });
|
|
4883
|
+
for (const sourceRoot of [seedRoot, overlayRoot]) {
|
|
4884
|
+
const source = join9(sourceRoot, entry);
|
|
4885
|
+
if (existsSync8(source)) copyTreeNoLinks(source, target);
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
const mergedJson = {};
|
|
4889
|
+
for (const entry of JSON_ENTRIES) {
|
|
4890
|
+
const seed = readJsonFile(join9(seedRoot, entry), `seed_${entry}`, {});
|
|
4891
|
+
const overlay = readJsonFile(join9(overlayRoot, entry), `overlay_${entry}`, {});
|
|
4892
|
+
const merged = deepMerge(seed, overlay);
|
|
4893
|
+
if (entry === "settings.json") {
|
|
4894
|
+
merged["pi-security"] = {
|
|
4895
|
+
...record2(merged["pi-security"]),
|
|
4896
|
+
enabled: true,
|
|
4897
|
+
approvals: {
|
|
4898
|
+
...record2(record2(merged["pi-security"]).approvals),
|
|
4899
|
+
allowSessionGrants: false
|
|
4900
|
+
}
|
|
4901
|
+
};
|
|
4902
|
+
}
|
|
4903
|
+
assertNoPersistentSecrets(merged, [entry]);
|
|
4904
|
+
writeFileSync5(join9(agentDir, entry), `${JSON.stringify(merged, null, 2)}
|
|
4905
|
+
`, {
|
|
4906
|
+
mode: 384
|
|
4907
|
+
});
|
|
4908
|
+
chmodSync4(join9(agentDir, entry), 384);
|
|
4909
|
+
mergedJson[entry] = merged;
|
|
4910
|
+
}
|
|
4911
|
+
const governedConfig = readJsonFile(input.governedMcpConfigPath, "governed_mcp");
|
|
4912
|
+
const mcp = mergeMcp(seedRoot, overlayRoot, governedConfig);
|
|
4913
|
+
writeFileSync5(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
|
|
4914
|
+
`, { mode: 384 });
|
|
4915
|
+
chmodSync4(input.governedMcpConfigPath, 384);
|
|
4916
|
+
const npmRoot = join9(seedRoot, "npm");
|
|
4917
|
+
assertEnabledPackagesAvailable(mergedJson["settings.json"], npmRoot);
|
|
4918
|
+
const npmTarget = join9(agentDir, "npm");
|
|
4919
|
+
rmSync5(npmTarget, { recursive: true, force: true });
|
|
4920
|
+
const npmStat = lstatSync5(npmRoot);
|
|
4921
|
+
if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) {
|
|
4922
|
+
throw new Error("pi_trusted_runtime_source_unsafe:seed_npm");
|
|
4923
|
+
}
|
|
4924
|
+
symlinkSync2(npmRoot, npmTarget, "dir");
|
|
4925
|
+
const facts = {
|
|
4926
|
+
schemaVersion: "amaster.trusted-pi-profile.v1",
|
|
4927
|
+
seedManifestDigest: input.verifiedAssertion.digests.seedManifestDigest,
|
|
4928
|
+
runtimeOverlayDigest: input.verifiedAssertion.digests.runtimeOverlayDigest,
|
|
4929
|
+
effectivePolicyDigest: input.verifiedAssertion.digests.effectivePolicyDigest,
|
|
4930
|
+
runtimeEnforcementDigest: input.verifiedAssertion.digests.runtimeEnforcementDigest,
|
|
4931
|
+
unknownToolMode: input.verifiedAssertion.unknownToolMode,
|
|
4932
|
+
directToolBudget: input.verifiedAssertion.directToolBudget,
|
|
4933
|
+
inheritedEntries: [...COPY_ENTRIES, ...JSON_ENTRIES, "mcp.json", "npm"]
|
|
4934
|
+
};
|
|
4935
|
+
return {
|
|
4936
|
+
facts,
|
|
4937
|
+
attestationId: createHash6("sha256").update(JSON.stringify(facts)).digest("hex")
|
|
4938
|
+
};
|
|
4939
|
+
}
|
|
4940
|
+
function assertAuditArgsRedacted(value) {
|
|
4941
|
+
if (Array.isArray(value)) {
|
|
4942
|
+
value.forEach(assertAuditArgsRedacted);
|
|
4943
|
+
return;
|
|
4944
|
+
}
|
|
4945
|
+
if (typeof value === "string") {
|
|
4946
|
+
if (SECRET_VALUE.test(value)) {
|
|
4947
|
+
throw new Error("pi_trusted_runtime_audit_secret_not_redacted");
|
|
4948
|
+
}
|
|
4949
|
+
return;
|
|
4950
|
+
}
|
|
4951
|
+
if (!value || typeof value !== "object") return;
|
|
4952
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
4953
|
+
if (SECRET_KEY.test(key) && entry !== "[redacted]") {
|
|
4954
|
+
throw new Error("pi_trusted_runtime_audit_secret_not_redacted");
|
|
4955
|
+
}
|
|
4956
|
+
assertAuditArgsRedacted(entry);
|
|
4957
|
+
}
|
|
4958
|
+
}
|
|
4959
|
+
function readTrustedPiRuntimeAudit(input) {
|
|
4960
|
+
const profileRoot = resolve8(requiredString2(input.profileRoot, "profileRoot"));
|
|
4961
|
+
const auditFile = resolve8(requiredString2(input.auditFile, "auditFile"));
|
|
4962
|
+
if (!within2(auditFile, profileRoot)) throw new Error("pi_trusted_runtime_audit_path_escape");
|
|
4963
|
+
if (!existsSync8(auditFile)) throw new Error("pi_trusted_runtime_audit_startup_missing");
|
|
4964
|
+
const stat = lstatSync5(auditFile);
|
|
4965
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4966
|
+
throw new Error("pi_trusted_runtime_audit_unsafe");
|
|
4967
|
+
}
|
|
4968
|
+
if (stat.size > MAX_AUDIT_BYTES) throw new Error("pi_trusted_runtime_audit_too_large");
|
|
4969
|
+
const lines = readFileSync6(auditFile, "utf8").split("\n").filter(Boolean);
|
|
4970
|
+
if (lines.length === 0 || lines.length > MAX_AUDIT_EVENTS) {
|
|
4971
|
+
throw new Error("pi_trusted_runtime_audit_event_count_invalid");
|
|
4972
|
+
}
|
|
4973
|
+
let decisions = 0;
|
|
4974
|
+
let outcomes = 0;
|
|
4975
|
+
let startupSeen = false;
|
|
4976
|
+
const decisionBySequence = /* @__PURE__ */ new Map();
|
|
4977
|
+
const outcomeSequences = /* @__PURE__ */ new Set();
|
|
4978
|
+
const events = lines.map((line) => {
|
|
4979
|
+
let event;
|
|
4980
|
+
try {
|
|
4981
|
+
event = JSON.parse(line);
|
|
4982
|
+
} catch {
|
|
4983
|
+
throw new Error("pi_trusted_runtime_audit_invalid_json");
|
|
4984
|
+
}
|
|
4985
|
+
if (event?.schemaVersion !== "amaster.managed-runtime-audit.v1" || event.commandId !== input.commandId || event.runId !== input.runId || !Number.isInteger(event.sequence) || event.sequence < 0) throw new Error("pi_trusted_runtime_audit_binding_mismatch");
|
|
4986
|
+
if (event.event === "decision") {
|
|
4987
|
+
decisions += 1;
|
|
4988
|
+
if (event.sequence !== decisions || decisionBySequence.has(event.sequence) || typeof event.toolCallId !== "string" || event.toolCallId === "" || typeof event.toolName !== "string" || event.toolName === "" || !["allow", "deny"].includes(event.decision)) {
|
|
4989
|
+
throw new Error("pi_trusted_runtime_audit_sequence_invalid");
|
|
4990
|
+
}
|
|
4991
|
+
decisionBySequence.set(event.sequence, event);
|
|
4992
|
+
assertAuditArgsRedacted(event.args);
|
|
4993
|
+
} else if (event.event === "outcome") {
|
|
4994
|
+
outcomes += 1;
|
|
4995
|
+
const decision = decisionBySequence.get(event.sequence);
|
|
4996
|
+
if (!decision || decision.decision !== "allow" || outcomeSequences.has(event.sequence) || event.toolCallId !== decision.toolCallId || event.toolName !== decision.toolName || !["success", "error"].includes(event.outcome)) {
|
|
4997
|
+
throw new Error("pi_trusted_runtime_audit_outcome_without_decision");
|
|
4998
|
+
}
|
|
4999
|
+
outcomeSequences.add(event.sequence);
|
|
5000
|
+
} else if (event.event !== "startup" || startupSeen || event.sequence !== 0 || event.assertionValid !== true || event.runtimeEnforcementDigest !== input.runtimeEnforcementDigest) {
|
|
5001
|
+
throw new Error("pi_trusted_runtime_audit_startup_invalid");
|
|
5002
|
+
}
|
|
5003
|
+
if (event.event === "startup") startupSeen = true;
|
|
5004
|
+
return event;
|
|
5005
|
+
});
|
|
5006
|
+
if (events[0]?.event !== "startup") throw new Error("pi_trusted_runtime_audit_startup_missing");
|
|
5007
|
+
return {
|
|
5008
|
+
schemaVersion: "amaster.managed-runtime-audit-summary.v1",
|
|
5009
|
+
decisionCount: decisions,
|
|
5010
|
+
outcomeCount: outcomes,
|
|
5011
|
+
deniedCount: events.filter((event) => event.event === "decision" && event.decision === "deny").length,
|
|
5012
|
+
maxSequence: decisions,
|
|
5013
|
+
events
|
|
5014
|
+
};
|
|
5015
|
+
}
|
|
5016
|
+
function readTrustedPiRuntimeLocalDigests(input) {
|
|
5017
|
+
const seedRoot = resolve8(requiredString2(input.seedRoot, "seedRoot"));
|
|
5018
|
+
const overlayRoot = resolve8(requiredString2(input.overlayRoot, "overlayRoot"));
|
|
5019
|
+
const policyFile = resolve8(requiredString2(input.policyFile, "policyFile"));
|
|
5020
|
+
for (const [path, label] of [[seedRoot, "seed_root"], [overlayRoot, "overlay_root"]]) {
|
|
5021
|
+
const stat = lstatSync5(path);
|
|
5022
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
5023
|
+
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
const seedManifestFile = join9(seedRoot, "seed-manifest.json");
|
|
5027
|
+
const overlayManifestFile = join9(overlayRoot, "runtime-overlay-manifest.json");
|
|
5028
|
+
const seedManifest = JSON.parse(readFileSync6(seedManifestFile, "utf8"));
|
|
5029
|
+
const overlayManifest = JSON.parse(readFileSync6(overlayManifestFile, "utf8"));
|
|
5030
|
+
const policyManifest = JSON.parse(readFileSync6(policyFile, "utf8"));
|
|
5031
|
+
verifyDeclaredFiles(seedManifest, seedRoot, "seed", ["seed-manifest.json"]);
|
|
5032
|
+
verifyDeclaredFiles(overlayManifest, overlayRoot, "overlay", ["runtime-overlay-manifest.json"]);
|
|
5033
|
+
verifyDeclaredFiles(
|
|
5034
|
+
policyManifest,
|
|
5035
|
+
dirname6(policyFile),
|
|
5036
|
+
"policy",
|
|
5037
|
+
[relative5(dirname6(policyFile), policyFile)],
|
|
5038
|
+
false
|
|
5039
|
+
);
|
|
5040
|
+
return {
|
|
5041
|
+
seedManifestDigest: sha256File(seedManifestFile, "seed_manifest"),
|
|
5042
|
+
runtimeOverlayDigest: sha256File(overlayManifestFile, "runtime_overlay_manifest"),
|
|
5043
|
+
effectivePolicyDigest: sha256File(policyFile, "effective_policy"),
|
|
5044
|
+
runtimeEnforcementDigest: requiredDigest(
|
|
5045
|
+
seedManifest.runtimeEnforcementDigest,
|
|
5046
|
+
"runtimeEnforcementDigest"
|
|
5047
|
+
)
|
|
5048
|
+
};
|
|
5049
|
+
}
|
|
5050
|
+
function createTrustedPiRuntimeProvenanceCache(input = {}) {
|
|
5051
|
+
const readDigests = input.readDigests ?? readTrustedPiRuntimeLocalDigests;
|
|
5052
|
+
let cachedKey = null;
|
|
5053
|
+
let cachedDigests = null;
|
|
5054
|
+
return {
|
|
5055
|
+
read(paths) {
|
|
5056
|
+
const key = JSON.stringify([
|
|
5057
|
+
paths.seedRoot,
|
|
5058
|
+
paths.overlayRoot,
|
|
5059
|
+
paths.policyFile
|
|
5060
|
+
]);
|
|
5061
|
+
if (cachedDigests && cachedKey === key) return cachedDigests;
|
|
5062
|
+
cachedDigests = readDigests(paths);
|
|
5063
|
+
cachedKey = key;
|
|
5064
|
+
return cachedDigests;
|
|
5065
|
+
}
|
|
5066
|
+
};
|
|
5067
|
+
}
|
|
5068
|
+
function verifyTrustedPiRuntimeAssertion(input) {
|
|
5069
|
+
const assertion = input.assertion;
|
|
5070
|
+
if (!assertion || typeof assertion !== "object" || Array.isArray(assertion)) {
|
|
5071
|
+
throw new Error("pi_trusted_runtime_assertion_missing");
|
|
5072
|
+
}
|
|
5073
|
+
if (assertion.version !== ASSERTION_VERSION) {
|
|
5074
|
+
throw new Error("pi_trusted_runtime_assertion_invalid:version");
|
|
5075
|
+
}
|
|
5076
|
+
const bindings = {
|
|
5077
|
+
connectorId: input.connectorId,
|
|
5078
|
+
commandId: input.commandId,
|
|
5079
|
+
runId: input.runId,
|
|
5080
|
+
leaseId: input.leaseId,
|
|
5081
|
+
executorKind: input.executorKind
|
|
5082
|
+
};
|
|
5083
|
+
requiredString2(assertion.attestationId, "attestationId");
|
|
5084
|
+
for (const [field, expected] of Object.entries(bindings)) {
|
|
5085
|
+
if (requiredString2(assertion[field], field) !== expected) {
|
|
5086
|
+
throw new Error(`pi_trusted_runtime_assertion_binding_mismatch:${field}`);
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
if (assertion.executorKind !== "pi") {
|
|
5090
|
+
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:executorKind");
|
|
5091
|
+
}
|
|
5092
|
+
const expiresAt = Date.parse(requiredString2(assertion.expiresAt, "expiresAt"));
|
|
5093
|
+
const now = input.now instanceof Date ? input.now : new Date(input.now ?? Date.now());
|
|
5094
|
+
if (!Number.isFinite(expiresAt) || input.verifyExpiry !== false && expiresAt <= now.getTime()) {
|
|
5095
|
+
throw new Error("pi_trusted_runtime_assertion_expired");
|
|
5096
|
+
}
|
|
5097
|
+
for (const field of [
|
|
5098
|
+
"seedManifestDigest",
|
|
5099
|
+
"runtimeOverlayDigest",
|
|
5100
|
+
"effectivePolicyDigest",
|
|
5101
|
+
"runtimeEnforcementDigest"
|
|
5102
|
+
]) {
|
|
5103
|
+
const asserted = requiredDigest(assertion[field], field);
|
|
5104
|
+
if (asserted !== requiredDigest(input.localDigests?.[field], field)) {
|
|
5105
|
+
throw new Error(`pi_trusted_runtime_digest_mismatch:${field}`);
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
if (!["deny", "allow_audited_bounded"].includes(assertion.unknownToolMode)) {
|
|
5109
|
+
throw new Error("pi_trusted_runtime_assertion_invalid:unknownToolMode");
|
|
5110
|
+
}
|
|
5111
|
+
const maxCalls = assertion.directToolBudget?.maxCalls;
|
|
5112
|
+
if (!Number.isInteger(maxCalls) || maxCalls < 0) {
|
|
5113
|
+
throw new Error("pi_trusted_runtime_assertion_invalid:directToolBudget.maxCalls");
|
|
5114
|
+
}
|
|
5115
|
+
if (assertion.unknownToolMode === "allow_audited_bounded" && maxCalls < 1) {
|
|
5116
|
+
throw new Error("pi_trusted_runtime_assertion_invalid:directToolBudget.maxCalls");
|
|
5117
|
+
}
|
|
5118
|
+
return {
|
|
5119
|
+
attestationId: assertion.attestationId,
|
|
5120
|
+
unknownToolMode: assertion.unknownToolMode,
|
|
5121
|
+
directToolBudget: { maxCalls },
|
|
5122
|
+
expiresAt: assertion.expiresAt,
|
|
5123
|
+
digests: { ...input.localDigests }
|
|
5124
|
+
};
|
|
5125
|
+
}
|
|
5126
|
+
|
|
4478
5127
|
// src/amaster-runtime-daemon/workspace-status.mjs
|
|
4479
5128
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
4480
|
-
import { createHash as
|
|
4481
|
-
import { existsSync as
|
|
4482
|
-
import { basename as basename5, extname, isAbsolute as
|
|
5129
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
5130
|
+
import { existsSync as existsSync9, readdirSync as readdirSync7, readFileSync as readFileSync7, statSync as statSync6 } from "node:fs";
|
|
5131
|
+
import { basename as basename5, extname, isAbsolute as isAbsolute6, join as join10, relative as relative6, resolve as resolve9 } from "node:path";
|
|
4483
5132
|
var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
|
|
4484
5133
|
var ARTIFACT_EXTENSIONS = /* @__PURE__ */ new Map([
|
|
4485
5134
|
[".md", "markdown"],
|
|
@@ -4524,11 +5173,11 @@ var SAFE_RUNTIME_SERVICE_STATUSES = /* @__PURE__ */ new Set(["starting", "runnin
|
|
|
4524
5173
|
var SAFE_RUNTIME_SERVICE_HEALTH_STATUSES = /* @__PURE__ */ new Set(["unknown", "healthy", "unhealthy"]);
|
|
4525
5174
|
var SAFE_RUNTIME_SERVICE_LIFECYCLES = /* @__PURE__ */ new Set(["shared", "ephemeral"]);
|
|
4526
5175
|
function statusPathWithin(candidate, root) {
|
|
4527
|
-
const rel =
|
|
4528
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5176
|
+
const rel = relative6(root, candidate);
|
|
5177
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
|
|
4529
5178
|
}
|
|
4530
5179
|
function normalizeRelativePath(root, filePath) {
|
|
4531
|
-
return
|
|
5180
|
+
return relative6(root, filePath).split(/[\\/]+/).join("/");
|
|
4532
5181
|
}
|
|
4533
5182
|
function isSafeRelativePath(value) {
|
|
4534
5183
|
const text = String(value ?? "").trim().split(/[\\/]+/).join("/");
|
|
@@ -4547,8 +5196,8 @@ function sanitizeTrackedChange(line) {
|
|
|
4547
5196
|
if (path === WORKSPACE_RUNTIME_SERVICES_FILENAME) return null;
|
|
4548
5197
|
return isSafeRelativePath(path) ? line : null;
|
|
4549
5198
|
}
|
|
4550
|
-
function
|
|
4551
|
-
return
|
|
5199
|
+
function sha256File2(filePath) {
|
|
5200
|
+
return createHash7("sha256").update(readFileSync7(filePath)).digest("hex");
|
|
4552
5201
|
}
|
|
4553
5202
|
function artifactHashCacheKey(relativePath, stat) {
|
|
4554
5203
|
return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
|
|
@@ -4562,7 +5211,7 @@ function artifactSha256(filePath, relativePath, stat, opts = {}) {
|
|
|
4562
5211
|
cache.set(key, cached);
|
|
4563
5212
|
return cached;
|
|
4564
5213
|
}
|
|
4565
|
-
const hashFile = typeof opts.hashFile === "function" ? opts.hashFile :
|
|
5214
|
+
const hashFile = typeof opts.hashFile === "function" ? opts.hashFile : sha256File2;
|
|
4566
5215
|
const hash = hashFile(filePath);
|
|
4567
5216
|
if (cache) {
|
|
4568
5217
|
cache.set(key, hash);
|
|
@@ -4576,7 +5225,7 @@ function artifactSha256(filePath, relativePath, stat, opts = {}) {
|
|
|
4576
5225
|
return hash;
|
|
4577
5226
|
}
|
|
4578
5227
|
function scanArtifactCandidates(cwd, opts = {}) {
|
|
4579
|
-
const root =
|
|
5228
|
+
const root = resolve9(cwd);
|
|
4580
5229
|
const maxCandidates = opts.maxCandidates ?? MAX_CANDIDATES;
|
|
4581
5230
|
const maxEntries = opts.maxEntries ?? MAX_SCAN_ENTRIES;
|
|
4582
5231
|
const candidates = [];
|
|
@@ -4586,7 +5235,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
|
|
|
4586
5235
|
const current = stack.pop();
|
|
4587
5236
|
let entries;
|
|
4588
5237
|
try {
|
|
4589
|
-
entries =
|
|
5238
|
+
entries = readdirSync7(current, { withFileTypes: true });
|
|
4590
5239
|
} catch {
|
|
4591
5240
|
continue;
|
|
4592
5241
|
}
|
|
@@ -4597,7 +5246,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
|
|
|
4597
5246
|
if (entry.name.startsWith(".") && entry.name !== ".amaster-runtime.json") {
|
|
4598
5247
|
if (entry.name === ".git") continue;
|
|
4599
5248
|
}
|
|
4600
|
-
const fullPath =
|
|
5249
|
+
const fullPath = join10(current, entry.name);
|
|
4601
5250
|
const relativePath = normalizeRelativePath(root, fullPath);
|
|
4602
5251
|
if (!isSafeRelativePath(relativePath)) continue;
|
|
4603
5252
|
if (basename5(relativePath) === ".amaster-runtime.json") continue;
|
|
@@ -4616,7 +5265,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
|
|
|
4616
5265
|
} catch {
|
|
4617
5266
|
continue;
|
|
4618
5267
|
}
|
|
4619
|
-
if (!statusPathWithin(
|
|
5268
|
+
if (!statusPathWithin(resolve9(fullPath), root) || stat.size > MAX_HASH_BYTES) continue;
|
|
4620
5269
|
candidates.push({
|
|
4621
5270
|
relativePath,
|
|
4622
5271
|
name: basename5(fullPath),
|
|
@@ -4676,10 +5325,10 @@ function sanitizeRuntimeService(entry) {
|
|
|
4676
5325
|
};
|
|
4677
5326
|
}
|
|
4678
5327
|
function readRuntimeServicesSnapshot(cwd) {
|
|
4679
|
-
const snapshotPath =
|
|
4680
|
-
if (!
|
|
5328
|
+
const snapshotPath = join10(resolve9(cwd), WORKSPACE_RUNTIME_SERVICES_FILENAME);
|
|
5329
|
+
if (!existsSync9(snapshotPath)) return [];
|
|
4681
5330
|
try {
|
|
4682
|
-
const parsed = JSON.parse(
|
|
5331
|
+
const parsed = JSON.parse(readFileSync7(snapshotPath, "utf8"));
|
|
4683
5332
|
const rawServices = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.services) ? parsed.services : [];
|
|
4684
5333
|
return rawServices.map((entry) => sanitizeRuntimeService(entry)).filter((entry) => entry !== null).slice(0, 50);
|
|
4685
5334
|
} catch {
|
|
@@ -4750,7 +5399,7 @@ function readWorkspaceStatus(cwd, opts = {}) {
|
|
|
4750
5399
|
}
|
|
4751
5400
|
|
|
4752
5401
|
// src/amaster-runtime-daemon.mjs
|
|
4753
|
-
var CONNECTOR_VERSION = "0.1.0-beta.
|
|
5402
|
+
var CONNECTOR_VERSION = "0.1.0-beta.32";
|
|
4754
5403
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
4755
5404
|
var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
|
|
4756
5405
|
var CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -4771,6 +5420,24 @@ var processGroupRssSampleCache = null;
|
|
|
4771
5420
|
var lastOrphanReaperRunAtMs = 0;
|
|
4772
5421
|
var lastOrphanReaperSummary = null;
|
|
4773
5422
|
var activeRunManifestOutputFlusher = createManifestOutputFlusher({ updateWorkspaceManifest });
|
|
5423
|
+
var piChildIdentityAllocator = null;
|
|
5424
|
+
var piChildIdentityAllocatorKey = null;
|
|
5425
|
+
var trustedPiRuntimeProvenanceCache = createTrustedPiRuntimeProvenanceCache();
|
|
5426
|
+
function configuredPiChildIdentityAllocator(config) {
|
|
5427
|
+
if (!(config.piChildUidBase > 0)) return null;
|
|
5428
|
+
const key = `${config.piChildUidBase}:${config.piChildUidSpan}`;
|
|
5429
|
+
if (!piChildIdentityAllocator || piChildIdentityAllocatorKey !== key) {
|
|
5430
|
+
if (piChildIdentityAllocator?.activeAssignments().length > 0) {
|
|
5431
|
+
throw new Error("pi_child_isolation_config_changed_with_active_runs");
|
|
5432
|
+
}
|
|
5433
|
+
piChildIdentityAllocator = createPiChildIdentityAllocator({
|
|
5434
|
+
uidBase: config.piChildUidBase,
|
|
5435
|
+
uidSpan: config.piChildUidSpan
|
|
5436
|
+
});
|
|
5437
|
+
piChildIdentityAllocatorKey = key;
|
|
5438
|
+
}
|
|
5439
|
+
return piChildIdentityAllocator;
|
|
5440
|
+
}
|
|
4774
5441
|
function mergeActiveRunManifestPatch(commandId, patch = {}) {
|
|
4775
5442
|
return activeRunManifestOutputFlusher.mergePendingPatch(commandId, patch);
|
|
4776
5443
|
}
|
|
@@ -4779,11 +5446,11 @@ function updateActiveRunWorkspaceManifest(commandId, manifestPath, patch = {}) {
|
|
|
4779
5446
|
}
|
|
4780
5447
|
function resultOutboxPendingCount(config) {
|
|
4781
5448
|
const dir = resultOutboxDir(config);
|
|
4782
|
-
if (!
|
|
5449
|
+
if (!existsSync10(dir)) return 0;
|
|
4783
5450
|
try {
|
|
4784
5451
|
let pending = 0;
|
|
4785
|
-
for (const file of
|
|
4786
|
-
if (readValidResultOutboxEntryOrQuarantine(config, file,
|
|
5452
|
+
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json"))) {
|
|
5453
|
+
if (readValidResultOutboxEntryOrQuarantine(config, file, join11(dir, file))) {
|
|
4787
5454
|
pending += 1;
|
|
4788
5455
|
}
|
|
4789
5456
|
}
|
|
@@ -4799,11 +5466,11 @@ function piCompletionOutputType(event) {
|
|
|
4799
5466
|
}
|
|
4800
5467
|
function resultOutboxActiveRunCommands(config) {
|
|
4801
5468
|
const dir = resultOutboxDir(config);
|
|
4802
|
-
if (!
|
|
5469
|
+
if (!existsSync10(dir)) return [];
|
|
4803
5470
|
const outboxPending = resultOutboxPendingCount(config);
|
|
4804
5471
|
const entries = [];
|
|
4805
|
-
for (const file of
|
|
4806
|
-
const entry = readValidResultOutboxEntryOrQuarantine(config, file,
|
|
5472
|
+
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort()) {
|
|
5473
|
+
const entry = readValidResultOutboxEntryOrQuarantine(config, file, join11(dir, file));
|
|
4807
5474
|
if (!entry) continue;
|
|
4808
5475
|
const activeRun = asRecord(entry.activeRun);
|
|
4809
5476
|
const commandId = readString(activeRun.commandId) ?? readString(entry.commandId);
|
|
@@ -4833,12 +5500,12 @@ function resultOutboxActiveRunCommands(config) {
|
|
|
4833
5500
|
}
|
|
4834
5501
|
function resultOutboxFailedRunCommands(config) {
|
|
4835
5502
|
const dir = resultOutboxInvalidDir(config);
|
|
4836
|
-
if (!
|
|
5503
|
+
if (!existsSync10(dir)) return [];
|
|
4837
5504
|
const entries = [];
|
|
4838
|
-
for (const file of
|
|
5505
|
+
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort().slice(-100)) {
|
|
4839
5506
|
let entry;
|
|
4840
5507
|
try {
|
|
4841
|
-
entry = asRecord(JSON.parse(
|
|
5508
|
+
entry = asRecord(JSON.parse(readFileSync8(join11(dir, file), "utf8")));
|
|
4842
5509
|
} catch {
|
|
4843
5510
|
continue;
|
|
4844
5511
|
}
|
|
@@ -4898,11 +5565,11 @@ function piExtraArgsDiagnostics(value) {
|
|
|
4898
5565
|
}
|
|
4899
5566
|
function safeExpandPath(value) {
|
|
4900
5567
|
const text = readString(value);
|
|
4901
|
-
return text ?
|
|
5568
|
+
return text ? resolve10(expandHomePath(text)) : null;
|
|
4902
5569
|
}
|
|
4903
5570
|
function safeJsonObjectFromFile(filePath) {
|
|
4904
5571
|
try {
|
|
4905
|
-
const parsed = JSON.parse(
|
|
5572
|
+
const parsed = JSON.parse(readFileSync8(filePath, "utf8"));
|
|
4906
5573
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
4907
5574
|
} catch {
|
|
4908
5575
|
return null;
|
|
@@ -4919,7 +5586,7 @@ function safeDirectorySummary(pathValue) {
|
|
|
4919
5586
|
}
|
|
4920
5587
|
let entryCount = 0;
|
|
4921
5588
|
let truncated = false;
|
|
4922
|
-
for (const name of
|
|
5589
|
+
for (const name of readdirSync8(pathValue)) {
|
|
4923
5590
|
if (name.startsWith(".")) continue;
|
|
4924
5591
|
entryCount += 1;
|
|
4925
5592
|
if (entryCount >= MAX_PI_CAPABILITY_SOURCE_ENTRIES) {
|
|
@@ -4943,12 +5610,12 @@ function safeSkillRootSummary(kind, source, pathValue) {
|
|
|
4943
5610
|
let truncated = false;
|
|
4944
5611
|
if (directory.available && pathValue) {
|
|
4945
5612
|
try {
|
|
4946
|
-
for (const name of
|
|
5613
|
+
for (const name of readdirSync8(pathValue)) {
|
|
4947
5614
|
if (name.startsWith(".")) continue;
|
|
4948
|
-
const skillDir =
|
|
5615
|
+
const skillDir = join11(pathValue, name);
|
|
4949
5616
|
try {
|
|
4950
5617
|
if (!statSync7(skillDir).isDirectory()) continue;
|
|
4951
|
-
if (!
|
|
5618
|
+
if (!existsSync10(join11(skillDir, "SKILL.md"))) continue;
|
|
4952
5619
|
skillCount += 1;
|
|
4953
5620
|
if (skillCount >= MAX_PI_CAPABILITY_SOURCE_ENTRIES) {
|
|
4954
5621
|
truncated = true;
|
|
@@ -4999,7 +5666,7 @@ function objectKeyCount(value) {
|
|
|
4999
5666
|
return value && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).length : 0;
|
|
5000
5667
|
}
|
|
5001
5668
|
function defaultPiCodingAgentDir() {
|
|
5002
|
-
return
|
|
5669
|
+
return join11(homedir3(), ".pi", "agent");
|
|
5003
5670
|
}
|
|
5004
5671
|
function piCapabilitySourcesDiagnostics() {
|
|
5005
5672
|
const configuredPiCodingAgentDir = safeExpandPath(process.env.PI_CODING_AGENT_DIR);
|
|
@@ -5008,11 +5675,11 @@ function piCapabilitySourcesDiagnostics() {
|
|
|
5008
5675
|
const configuredPiAgentHome = safeExpandPath(process.env.PI_AGENT_HOME);
|
|
5009
5676
|
const piAgentHome = configuredPiAgentHome ?? piCodingAgentDir;
|
|
5010
5677
|
const piAgentHomeSource = configuredPiAgentHome ? "PI_AGENT_HOME" : piCodingAgentDirSource;
|
|
5011
|
-
const userSkillsPath = piAgentHome ?
|
|
5012
|
-
const marketplaceSkillsPath = safeExpandPath(process.env.PI_AGENT_MARKETPLACE_SKILLS_DIR) ?? (piAgentHome ?
|
|
5678
|
+
const userSkillsPath = piAgentHome ? join11(piAgentHome, "skills") : null;
|
|
5679
|
+
const marketplaceSkillsPath = safeExpandPath(process.env.PI_AGENT_MARKETPLACE_SKILLS_DIR) ?? (piAgentHome ? join11(piAgentHome, "marketplace", "skills") : null);
|
|
5013
5680
|
const builtinSkillsPath = safeExpandPath(process.env.PI_AGENT_BUILTIN_SKILLS_DIR) ?? safeExpandPath(process.env.AMASTER_BUILTIN_SKILLS);
|
|
5014
|
-
const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ?
|
|
5015
|
-
const settingsConfigPath = piCodingAgentDir ?
|
|
5681
|
+
const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ? join11(piAgentHome, "mcp.json") : null);
|
|
5682
|
+
const settingsConfigPath = piCodingAgentDir ? join11(piCodingAgentDir, "settings.json") : null;
|
|
5016
5683
|
const skillRoots = [
|
|
5017
5684
|
safeSkillRootSummary("user", `${piAgentHomeSource}/skills`, userSkillsPath),
|
|
5018
5685
|
safeSkillRootSummary(
|
|
@@ -5127,6 +5794,16 @@ function executorReadinessFor(config, executor) {
|
|
|
5127
5794
|
function buildExecutorReadiness(config) {
|
|
5128
5795
|
return config.executors.filter((executor) => executor.kind === "codex" || executor.kind === "pi").map((executor) => executorReadinessFor(config, executor));
|
|
5129
5796
|
}
|
|
5797
|
+
function trustedPiRuntimeProvenancePayload(config) {
|
|
5798
|
+
const configured = [
|
|
5799
|
+
config.piRuntimeSeedRoot,
|
|
5800
|
+
config.piRuntimeOverlayRoot,
|
|
5801
|
+
config.piRuntimeEffectivePolicyFile
|
|
5802
|
+
].filter(Boolean).length;
|
|
5803
|
+
if (configured === 0) return {};
|
|
5804
|
+
if (configured !== 3) throw new Error("pi_trusted_runtime_source_config_missing");
|
|
5805
|
+
return trustedPiRuntimeProvenanceCache.read(trustedPiRuntimeSources(config));
|
|
5806
|
+
}
|
|
5130
5807
|
function buildRegisterPayload(config) {
|
|
5131
5808
|
const buildCommit = readString(process.env.AMASTER_RUNTIME_BUILD_COMMIT ?? process.env.AMASTER_SOURCE_COMMIT);
|
|
5132
5809
|
return {
|
|
@@ -5190,6 +5867,7 @@ function buildHeartbeatPayload(config, options = {}) {
|
|
|
5190
5867
|
contractVersion: CONNECTOR_CONTRACT_VERSION,
|
|
5191
5868
|
platform: process.platform,
|
|
5192
5869
|
arch: process.arch,
|
|
5870
|
+
...trustedPiRuntimeProvenancePayload(config),
|
|
5193
5871
|
runtimeStatus: {
|
|
5194
5872
|
daemon: "running",
|
|
5195
5873
|
pid: process.pid,
|
|
@@ -5217,13 +5895,13 @@ function piAgentLocalPlatformRunnerEnabled(config) {
|
|
|
5217
5895
|
}
|
|
5218
5896
|
function piAgentSystemDataDir(config) {
|
|
5219
5897
|
const configured = readString(config.AMASTER_PI_AGENT_SYSTEM_DATA_DIR ?? process.env.AMASTER_PI_AGENT_SYSTEM_DATA_DIR);
|
|
5220
|
-
return configured ?
|
|
5898
|
+
return configured ? resolve10(expandHomePath(configured)) : null;
|
|
5221
5899
|
}
|
|
5222
5900
|
function readPiAgentLocalPlatformCredential(credentialsDir) {
|
|
5223
|
-
const pointer =
|
|
5901
|
+
const pointer = readJsonFile2(join11(credentialsDir, "latest.json"));
|
|
5224
5902
|
const credentialRef = readString(pointer.credentialRef);
|
|
5225
5903
|
if (!credentialRef || !/^[a-f0-9]{64}$/i.test(credentialRef)) return null;
|
|
5226
|
-
const credential =
|
|
5904
|
+
const credential = readJsonFile2(join11(credentialsDir, `${credentialRef}.json`));
|
|
5227
5905
|
const organizationId = readString(credential.organizationId);
|
|
5228
5906
|
const apiKey = readString(credential.apiKey);
|
|
5229
5907
|
if (credential.version !== 1 || !organizationId || !apiKey) return null;
|
|
@@ -5239,17 +5917,17 @@ function piAgentLocalPlatformCredentials(config) {
|
|
|
5239
5917
|
if (!piAgentLocalPlatformRunnerEnabled(config)) return [];
|
|
5240
5918
|
const systemDataDir = piAgentSystemDataDir(config);
|
|
5241
5919
|
if (!systemDataDir) return [];
|
|
5242
|
-
const companiesDir =
|
|
5920
|
+
const companiesDir = join11(systemDataDir, "companies");
|
|
5243
5921
|
let entries = [];
|
|
5244
5922
|
try {
|
|
5245
|
-
entries =
|
|
5923
|
+
entries = readdirSync8(companiesDir, { withFileTypes: true });
|
|
5246
5924
|
} catch {
|
|
5247
5925
|
return [];
|
|
5248
5926
|
}
|
|
5249
5927
|
const credentialsByOrganizationId = /* @__PURE__ */ new Map();
|
|
5250
5928
|
for (const entry of entries) {
|
|
5251
5929
|
if (!entry.isDirectory()) continue;
|
|
5252
|
-
const credential = readPiAgentLocalPlatformCredential(
|
|
5930
|
+
const credential = readPiAgentLocalPlatformCredential(join11(companiesDir, entry.name, "model-credentials"));
|
|
5253
5931
|
if (credential) credentialsByOrganizationId.set(credential.organizationId, credential);
|
|
5254
5932
|
}
|
|
5255
5933
|
return [...credentialsByOrganizationId.values()];
|
|
@@ -5423,7 +6101,7 @@ AMASTER_WORKSPACE_ALLOWLIST=${quoteShell(config.workspaceBindings.join(","))}
|
|
|
5423
6101
|
AMASTER_EXECUTORS=${quoteShell(executorEnv)}
|
|
5424
6102
|
AMASTER_CAPABILITIES=${quoteShell(config.capabilities.join(","))}
|
|
5425
6103
|
AMASTER_NETWORK_DOMAINS=${quoteShell(config.networkDomains.join(","))}
|
|
5426
|
-
AMASTER_DAEMON_STATE_FILE=${quoteShell(
|
|
6104
|
+
AMASTER_DAEMON_STATE_FILE=${quoteShell(join11(homedir3(), ".amaster-employee", "runtime-connector-state.json"))}
|
|
5427
6105
|
EOF
|
|
5428
6106
|
|
|
5429
6107
|
set -a
|
|
@@ -5611,10 +6289,10 @@ function buildActiveRunCommandStatus(config, entry) {
|
|
|
5611
6289
|
const base = {
|
|
5612
6290
|
...entry,
|
|
5613
6291
|
phase: readString(entry.phase) ?? "executing",
|
|
5614
|
-
managedWorkdirPresent: entry.workspacePath ?
|
|
6292
|
+
managedWorkdirPresent: entry.workspacePath ? existsSync10(entry.workspacePath) : false,
|
|
5615
6293
|
outboxPending: resultOutboxPendingCount(config)
|
|
5616
6294
|
};
|
|
5617
|
-
if (!entry.workspacePath || !
|
|
6295
|
+
if (!entry.workspacePath || !existsSync10(entry.workspacePath)) return base;
|
|
5618
6296
|
const manifestPath = entry.manifestPath ?? workspaceManifestPath(entry.workspacePath);
|
|
5619
6297
|
const status = readWorkspaceStatus(entry.workspacePath, { hashCache: workspaceStatusHashCache });
|
|
5620
6298
|
const artifactCandidates = status.artifacts.slice(0, 20);
|
|
@@ -5778,18 +6456,33 @@ function commandExecutorEnv(command) {
|
|
|
5778
6456
|
...normalizeExecutorEnvValue(command.executorEnv)
|
|
5779
6457
|
};
|
|
5780
6458
|
}
|
|
5781
|
-
function
|
|
6459
|
+
function commandTrustedPiRuntimeAssertion(command) {
|
|
6460
|
+
const topLevel = asRecord(command.trustedPiRuntime);
|
|
6461
|
+
if (Object.keys(topLevel).length > 0) return topLevel;
|
|
6462
|
+
return asRecord(asRecord(command.payload).trustedPiRuntime);
|
|
6463
|
+
}
|
|
6464
|
+
function trustedPiRuntimeSources(config) {
|
|
6465
|
+
if (!config.piRuntimeSeedRoot || !config.piRuntimeOverlayRoot || !config.piRuntimeEffectivePolicyFile) {
|
|
6466
|
+
throw new Error("pi_trusted_runtime_source_config_missing");
|
|
6467
|
+
}
|
|
6468
|
+
return {
|
|
6469
|
+
seedRoot: config.piRuntimeSeedRoot,
|
|
6470
|
+
overlayRoot: config.piRuntimeOverlayRoot,
|
|
6471
|
+
policyFile: config.piRuntimeEffectivePolicyFile
|
|
6472
|
+
};
|
|
6473
|
+
}
|
|
6474
|
+
function readJsonFile2(filePath) {
|
|
5782
6475
|
try {
|
|
5783
|
-
const parsed = JSON.parse(
|
|
6476
|
+
const parsed = JSON.parse(readFileSync8(filePath, "utf8"));
|
|
5784
6477
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
5785
6478
|
} catch {
|
|
5786
6479
|
return {};
|
|
5787
6480
|
}
|
|
5788
6481
|
}
|
|
5789
6482
|
function writeJsonFileAtomic(filePath, value) {
|
|
5790
|
-
|
|
6483
|
+
mkdirSync6(dirname7(filePath), { recursive: true });
|
|
5791
6484
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
5792
|
-
|
|
6485
|
+
writeFileSync6(tmpPath, `${JSON.stringify(value, null, 2)}
|
|
5793
6486
|
`, { mode: 384 });
|
|
5794
6487
|
renameSync3(tmpPath, filePath);
|
|
5795
6488
|
}
|
|
@@ -5835,8 +6528,8 @@ function ensureAmasterProviderModel(models, modelId, flash) {
|
|
|
5835
6528
|
function syncAmasterProviderModels(agentDir, executorEnv) {
|
|
5836
6529
|
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
5837
6530
|
if (!apiKey) return false;
|
|
5838
|
-
const modelsPath =
|
|
5839
|
-
const config =
|
|
6531
|
+
const modelsPath = join11(agentDir, "models.json");
|
|
6532
|
+
const config = readJsonFile2(modelsPath);
|
|
5840
6533
|
const providers = asRecord(config.providers);
|
|
5841
6534
|
const amaster = { ...asRecord(providers.amaster) };
|
|
5842
6535
|
amaster.apiKey = apiKey;
|
|
@@ -5859,9 +6552,9 @@ function syncAmasterProviderModels(agentDir, executorEnv) {
|
|
|
5859
6552
|
function syncAmasterProviderSettings(agentDir, executorEnv) {
|
|
5860
6553
|
const apiKey = readString(executorEnv.AMASTER_API_KEY);
|
|
5861
6554
|
if (!apiKey) return false;
|
|
5862
|
-
const settingsPath =
|
|
5863
|
-
if (!
|
|
5864
|
-
const settings =
|
|
6555
|
+
const settingsPath = join11(agentDir, "settings.json");
|
|
6556
|
+
if (!existsSync10(settingsPath)) return false;
|
|
6557
|
+
const settings = readJsonFile2(settingsPath);
|
|
5865
6558
|
const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
|
|
5866
6559
|
const defaultModel = readString(executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL);
|
|
5867
6560
|
const imageGenBaseUrl = imageGenBaseUrlFromProviderBaseUrl(baseUrl);
|
|
@@ -5987,11 +6680,11 @@ function safeAgentInstructionMaterializationTarget(workspace, filePath) {
|
|
|
5987
6680
|
const raw = readString(filePath);
|
|
5988
6681
|
if (!raw || raw.includes("\0")) return null;
|
|
5989
6682
|
const normalized = raw.replace(/\\/g, "/");
|
|
5990
|
-
if (
|
|
6683
|
+
if (isAbsolute7(normalized)) return null;
|
|
5991
6684
|
const segments = normalized.split("/").filter(Boolean);
|
|
5992
6685
|
if (segments.length === 0 || segments.some((segment) => segment === "." || segment === "..")) return null;
|
|
5993
6686
|
const relativePath = segments.join("/");
|
|
5994
|
-
const targetPath =
|
|
6687
|
+
const targetPath = resolve10(workspace.cwd, relativePath);
|
|
5995
6688
|
if (!pathWithin2(targetPath, workspace.cwd)) return null;
|
|
5996
6689
|
return { relativePath, targetPath };
|
|
5997
6690
|
}
|
|
@@ -6005,8 +6698,8 @@ async function materializeAgentInstructionsBundle(config, command, workspace) {
|
|
|
6005
6698
|
if (!content) continue;
|
|
6006
6699
|
const target = safeAgentInstructionMaterializationTarget(workspace, filePath);
|
|
6007
6700
|
if (!target) continue;
|
|
6008
|
-
|
|
6009
|
-
|
|
6701
|
+
mkdirSync6(dirname7(target.targetPath), { recursive: true });
|
|
6702
|
+
writeFileSync6(target.targetPath, content, "utf8");
|
|
6010
6703
|
materialized.push({
|
|
6011
6704
|
path: target.relativePath,
|
|
6012
6705
|
byteSize: Buffer.byteLength(content, "utf8")
|
|
@@ -6075,20 +6768,20 @@ function safeCompanyPiHomeSegment(companyId) {
|
|
|
6075
6768
|
if (!raw) return null;
|
|
6076
6769
|
if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(raw)) return raw;
|
|
6077
6770
|
const normalized = raw.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
6078
|
-
const hash =
|
|
6771
|
+
const hash = createHash8("sha256").update(raw).digest("hex").slice(0, 12);
|
|
6079
6772
|
return normalized ? `${normalized}-${hash}` : `company-${hash}`;
|
|
6080
6773
|
}
|
|
6081
6774
|
function companyPiHomeRoot(baseEnv) {
|
|
6082
6775
|
const explicitRoot = readString(baseEnv.AMASTER_COMPANY_PI_HOME_ROOT);
|
|
6083
|
-
if (explicitRoot) return
|
|
6776
|
+
if (explicitRoot) return resolve10(expandHomePath(explicitRoot));
|
|
6084
6777
|
const configuredPiHome = readString(baseEnv.PI_AGENT_HOME) ?? readString(baseEnv.PI_CODING_AGENT_DIR);
|
|
6085
|
-
if (configuredPiHome) return
|
|
6086
|
-
return
|
|
6778
|
+
if (configuredPiHome) return join11(dirname7(resolve10(expandHomePath(configuredPiHome))), "companies");
|
|
6779
|
+
return join11(homedir3(), ".amaster-employee", "companies");
|
|
6087
6780
|
}
|
|
6088
6781
|
function companyPiAgentHome(baseEnv, companyId) {
|
|
6089
6782
|
const segment = safeCompanyPiHomeSegment(companyId);
|
|
6090
6783
|
if (!segment) return null;
|
|
6091
|
-
return
|
|
6784
|
+
return join11(companyPiHomeRoot(baseEnv), segment, ".pi");
|
|
6092
6785
|
}
|
|
6093
6786
|
function commandUsesPiExecutor(command) {
|
|
6094
6787
|
return readString(asRecord(command.payload).executorKind) === "pi";
|
|
@@ -6157,7 +6850,7 @@ function resolveNativeSessionRequest(command, workspace) {
|
|
|
6157
6850
|
try {
|
|
6158
6851
|
cwdMatched = realpathSync3(requestedCwd) === realpathSync3(sourceWorkspacePath);
|
|
6159
6852
|
} catch {
|
|
6160
|
-
cwdMatched =
|
|
6853
|
+
cwdMatched = resolve10(requestedCwd) === resolve10(sourceWorkspacePath);
|
|
6161
6854
|
}
|
|
6162
6855
|
}
|
|
6163
6856
|
const used = Boolean(enabled && requested && sessionId && requestedCwd && cwdMatched);
|
|
@@ -6584,10 +7277,10 @@ function realOrResolvedPath(value) {
|
|
|
6584
7277
|
try {
|
|
6585
7278
|
return realpathSync3(value);
|
|
6586
7279
|
} catch {
|
|
6587
|
-
return
|
|
7280
|
+
return resolve10(value);
|
|
6588
7281
|
}
|
|
6589
7282
|
}
|
|
6590
|
-
var LSOF_COMMAND = process.platform === "darwin" &&
|
|
7283
|
+
var LSOF_COMMAND = process.platform === "darwin" && existsSync10("/usr/sbin/lsof") ? "/usr/sbin/lsof" : "lsof";
|
|
6591
7284
|
function processCwdForPid(pid) {
|
|
6592
7285
|
if (process.platform === "linux") {
|
|
6593
7286
|
try {
|
|
@@ -6613,7 +7306,7 @@ function allProcessCwdsByPid() {
|
|
|
6613
7306
|
if (process.platform === "linux") {
|
|
6614
7307
|
const procEntries = (() => {
|
|
6615
7308
|
try {
|
|
6616
|
-
return
|
|
7309
|
+
return readdirSync8("/proc", { withFileTypes: true });
|
|
6617
7310
|
} catch {
|
|
6618
7311
|
return [];
|
|
6619
7312
|
}
|
|
@@ -6709,21 +7402,21 @@ function killWorkspaceResidentProcesses(cwd, processGroupId, options = {}) {
|
|
|
6709
7402
|
}
|
|
6710
7403
|
function walkManagedWorkdirs(root) {
|
|
6711
7404
|
const workdirs = [];
|
|
6712
|
-
if (!root || !
|
|
7405
|
+
if (!root || !existsSync10(root)) return workdirs;
|
|
6713
7406
|
const stack = [root];
|
|
6714
7407
|
while (stack.length > 0) {
|
|
6715
7408
|
const current = stack.pop();
|
|
6716
7409
|
if (!current) continue;
|
|
6717
7410
|
let entries = [];
|
|
6718
7411
|
try {
|
|
6719
|
-
entries =
|
|
7412
|
+
entries = readdirSync8(current, { withFileTypes: true });
|
|
6720
7413
|
} catch {
|
|
6721
7414
|
continue;
|
|
6722
7415
|
}
|
|
6723
7416
|
for (const entry of entries) {
|
|
6724
7417
|
if (!entry.isDirectory()) continue;
|
|
6725
|
-
const fullPath =
|
|
6726
|
-
if (entry.name === "workdir" &&
|
|
7418
|
+
const fullPath = join11(current, entry.name);
|
|
7419
|
+
if (entry.name === "workdir" && existsSync10(workspaceManifestPath(fullPath))) {
|
|
6727
7420
|
workdirs.push(fullPath);
|
|
6728
7421
|
continue;
|
|
6729
7422
|
}
|
|
@@ -6761,8 +7454,8 @@ function manifestMatchesActiveRuntimeRef(manifest, refs, workdir = null) {
|
|
|
6761
7454
|
}
|
|
6762
7455
|
function buildOrphanReaperSample(root, workdir, manifest, residents) {
|
|
6763
7456
|
const relativeWorkdir = (() => {
|
|
6764
|
-
const value =
|
|
6765
|
-
return value && !value.startsWith("..") && !
|
|
7457
|
+
const value = relative7(root, workdir);
|
|
7458
|
+
return value && !value.startsWith("..") && !isAbsolute7(value) ? value : basename6(workdir);
|
|
6766
7459
|
})();
|
|
6767
7460
|
return {
|
|
6768
7461
|
workdir: relativeWorkdir,
|
|
@@ -6869,7 +7562,8 @@ function runExecutor(command, args, options) {
|
|
|
6869
7562
|
cwd: options.cwd,
|
|
6870
7563
|
env: options.env,
|
|
6871
7564
|
detached: process.platform !== "win32",
|
|
6872
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
7565
|
+
stdio: options.managedInput ? ["pipe", "pipe", "pipe", "pipe"] : ["pipe", "pipe", "pipe"],
|
|
7566
|
+
...options.spawnIdentity ?? {}
|
|
6873
7567
|
});
|
|
6874
7568
|
const processGroupId = processGroupIdForChild(child);
|
|
6875
7569
|
const finish = (result2) => {
|
|
@@ -6904,6 +7598,13 @@ function runExecutor(command, args, options) {
|
|
|
6904
7598
|
signalExecutorProcess(child, "SIGTERM", processGroupId);
|
|
6905
7599
|
scheduleStopKill();
|
|
6906
7600
|
};
|
|
7601
|
+
if (options.managedInput) {
|
|
7602
|
+
child.stdio[3].once("error", (error) => {
|
|
7603
|
+
spawnError = `managed_runtime_assertion_delivery_failed: ${error.message}`;
|
|
7604
|
+
requestStop("managed_runtime_assertion_delivery_failed");
|
|
7605
|
+
});
|
|
7606
|
+
child.stdio[3].end(options.managedInput);
|
|
7607
|
+
}
|
|
6907
7608
|
const reapStoppedWorkspaceResidents = () => {
|
|
6908
7609
|
if (settled || !stopReason || stopReason === "completion_cleanup") return;
|
|
6909
7610
|
const residents = listWorkspaceResidentProcesses(options.cwd, processGroupId, {
|
|
@@ -7146,12 +7847,16 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
|
|
|
7146
7847
|
const receipts = [];
|
|
7147
7848
|
for (const upload of uploads) {
|
|
7148
7849
|
const path = `/api/amaster/runtime-connectors/${connectorId}/artifact-intents/${encodeURIComponent(upload.intentId)}/ingest`;
|
|
7850
|
+
const sourcePathHeaders = /^[\x20-\x7e]+$/.test(upload.sourceRelativePath) ? { "x-amaster-artifact-source-path": upload.sourceRelativePath } : {
|
|
7851
|
+
"x-amaster-artifact-source-path": encodeURIComponent(upload.sourceRelativePath),
|
|
7852
|
+
"x-amaster-artifact-source-path-encoding": "uri-component"
|
|
7853
|
+
};
|
|
7149
7854
|
try {
|
|
7150
7855
|
const receipt = asRecord(await postRuntimeConnectorBytes(config, path, upload.body, {
|
|
7151
7856
|
"x-amaster-command-id": command.commandId,
|
|
7152
7857
|
"x-amaster-run-id": runId,
|
|
7153
7858
|
"x-amaster-artifact-manifest-id": upload.manifestId,
|
|
7154
|
-
|
|
7859
|
+
...sourcePathHeaders
|
|
7155
7860
|
}));
|
|
7156
7861
|
if (readString(receipt.intentId) !== upload.intentId || readString(receipt.status) !== "finalized") {
|
|
7157
7862
|
throw new Error(`Runtime Artifact ${upload.intentId} was not finalized: ${JSON.stringify(receipt)}`);
|
|
@@ -7234,15 +7939,15 @@ async function completeCommand(config, command, status, result2, error) {
|
|
|
7234
7939
|
}
|
|
7235
7940
|
function resultOutboxDir(config) {
|
|
7236
7941
|
const explicit = readString(process.env.AMASTER_RESULT_OUTBOX_DIR);
|
|
7237
|
-
if (explicit) return
|
|
7238
|
-
return
|
|
7942
|
+
if (explicit) return resolve10(expandHomePath(explicit));
|
|
7943
|
+
return join11(dirname7(stateFilePath(process.env)), "result-outbox");
|
|
7239
7944
|
}
|
|
7240
7945
|
function resultOutboxInvalidDir(config) {
|
|
7241
|
-
return
|
|
7946
|
+
return join11(resultOutboxDir(config), "invalid");
|
|
7242
7947
|
}
|
|
7243
7948
|
function writeResultOutboxEntry(config, entry) {
|
|
7244
7949
|
const dir = resultOutboxDir(config);
|
|
7245
|
-
|
|
7950
|
+
mkdirSync6(dir, { recursive: true });
|
|
7246
7951
|
const body = {
|
|
7247
7952
|
version: 1,
|
|
7248
7953
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -7250,18 +7955,18 @@ function writeResultOutboxEntry(config, entry) {
|
|
|
7250
7955
|
lastAttemptAt: null,
|
|
7251
7956
|
...entry
|
|
7252
7957
|
};
|
|
7253
|
-
|
|
7958
|
+
writeFileSync6(join11(dir, resultOutboxFileName(entry.commandId)), `${JSON.stringify(body, null, 2)}
|
|
7254
7959
|
`, { mode: 384 });
|
|
7255
7960
|
}
|
|
7256
7961
|
function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail, original) {
|
|
7257
7962
|
const invalidDir = resultOutboxInvalidDir(config);
|
|
7258
|
-
|
|
7259
|
-
const invalidPath =
|
|
7963
|
+
mkdirSync6(invalidDir, { recursive: true });
|
|
7964
|
+
const invalidPath = join11(invalidDir, file);
|
|
7260
7965
|
if (original === void 0) {
|
|
7261
7966
|
try {
|
|
7262
7967
|
renameSync3(fullPath, invalidPath);
|
|
7263
7968
|
} catch {
|
|
7264
|
-
|
|
7969
|
+
copyFileSync3(fullPath, invalidPath);
|
|
7265
7970
|
unlinkSync(fullPath);
|
|
7266
7971
|
}
|
|
7267
7972
|
return;
|
|
@@ -7272,14 +7977,14 @@ function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail,
|
|
|
7272
7977
|
...detail ? { detail: truncateText(detail, 1e3) } : {},
|
|
7273
7978
|
original
|
|
7274
7979
|
};
|
|
7275
|
-
|
|
7980
|
+
writeFileSync6(invalidPath, `${JSON.stringify(evidence, null, 2)}
|
|
7276
7981
|
`, { mode: 384 });
|
|
7277
7982
|
unlinkSync(fullPath);
|
|
7278
7983
|
}
|
|
7279
7984
|
function readValidResultOutboxEntryOrQuarantine(config, file, fullPath) {
|
|
7280
7985
|
let entry;
|
|
7281
7986
|
try {
|
|
7282
|
-
entry = JSON.parse(
|
|
7987
|
+
entry = JSON.parse(readFileSync8(fullPath, "utf8"));
|
|
7283
7988
|
} catch (err) {
|
|
7284
7989
|
const message = err instanceof Error ? err.message : String(err);
|
|
7285
7990
|
moveResultOutboxEntryToInvalid(config, file, fullPath, "malformed_result_outbox_json", message);
|
|
@@ -7309,13 +8014,13 @@ function updateResultOutboxAttempt(fullPath, entry, err) {
|
|
|
7309
8014
|
...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
|
|
7310
8015
|
lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
|
|
7311
8016
|
};
|
|
7312
|
-
|
|
8017
|
+
writeFileSync6(fullPath, `${JSON.stringify(next, null, 2)}
|
|
7313
8018
|
`, { mode: 384 });
|
|
7314
8019
|
return next;
|
|
7315
8020
|
}
|
|
7316
8021
|
function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err) {
|
|
7317
8022
|
const invalidDir = resultOutboxInvalidDir(config);
|
|
7318
|
-
|
|
8023
|
+
mkdirSync6(invalidDir, { recursive: true });
|
|
7319
8024
|
const body = {
|
|
7320
8025
|
...entry,
|
|
7321
8026
|
invalidReason: reason,
|
|
@@ -7323,8 +8028,8 @@ function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err)
|
|
|
7323
8028
|
...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
|
|
7324
8029
|
lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
|
|
7325
8030
|
};
|
|
7326
|
-
const invalidPath =
|
|
7327
|
-
|
|
8031
|
+
const invalidPath = join11(invalidDir, file);
|
|
8032
|
+
writeFileSync6(invalidPath, `${JSON.stringify(body, null, 2)}
|
|
7328
8033
|
`, { mode: 384 });
|
|
7329
8034
|
try {
|
|
7330
8035
|
unlinkSync(fullPath);
|
|
@@ -7337,11 +8042,11 @@ function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err)
|
|
|
7337
8042
|
}
|
|
7338
8043
|
async function flushResultOutbox(config) {
|
|
7339
8044
|
const dir = resultOutboxDir(config);
|
|
7340
|
-
if (!
|
|
7341
|
-
const files =
|
|
8045
|
+
if (!existsSync10(dir)) return { attempted: 0, completed: 0 };
|
|
8046
|
+
const files = readdirSync8(dir).filter((name) => name.endsWith(".json")).sort();
|
|
7342
8047
|
let completed = 0;
|
|
7343
8048
|
for (const file of files) {
|
|
7344
|
-
const fullPath =
|
|
8049
|
+
const fullPath = join11(dir, file);
|
|
7345
8050
|
const entry = readValidResultOutboxEntryOrQuarantine(config, file, fullPath);
|
|
7346
8051
|
if (!entry) continue;
|
|
7347
8052
|
try {
|
|
@@ -7538,8 +8243,8 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
7538
8243
|
runtimeAuth,
|
|
7539
8244
|
issueId
|
|
7540
8245
|
);
|
|
7541
|
-
const targetDir =
|
|
7542
|
-
|
|
8246
|
+
const targetDir = join11(workspace.cwd, "input-attachments");
|
|
8247
|
+
mkdirSync6(targetDir, { recursive: true });
|
|
7543
8248
|
const usedFilenames = /* @__PURE__ */ new Set();
|
|
7544
8249
|
const materialized = [];
|
|
7545
8250
|
for (const [index, rawAttachment] of attachments.entries()) {
|
|
@@ -7553,11 +8258,11 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
7553
8258
|
filename = `${stem}-${index + 1}${ext}`;
|
|
7554
8259
|
}
|
|
7555
8260
|
usedFilenames.add(filename);
|
|
7556
|
-
const targetPath =
|
|
8261
|
+
const targetPath = join11(targetDir, filename);
|
|
7557
8262
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
7558
|
-
|
|
8263
|
+
writeFileSync6(targetPath, body);
|
|
7559
8264
|
const attachmentId = readString(attachment.id);
|
|
7560
|
-
const actualSha256 =
|
|
8265
|
+
const actualSha256 = createHash8("sha256").update(body).digest("hex");
|
|
7561
8266
|
const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
|
|
7562
8267
|
const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
|
|
7563
8268
|
if (lineageCandidates.length > 0 && !lineage) {
|
|
@@ -7580,7 +8285,7 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
7580
8285
|
id: attachmentId,
|
|
7581
8286
|
name: readString(attachment.originalFilename) ?? filename,
|
|
7582
8287
|
path: targetPath,
|
|
7583
|
-
relativePath:
|
|
8288
|
+
relativePath: relative7(workspace.cwd, targetPath),
|
|
7584
8289
|
contentType: readString(attachment.contentType),
|
|
7585
8290
|
byteSize: body.byteLength,
|
|
7586
8291
|
contentPath,
|
|
@@ -7629,9 +8334,9 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
7629
8334
|
if (manifest.version !== 1 || !Array.isArray(manifest.entries)) {
|
|
7630
8335
|
throw new Error("artifact_input_manifest_invalid: expected version 1 entries array");
|
|
7631
8336
|
}
|
|
7632
|
-
const targetRoot =
|
|
7633
|
-
|
|
7634
|
-
|
|
8337
|
+
const targetRoot = join11(workspace.cwd, "input-artifacts");
|
|
8338
|
+
rmSync6(targetRoot, { recursive: true, force: true });
|
|
8339
|
+
mkdirSync6(targetRoot, { recursive: true });
|
|
7635
8340
|
const usedPaths = /* @__PURE__ */ new Set();
|
|
7636
8341
|
const materialized = [];
|
|
7637
8342
|
for (const [index, rawEntry] of manifest.entries.entries()) {
|
|
@@ -7649,7 +8354,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
7649
8354
|
throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
|
|
7650
8355
|
}
|
|
7651
8356
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
7652
|
-
const actualSha256 =
|
|
8357
|
+
const actualSha256 = createHash8("sha256").update(body).digest("hex");
|
|
7653
8358
|
if (body.byteLength !== byteSize || actualSha256 !== sha256) {
|
|
7654
8359
|
throw new Error(
|
|
7655
8360
|
`artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha256} actualSha256=${actualSha256}`
|
|
@@ -7660,18 +8365,18 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
7660
8365
|
id: attachmentId,
|
|
7661
8366
|
originalFilename: readString(entry.originalFilename)
|
|
7662
8367
|
}, index);
|
|
7663
|
-
let relativePath =
|
|
8368
|
+
let relativePath = join11("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
|
|
7664
8369
|
if (usedPaths.has(relativePath)) {
|
|
7665
8370
|
const ext = extname2(filename);
|
|
7666
8371
|
const stem = ext ? filename.slice(0, -ext.length) : filename;
|
|
7667
8372
|
filename = `${stem}-${index + 1}${ext}`;
|
|
7668
|
-
relativePath =
|
|
8373
|
+
relativePath = join11("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
|
|
7669
8374
|
}
|
|
7670
8375
|
usedPaths.add(relativePath);
|
|
7671
|
-
const targetPath =
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
8376
|
+
const targetPath = join11(workspace.cwd, relativePath);
|
|
8377
|
+
mkdirSync6(dirname7(targetPath), { recursive: true });
|
|
8378
|
+
writeFileSync6(targetPath, body);
|
|
8379
|
+
chmodSync5(targetPath, 292);
|
|
7675
8380
|
materialized.push({
|
|
7676
8381
|
id: attachmentId,
|
|
7677
8382
|
workProductId,
|
|
@@ -7690,9 +8395,9 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
7690
8395
|
version: 1,
|
|
7691
8396
|
entries: materialized.map(({ path: _path, relativePath, ...entry }) => ({ ...entry, path: relativePath }))
|
|
7692
8397
|
};
|
|
7693
|
-
const manifestPath =
|
|
7694
|
-
|
|
7695
|
-
|
|
8398
|
+
const manifestPath = join11(targetRoot, "artifact-input-manifest.json");
|
|
8399
|
+
writeFileSync6(manifestPath, JSON.stringify(localManifest, null, 2) + "\n");
|
|
8400
|
+
chmodSync5(manifestPath, 292);
|
|
7696
8401
|
updateWorkspaceManifest(workspaceManifestPath(workspace), { artifactInputManifest: localManifest });
|
|
7697
8402
|
await ingestLog(config, command, "system", "info", `Materialized ${materialized.length} required artifact input(s) into the execution workspace`, {
|
|
7698
8403
|
artifactInputCount: materialized.length,
|
|
@@ -7701,46 +8406,46 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
7701
8406
|
return materialized;
|
|
7702
8407
|
}
|
|
7703
8408
|
function issueCheckpointDir(workspace) {
|
|
7704
|
-
return
|
|
8409
|
+
return join11(dirname7(workspace.runDir), "checkpoint");
|
|
7705
8410
|
}
|
|
7706
8411
|
async function clearIssueCheckpoint(config, command, workspace, reason) {
|
|
7707
8412
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
7708
|
-
if (!
|
|
7709
|
-
|
|
8413
|
+
if (!existsSync10(checkpointDir)) return false;
|
|
8414
|
+
rmSync6(checkpointDir, { recursive: true, force: true });
|
|
7710
8415
|
await ingestLog(config, command, "system", "info", "Cleared issue continuation checkpoint", { reason });
|
|
7711
8416
|
return true;
|
|
7712
8417
|
}
|
|
7713
8418
|
function safeCheckpointRelativePath(rawPath) {
|
|
7714
8419
|
const raw = String(rawPath ?? "").trim();
|
|
7715
|
-
if (
|
|
8420
|
+
if (isAbsolute7(raw) || /^[A-Za-z]:[\\/]/.test(raw)) return null;
|
|
7716
8421
|
const normalized = raw.split(/[\\/]+/).filter(Boolean).join("/");
|
|
7717
8422
|
if (!normalized || normalized.startsWith("../") || normalized.split("/").some((segment) => segment.startsWith("."))) return null;
|
|
7718
8423
|
if (normalized.startsWith("input-attachments/") || isRuntimeMetadataArtifactPath(normalized)) return null;
|
|
7719
8424
|
return normalized;
|
|
7720
8425
|
}
|
|
7721
8426
|
function hashFileSha256(filePath) {
|
|
7722
|
-
return
|
|
8427
|
+
return createHash8("sha256").update(readFileSync8(filePath)).digest("hex");
|
|
7723
8428
|
}
|
|
7724
8429
|
async function materializeIssueCheckpoint(config, command, workspace) {
|
|
7725
8430
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
7726
|
-
const manifestPath =
|
|
7727
|
-
if (!
|
|
8431
|
+
const manifestPath = join11(checkpointDir, "manifest.json");
|
|
8432
|
+
if (!existsSync10(manifestPath)) return [];
|
|
7728
8433
|
let manifest;
|
|
7729
8434
|
try {
|
|
7730
|
-
manifest = asRecord(JSON.parse(
|
|
8435
|
+
manifest = asRecord(JSON.parse(readFileSync8(manifestPath, "utf8")));
|
|
7731
8436
|
} catch (err) {
|
|
7732
|
-
|
|
8437
|
+
rmSync6(checkpointDir, { recursive: true, force: true });
|
|
7733
8438
|
throw new Error(`invalid issue checkpoint manifest: ${err instanceof Error ? err.message : String(err)}`);
|
|
7734
8439
|
}
|
|
7735
8440
|
const expiresAt = Date.parse(readString(manifest.expiresAt) ?? "");
|
|
7736
8441
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() || readString(manifest.issueId) !== commandIssueId(command)) {
|
|
7737
|
-
|
|
8442
|
+
rmSync6(checkpointDir, { recursive: true, force: true });
|
|
7738
8443
|
return [];
|
|
7739
8444
|
}
|
|
7740
8445
|
try {
|
|
7741
8446
|
const files = Array.isArray(manifest.files) ? manifest.files : [];
|
|
7742
8447
|
if (files.length > 20) throw new Error("issue checkpoint manifest exceeds the limit of 20 files");
|
|
7743
|
-
const filesRoot = realpathSync3(
|
|
8448
|
+
const filesRoot = realpathSync3(join11(checkpointDir, "files"));
|
|
7744
8449
|
const workspaceRoot = realpathSync3(workspace.cwd);
|
|
7745
8450
|
const validated = [];
|
|
7746
8451
|
let totalBytes = 0;
|
|
@@ -7748,12 +8453,12 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
7748
8453
|
const file = asRecord(rawFile);
|
|
7749
8454
|
const relativePath = safeCheckpointRelativePath(readString(file.path));
|
|
7750
8455
|
if (!relativePath) throw new Error("issue checkpoint manifest contains an invalid file path");
|
|
7751
|
-
const sourceCandidate =
|
|
7752
|
-
const target =
|
|
8456
|
+
const sourceCandidate = resolve10(filesRoot, relativePath);
|
|
8457
|
+
const target = resolve10(workspaceRoot, relativePath);
|
|
7753
8458
|
if (!pathWithin2(sourceCandidate, filesRoot) || !pathWithin2(target, workspaceRoot)) {
|
|
7754
8459
|
throw new Error(`issue checkpoint path escapes its workspace: ${relativePath}`);
|
|
7755
8460
|
}
|
|
7756
|
-
if (!
|
|
8461
|
+
if (!existsSync10(sourceCandidate)) throw new Error(`issue checkpoint file is missing: ${relativePath}`);
|
|
7757
8462
|
const source = realpathSync3(sourceCandidate);
|
|
7758
8463
|
if (!pathWithin2(source, filesRoot) || !statSync7(source).isFile()) {
|
|
7759
8464
|
throw new Error(`issue checkpoint source escapes its storage root: ${relativePath}`);
|
|
@@ -7773,17 +8478,17 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
7773
8478
|
const materialized = [];
|
|
7774
8479
|
for (const { relativePath, source, target } of validated) {
|
|
7775
8480
|
try {
|
|
7776
|
-
|
|
8481
|
+
lstatSync6(target);
|
|
7777
8482
|
continue;
|
|
7778
8483
|
} catch (err) {
|
|
7779
8484
|
if (err?.code !== "ENOENT") throw err;
|
|
7780
8485
|
}
|
|
7781
|
-
|
|
7782
|
-
const targetParent = realpathSync3(
|
|
8486
|
+
mkdirSync6(dirname7(target), { recursive: true });
|
|
8487
|
+
const targetParent = realpathSync3(dirname7(target));
|
|
7783
8488
|
if (!pathWithin2(targetParent, workspaceRoot)) {
|
|
7784
8489
|
throw new Error(`issue checkpoint target escapes its workspace: ${relativePath}`);
|
|
7785
8490
|
}
|
|
7786
|
-
|
|
8491
|
+
copyFileSync3(source, target);
|
|
7787
8492
|
materialized.push(relativePath);
|
|
7788
8493
|
}
|
|
7789
8494
|
if (materialized.length > 0) {
|
|
@@ -7807,31 +8512,31 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
7807
8512
|
}
|
|
7808
8513
|
async function saveIssueCheckpoint(config, command, workspace, candidates) {
|
|
7809
8514
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
7810
|
-
const filesDir =
|
|
7811
|
-
|
|
7812
|
-
|
|
8515
|
+
const filesDir = join11(checkpointDir, "files");
|
|
8516
|
+
rmSync6(checkpointDir, { recursive: true, force: true });
|
|
8517
|
+
mkdirSync6(filesDir, { recursive: true });
|
|
7813
8518
|
const files = [];
|
|
7814
8519
|
let totalBytes = 0;
|
|
7815
8520
|
const workspaceRoot = realpathSync3(workspace.cwd);
|
|
7816
8521
|
for (const candidate of candidates.slice(0, 20)) {
|
|
7817
8522
|
const relativePath = safeCheckpointRelativePath(candidate.rawPath);
|
|
7818
8523
|
const source = readString(candidate.filePath);
|
|
7819
|
-
if (!relativePath || !source || !
|
|
8524
|
+
if (!relativePath || !source || !existsSync10(source) || !statSync7(source).isFile()) continue;
|
|
7820
8525
|
const ownedSource = realpathSync3(source);
|
|
7821
8526
|
if (!pathWithin2(ownedSource, workspaceRoot)) {
|
|
7822
8527
|
throw new Error(`issue checkpoint source escapes its execution workspace: ${relativePath}`);
|
|
7823
8528
|
}
|
|
7824
8529
|
const byteSize = statSync7(ownedSource).size;
|
|
7825
8530
|
if (byteSize <= 0 || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) continue;
|
|
7826
|
-
const target =
|
|
8531
|
+
const target = resolve10(filesDir, relativePath);
|
|
7827
8532
|
if (!pathWithin2(target, filesDir)) continue;
|
|
7828
|
-
|
|
7829
|
-
|
|
8533
|
+
mkdirSync6(dirname7(target), { recursive: true });
|
|
8534
|
+
copyFileSync3(ownedSource, target);
|
|
7830
8535
|
totalBytes += byteSize;
|
|
7831
8536
|
files.push({ path: relativePath, byteSize, sha256: hashFileSha256(ownedSource) });
|
|
7832
8537
|
}
|
|
7833
8538
|
if (files.length === 0) {
|
|
7834
|
-
|
|
8539
|
+
rmSync6(checkpointDir, { recursive: true, force: true });
|
|
7835
8540
|
return null;
|
|
7836
8541
|
}
|
|
7837
8542
|
const manifest = {
|
|
@@ -7843,7 +8548,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates) {
|
|
|
7843
8548
|
totalBytes,
|
|
7844
8549
|
files
|
|
7845
8550
|
};
|
|
7846
|
-
|
|
8551
|
+
writeFileSync6(join11(checkpointDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
7847
8552
|
`);
|
|
7848
8553
|
await ingestLog(config, command, "system", "warn", `Saved ${files.length} required deliverable(s) for continuation recovery`, manifest);
|
|
7849
8554
|
return manifest;
|
|
@@ -7915,6 +8620,11 @@ async function executeRunCommand(config, command) {
|
|
|
7915
8620
|
let managedMcpProfile = null;
|
|
7916
8621
|
let managedMcpCleanup = null;
|
|
7917
8622
|
let cleanupManagedMcpProfile = null;
|
|
8623
|
+
let piChildIsolation = null;
|
|
8624
|
+
let trustedPiRuntime = null;
|
|
8625
|
+
let trustedPiRuntimeSourcePaths = null;
|
|
8626
|
+
let trustedPiRuntimeProfile = null;
|
|
8627
|
+
let trustedPiRuntimeAudit = null;
|
|
7918
8628
|
if (executor.kind === "codex" && Object.keys(governedMcp).length > 0) {
|
|
7919
8629
|
managedMcpProfile = prepareManagedCodexMcpProfile({
|
|
7920
8630
|
commandId: command.commandId,
|
|
@@ -7987,6 +8697,92 @@ async function executeRunCommand(config, command) {
|
|
|
7987
8697
|
...managedMcpProfile.attestation
|
|
7988
8698
|
});
|
|
7989
8699
|
}
|
|
8700
|
+
const piChildAllocator = executor.kind === "pi" ? configuredPiChildIdentityAllocator(config) : null;
|
|
8701
|
+
const trustedPiRuntimeAssertion = commandTrustedPiRuntimeAssertion(command);
|
|
8702
|
+
if (Object.keys(trustedPiRuntimeAssertion).length > 0) {
|
|
8703
|
+
try {
|
|
8704
|
+
if (executor.kind !== "pi") {
|
|
8705
|
+
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:executorKind");
|
|
8706
|
+
}
|
|
8707
|
+
trustedPiRuntimeSourcePaths = trustedPiRuntimeSources(config);
|
|
8708
|
+
trustedPiRuntime = verifyTrustedPiRuntimeAssertion({
|
|
8709
|
+
assertion: trustedPiRuntimeAssertion,
|
|
8710
|
+
connectorId: requireConnectorId(config),
|
|
8711
|
+
commandId: command.commandId,
|
|
8712
|
+
runId: commandRunId(command),
|
|
8713
|
+
leaseId: command.leaseId,
|
|
8714
|
+
executorKind: executor.kind,
|
|
8715
|
+
localDigests: readTrustedPiRuntimeLocalDigests(trustedPiRuntimeSourcePaths)
|
|
8716
|
+
});
|
|
8717
|
+
if (!managedMcpProfile) {
|
|
8718
|
+
throw new Error("pi_trusted_runtime_governed_profile_required");
|
|
8719
|
+
}
|
|
8720
|
+
requireTrustedPiChildAllocator(piChildAllocator, true);
|
|
8721
|
+
trustedPiRuntimeProfile = materializeTrustedPiRuntimeProfile({
|
|
8722
|
+
seedRoot: trustedPiRuntimeSourcePaths.seedRoot,
|
|
8723
|
+
overlayRoot: trustedPiRuntimeSourcePaths.overlayRoot,
|
|
8724
|
+
profileRoot: managedMcpProfile.profileRoot,
|
|
8725
|
+
agentDir: managedMcpProfile.env.PI_CODING_AGENT_DIR,
|
|
8726
|
+
governedMcpConfigPath: managedMcpProfile.configPath,
|
|
8727
|
+
verifiedAssertion: trustedPiRuntime
|
|
8728
|
+
});
|
|
8729
|
+
executorEnv = {
|
|
8730
|
+
...executorEnv,
|
|
8731
|
+
AMASTER_MANAGED_RUNTIME_ASSERTION_FD: "3",
|
|
8732
|
+
AMASTER_MANAGED_RUNTIME_AUDIT_FILE: join11(
|
|
8733
|
+
managedMcpProfile.env.HOME,
|
|
8734
|
+
".amaster-managed-runtime-audit.jsonl"
|
|
8735
|
+
),
|
|
8736
|
+
AMASTER_RUNTIME_LEASE_ID: command.leaseId
|
|
8737
|
+
};
|
|
8738
|
+
} catch (error) {
|
|
8739
|
+
if (managedMcpProfile) {
|
|
8740
|
+
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
8741
|
+
commandId: command.commandId,
|
|
8742
|
+
runId: commandRunId(command)
|
|
8743
|
+
});
|
|
8744
|
+
}
|
|
8745
|
+
throw error;
|
|
8746
|
+
}
|
|
8747
|
+
await ingestLog(config, command, "system", "info", "Verified trusted Pi runtime provenance", {
|
|
8748
|
+
presentationKind: "trusted_pi_runtime_attestation",
|
|
8749
|
+
attestationId: trustedPiRuntime.attestationId,
|
|
8750
|
+
unknownToolMode: trustedPiRuntime.unknownToolMode,
|
|
8751
|
+
directToolBudget: trustedPiRuntime.directToolBudget,
|
|
8752
|
+
digests: trustedPiRuntime.digests,
|
|
8753
|
+
profileAttestationId: trustedPiRuntimeProfile.attestationId,
|
|
8754
|
+
inheritedEntries: trustedPiRuntimeProfile.facts.inheritedEntries
|
|
8755
|
+
});
|
|
8756
|
+
}
|
|
8757
|
+
if (piChildAllocator) {
|
|
8758
|
+
try {
|
|
8759
|
+
const profileRoot = piChildIsolationProfileRoot({
|
|
8760
|
+
managedMcpProfile,
|
|
8761
|
+
executorHome: workspace.executorHome
|
|
8762
|
+
});
|
|
8763
|
+
piChildIsolation = preparePiChildIsolation({
|
|
8764
|
+
allocator: piChildAllocator,
|
|
8765
|
+
effectiveUid: typeof process.geteuid === "function" ? process.geteuid() : null,
|
|
8766
|
+
commandId: command.commandId,
|
|
8767
|
+
runId: commandRunId(command),
|
|
8768
|
+
profileRoot,
|
|
8769
|
+
workspaceRoot: cwd,
|
|
8770
|
+
allowedRoot: config.runtimeWorkspacesRoot
|
|
8771
|
+
});
|
|
8772
|
+
} catch (error) {
|
|
8773
|
+
if (managedMcpProfile) {
|
|
8774
|
+
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
8775
|
+
commandId: command.commandId,
|
|
8776
|
+
runId: commandRunId(command)
|
|
8777
|
+
});
|
|
8778
|
+
}
|
|
8779
|
+
throw error;
|
|
8780
|
+
}
|
|
8781
|
+
await ingestLog(config, command, "system", "info", "Prepared isolated Pi child identity", {
|
|
8782
|
+
presentationKind: "pi_child_isolation_attestation",
|
|
8783
|
+
...piChildIsolation.attestation
|
|
8784
|
+
});
|
|
8785
|
+
}
|
|
7990
8786
|
await ingestLog(config, command, "system", "info", `Compiled ${contextManifest.mode} prompt using ${contextManifest.budget.usedChars}/${contextManifest.budget.totalChars} characters`, {
|
|
7991
8787
|
presentationKind: "context_manifest",
|
|
7992
8788
|
contextManifest
|
|
@@ -8033,11 +8829,35 @@ async function executeRunCommand(config, command) {
|
|
|
8033
8829
|
maxRssMb: config.executorMaxRssMb,
|
|
8034
8830
|
signal: abortController.signal,
|
|
8035
8831
|
executorKind: executor.kind,
|
|
8832
|
+
...piChildIsolation ? { spawnIdentity: piChildIsolation.spawn } : {},
|
|
8833
|
+
...trustedPiRuntime ? {
|
|
8834
|
+
managedInput: `${JSON.stringify(trustedPiRuntimeAssertion)}
|
|
8835
|
+
`
|
|
8836
|
+
} : {},
|
|
8036
8837
|
onOutput: (stream, chunk, rawBytes) => {
|
|
8037
8838
|
noteActiveRunOutput(command, stream, chunk, rawBytes);
|
|
8038
8839
|
liveOutputLogger.write(stream, chunk);
|
|
8039
8840
|
}
|
|
8040
8841
|
});
|
|
8842
|
+
if (trustedPiRuntime) {
|
|
8843
|
+
verifyTrustedPiRuntimeAssertion({
|
|
8844
|
+
assertion: trustedPiRuntimeAssertion,
|
|
8845
|
+
connectorId: requireConnectorId(config),
|
|
8846
|
+
commandId: command.commandId,
|
|
8847
|
+
runId: commandRunId(command),
|
|
8848
|
+
leaseId: command.leaseId,
|
|
8849
|
+
executorKind: executor.kind,
|
|
8850
|
+
localDigests: readTrustedPiRuntimeLocalDigests(trustedPiRuntimeSourcePaths),
|
|
8851
|
+
verifyExpiry: false
|
|
8852
|
+
});
|
|
8853
|
+
trustedPiRuntimeAudit = readTrustedPiRuntimeAudit({
|
|
8854
|
+
profileRoot: managedMcpProfile.profileRoot,
|
|
8855
|
+
auditFile: executorEnv.AMASTER_MANAGED_RUNTIME_AUDIT_FILE,
|
|
8856
|
+
commandId: command.commandId,
|
|
8857
|
+
runId: commandRunId(command),
|
|
8858
|
+
runtimeEnforcementDigest: trustedPiRuntime.digests.runtimeEnforcementDigest
|
|
8859
|
+
});
|
|
8860
|
+
}
|
|
8041
8861
|
} finally {
|
|
8042
8862
|
await liveOutputLogger.flush();
|
|
8043
8863
|
}
|
|
@@ -8121,7 +8941,7 @@ async function executeRunCommand(config, command) {
|
|
|
8121
8941
|
workspace,
|
|
8122
8942
|
workspaceStatus.artifacts.map((artifact) => ({
|
|
8123
8943
|
rawPath: artifact.relativePath,
|
|
8124
|
-
filePath:
|
|
8944
|
+
filePath: resolve10(cwd, artifact.relativePath)
|
|
8125
8945
|
}))
|
|
8126
8946
|
);
|
|
8127
8947
|
nativeSessionRollout = {
|
|
@@ -8265,6 +9085,17 @@ async function executeRunCommand(config, command) {
|
|
|
8265
9085
|
attestation: managedMcpProfile.attestation,
|
|
8266
9086
|
cleanup: managedMcpCleanup
|
|
8267
9087
|
}
|
|
9088
|
+
} : {},
|
|
9089
|
+
...piChildIsolation ? {
|
|
9090
|
+
piChildIsolation: piChildIsolation.attestation
|
|
9091
|
+
} : {},
|
|
9092
|
+
...trustedPiRuntimeProfile ? {
|
|
9093
|
+
trustedPiRuntime: {
|
|
9094
|
+
attestationId: trustedPiRuntime.attestationId,
|
|
9095
|
+
profileAttestationId: trustedPiRuntimeProfile.attestationId,
|
|
9096
|
+
...trustedPiRuntimeProfile.facts,
|
|
9097
|
+
audit: trustedPiRuntimeAudit
|
|
9098
|
+
}
|
|
8268
9099
|
} : {}
|
|
8269
9100
|
};
|
|
8270
9101
|
const completion = await completeCommand(config, command, cancelled ? "cancelled" : succeeded ? "succeeded" : "failed", result2, error ?? void 0);
|
|
@@ -8287,6 +9118,7 @@ async function executeRunCommand(config, command) {
|
|
|
8287
9118
|
runId: commandRunId(command)
|
|
8288
9119
|
});
|
|
8289
9120
|
}
|
|
9121
|
+
piChildIsolation?.release();
|
|
8290
9122
|
stopActiveRunHeartbeats();
|
|
8291
9123
|
forgetActiveRunCommand();
|
|
8292
9124
|
}
|
|
@@ -8489,7 +9321,7 @@ async function runLoop(config) {
|
|
|
8489
9321
|
${message}
|
|
8490
9322
|
`);
|
|
8491
9323
|
}
|
|
8492
|
-
await new Promise((
|
|
9324
|
+
await new Promise((resolve11) => setTimeout(resolve11, config.pollIntervalSeconds * 1e3));
|
|
8493
9325
|
}
|
|
8494
9326
|
}
|
|
8495
9327
|
function help() {
|