Files
reverse-engineering-anything/tests/acceptance/setup/hermesAnchoredEntrySetup.test.ts
T
84f62f76e5 fix(hermes): preserve external YAML anchor consumers (#5152)
* fix(hermes): preserve consumers of anchored registrations

Keep original alias values and comments before setup or uninstall replaces an anchored REA node. Preserve original nested bindings and retained sharing through the common YAML writer.

Fixes #3325

* test(hermes): assert retained alias object identity

* fix(hermes): preserve removed keys and surviving alias owners

* test(cli): restore retained-view cancellation phase coverage

* fix(setup): retain copied Hermes anchor comments

* chore(hermes): reverse incidental merge hook changes

Reverse the merge relative to its included-main parent to restore exact upstream bytes. Reapply only the independently reviewed shared-owner and regression patch in a normal follow-up commit. Keep all ordinary history and normal hooks; no remote push of the rejected hook drift.

Refs #3325

* fix(hermes): retain reviewed shared-owner integration

* chore(hermes): reverse incidental merge hook changes

Reverse the merge relative to its included-main parent to restore exact upstream bytes. Reapply only the independently reviewed shared-owner and regression patch in a normal follow-up commit. Keep all ordinary history and normal hooks; no remote push of the rejected hook drift.

Refs #3325

* fix(hermes): retain exact reviewed shared-owner regression

* test(native): align plist command fixtures with main

Adopt the two maintained-main fixture files as of
dd198d037f. Distinguish exact XML lint
validation from conversion commands and retain truthful provenance,
source-value, format, limitations and unknown-scalar assertions.

The original seven provenance failures reproduce before this repair.
The affected three-file group passes all 86 checks afterward. Product
code and installed-package bytes remain unchanged.

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>

* fix(native): retain bound-target dispatch failure contracts

Adopt morluto's canonical Apple dispatch metadata owner and bounded MCP
and cleanup controls from 41e10b240c.
Keep fresh admission separate from already-bound target changes and
retain access-denied classification, exact physical causes and cleanup
ownership. Update the two stale unit expectations exposed by Source CI.

The original unit pair reproduces before the correction. Current focused
regressions, package verification and installed feature controls pass.
Only the canonical Apple owner and related controls are ported; this does
not integrate unrelated later-main changes or create another contribution.

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>

* test: align plist provenance and package listing fixtures

Keep the exact XML lint invocation in CLI provenance and include the
required CLI environment owner in the synthetic package member list.
Preserve binary provenance and all LF, CRLF, literal-CR and bytecode checks.

* revert(hermes): restore canonical main before reviewed replay

This reverts commit 575a10d194, reversing
changes made to bb17e90f27.

* test(cli): retain full cancellation oracle with prepared projection

---------

Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-27 21:33:17 +08:00

157 lines
6.1 KiB
TypeScript

import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join, resolve } from "node:path";
import { parse } from "yaml";
import { expect } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
for (const version of ["1.1", "1.2"] as const) {
for (const style of [
"entry",
"child",
"shadowed",
"key",
"external",
] as const) {
cliTest(
`Hermes ${version} preserves ${style} anchor consumers through setup and uninstall`,
async ({ cli }) => {
const home = await createTestTempDirectory(
"rea-hermes-anchored-entry-",
);
const profile = join(home, "hermes");
const config = join(profile, "config.yaml");
const server = {
command: process.execPath,
args: [resolve("scripts/rea.mjs"), "mcp"],
env: { KEEP: "off" },
enabled: false,
};
const directive = version === "1.2" ? "%YAML 1.2\n---\n" : "";
const hasDefaults = style === "shadowed" || style === "external";
const entry =
` command: ${JSON.stringify(server.command)}\n` +
` args: ${JSON.stringify(server.args)}\n` +
" enabled: false\n" +
(hasDefaults
? " env: *settings # Keep nested reference comment\n"
: ` env: ${style === "child" ? "&settings " : ""}{KEEP: 'off'}\n`);
const original =
directive +
"# Keep this user setting\nmodel: custom\n" +
(hasDefaults ? "defaults: &settings {KEEP: 'off'}\n" : "") +
`mcp_servers:\n ${style === "key" ? "&server_name " : ""}rea:${style === "child" || style === "key" ? "" : " &server"}${style === "entry" ? " # Keep anchor definition comment" : ""}\n` +
entry +
(style === "child"
? " other:\n command: other-server\n env: *settings # Shared environment\n"
: style === "key"
? " other: {command: other-server}\nobserver: *server_name # Registration name\n"
: " other: *server # Independent server\n") +
(style === "shadowed"
? "later: &settings {KEEP: later}\nobserver: *server\n"
: "");
const other =
style === "child"
? { command: "other-server", env: { KEEP: "off" } }
: style === "key"
? { command: "other-server" }
: server;
await mkdir(profile);
await writeFile(config, original);
const run = (arguments_: readonly string[]) =>
cli.run({
arguments: arguments_,
cwd: home,
environment: {
HOME: home,
USERPROFILE: home,
HERMES_HOME: profile,
},
timeoutMs: 20_000,
});
const setup = [
"setup",
"--client",
"hermes",
"--skill=false",
"--yes",
"--json",
];
const applied = await run(setup);
expect(applied.exitCode, JSON.stringify(applied)).toBe(0);
expect(applied.json).toMatchObject({ status: "ready" });
const configured = await readFile(config, "utf8");
const configuredValues = parse(configured, { version });
expect(configuredValues).toMatchObject({
model: "custom",
mcp_servers: { rea: { enabled: true, env: { KEEP: "off" } }, other },
...(style === "shadowed"
? { observer: server, later: { KEEP: "later" } }
: {}),
...(style === "key" ? { observer: "rea" } : {}),
});
if (hasDefaults)
expect(configuredValues.mcp_servers.other.env).toBe(
configuredValues.defaults,
);
expect(configured).toContain("# Keep this user setting");
if (style === "entry")
expect(configured).toContain("# Keep anchor definition comment");
expect(configured).toContain(
style === "child"
? "# Shared environment"
: style === "key"
? "# Registration name"
: "# Independent server",
);
if (hasDefaults)
expect(configured).toContain("# Keep nested reference comment");
expect(await readFile(`${config}.rea.backup`, "utf8")).toBe(original);
const doctor = await run(["doctor", "--client", "hermes", "--json"]);
expect(doctor.exitCode, JSON.stringify(doctor)).toBe(0);
expect(doctor.json).toMatchObject({
healthy: true,
identity: { registrations: [{ client: "hermes", state: "aligned" }] },
});
const repeated = await run(setup);
expect(repeated.exitCode, JSON.stringify(repeated)).toBe(0);
expect(repeated.json).toMatchObject({
plannedActions: [],
appliedActions: [],
});
expect(await readFile(config, "utf8")).toBe(configured);
const removed = await run(["uninstall", "--json"]);
expect(removed.exitCode, JSON.stringify(removed)).toBe(0);
const removedValues = parse(await readFile(config, "utf8"), {
version,
});
expect(removedValues).toEqual({
model: "custom",
mcp_servers: { other },
...(hasDefaults ? { defaults: { KEEP: "off" } } : {}),
...(style === "shadowed"
? {
later: { KEEP: "later" },
observer: server,
}
: {}),
...(style === "key" ? { observer: "rea" } : {}),
});
if (hasDefaults)
expect(removedValues.mcp_servers.other.env).toBe(
removedValues.defaults,
);
expect(await readFile(`${config}.rea.backup`, "utf8")).toBe(original);
const remaining = await readFile(config, "utf8");
if (style === "entry")
expect(remaining).toContain("# Keep anchor definition comment");
if (hasDefaults)
expect(remaining).toContain("# Keep nested reference comment");
expect((await run(["uninstall", "--json"])).exitCode).toBe(0);
expect(await readFile(config, "utf8")).toBe(remaining);
},
);
}
}