mirror of
https://github.com/morluto/rea.git
synced 2026-10-19 04:19:54 -05:00
Replace fixed Linux Hopper release pins with current vendor feed metadata, complete detached-PGP package verification under the stable publisher primary key, and authenticated package evidence for offline admission. Share parsed publisher facts across approved setup, doctor and the pre-execution guard. Preserve existing ownership, cancellation, private-display and cleanup rules. Fixes #3577 Normalize empty XDG settings, preserve backups during approved cache repair, and retain publisher cleanup through cancellation and shutdown. Exercise cold offline verification without reusing process-local proof state. Serialize approved cache publication across processes, restore old evidence on failure, and share the existing lease owner from process without changing its identities. Validation: 438 focused tests (six platform-related skips), full static/documentation checks, real Ubuntu 24.04 official Hopper 6.6.0 setup/CLI/MCP, offline ordinary-user admission, launcher mutation rejection, and cold/warm verification measurements. Official RPM metadata mismatch is tracked separately in #3578 and fails closed. BREAKING CHANGE: Older Linux Hopper builds admitted by the fixed allowlist now require retained publisher-signed package evidence or an approved update to the current public demo. Update explicit HOPPER_LAUNCHER_PATH values when migrating; the live feed exposes only its current release. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
139 lines
4.3 KiB
JavaScript
139 lines
4.3 KiB
JavaScript
import { json, run, runWithStatus } from "./lib/verify-package-core.mjs";
|
|
|
|
/** Run platform-specific deep-analysis smoke tests. */
|
|
export async function verifyPackagePlatform({
|
|
cli,
|
|
environment,
|
|
platform = process.platform,
|
|
runCommand = run,
|
|
}) {
|
|
if (platform === "linux") {
|
|
const unsupportedExecution = await runWithStatus(
|
|
cli,
|
|
["analyze", process.execPath, "--provider", "hopper", "--json"],
|
|
environment,
|
|
);
|
|
assertLinuxPackageProviderFailure(unsupportedExecution);
|
|
} else {
|
|
const overview = json(
|
|
await runCommand(
|
|
cli,
|
|
["analyze", process.execPath, "--provider", "hopper", "--json"],
|
|
environment,
|
|
),
|
|
);
|
|
if (!hasPositiveProcedureCount(overview))
|
|
throw new Error(
|
|
`packaged Hopper-backed analyze CLI failed: ${JSON.stringify(overview)}`,
|
|
);
|
|
const inspected = json(
|
|
await runCommand(
|
|
cli,
|
|
["inspect", process.execPath, "--provider", "hopper", "--json"],
|
|
environment,
|
|
),
|
|
);
|
|
if (!hasPositiveProcedureCount(inspected))
|
|
throw new Error("packaged inspect CLI failed");
|
|
const functionResult = json(
|
|
await runCommand(
|
|
cli,
|
|
[
|
|
"function",
|
|
process.execPath,
|
|
"0x1000",
|
|
"--provider",
|
|
"hopper",
|
|
"--json",
|
|
],
|
|
environment,
|
|
),
|
|
);
|
|
if (
|
|
functionResult.operation !== "analyze_function" ||
|
|
functionResult.provider?.id !== "hopper" ||
|
|
functionResult.normalized_result?.procedure?.address !== "0x1000"
|
|
)
|
|
throw new Error(
|
|
`packaged function CLI failed: ${JSON.stringify(functionResult)}`,
|
|
);
|
|
const xrefs = json(
|
|
await runCommand(
|
|
cli,
|
|
["xrefs", process.execPath, "0x1000", "--provider", "hopper", "--json"],
|
|
environment,
|
|
),
|
|
);
|
|
if (
|
|
xrefs.operation !== "xrefs" ||
|
|
JSON.stringify(xrefs.normalized_result) !== JSON.stringify(["0x1000"])
|
|
)
|
|
throw new Error(`packaged xrefs CLI failed: ${JSON.stringify(xrefs)}`);
|
|
const trace = json(
|
|
await runCommand(
|
|
cli,
|
|
[
|
|
"trace",
|
|
process.execPath,
|
|
"fixture",
|
|
"--provider",
|
|
"hopper",
|
|
"--json",
|
|
],
|
|
environment,
|
|
),
|
|
);
|
|
if (trace.operation !== "trace_feature")
|
|
throw new Error(`packaged trace CLI failed: ${JSON.stringify(trace)}`);
|
|
}
|
|
}
|
|
|
|
/** One owner for unsupported-launch evidence across package and real-Hopper verification. */
|
|
export const isUnsupportedHopperLaunchFailure = (failure) => {
|
|
const details = failure?.details;
|
|
const unsupportedBuild =
|
|
details?.failure_code === "unsupported_hopper_build" &&
|
|
details.exit_code === 72;
|
|
const publisherRejection =
|
|
details?.stage === "launch" &&
|
|
details.launch_rejection?.boundary === "publisher_verification" &&
|
|
details.launch_rejection.reason === "unsupported_hopper_build" &&
|
|
details.exit_code === undefined &&
|
|
details.launcher === undefined;
|
|
return (
|
|
failure?.code === "provider_unavailable" &&
|
|
(publisherRejection || unsupportedBuild)
|
|
);
|
|
};
|
|
|
|
/** Require an exact pre-execution rejection, observed helper exit, or missing-Xvfb diagnostic. */
|
|
export const assertLinuxPackageProviderFailure = (execution) => {
|
|
const failure = json(execution.stdout);
|
|
const details = failure?.details;
|
|
const diagnostic = details?.diagnostics;
|
|
const missingDisplayDependency =
|
|
details?.failure_code === "runtime_dependency_unavailable" &&
|
|
details.exit_code === 79 &&
|
|
diagnostic?.component === "hopper_private_display" &&
|
|
diagnostic.operation === "probe" &&
|
|
diagnostic.reason === "missing_xvfb" &&
|
|
diagnostic.status === "error" &&
|
|
diagnostic.failure_code === "runtime_dependency_unavailable" &&
|
|
diagnostic.strategy === "unavailable";
|
|
if (
|
|
execution.status !== 1 ||
|
|
failure?.code !== "provider_unavailable" ||
|
|
(!isUnsupportedHopperLaunchFailure(failure) && !missingDisplayDependency)
|
|
)
|
|
throw new Error(
|
|
`packaged Linux Hopper verification did not fail closed: ${JSON.stringify(failure)}`,
|
|
);
|
|
};
|
|
|
|
const hasPositiveProcedureCount = (result) =>
|
|
typeof result === "object" &&
|
|
result !== null &&
|
|
result.operation === "binary_overview" &&
|
|
Number.isInteger(result.normalized_result?.procedure_count) &&
|
|
result.normalized_result.procedure_count > 0;
|