murashit_codex-panel/tests/features/chat/domain/runtime/resolution.test.ts
2026-07-18 18:18:24 +09:00

496 lines
21 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { runtimeConfigOrDefault } from "../../../../../src/domain/runtime/config";
import {
resetRuntimeIntentToConfig,
setCollaborationModeIntent,
setRuntimeIntentValue,
} from "../../../../../src/features/chat/domain/runtime/intent";
import { resolveRuntimeControls } from "../../../../../src/features/chat/domain/runtime/resolution";
import { serviceTierRequestForThreadStart } from "../../../../../src/features/chat/domain/runtime/thread-settings-patch";
import {
autoReviewActive,
configLayer,
currentModel,
currentReasoningEffort,
currentServiceTier,
fastModeActive,
fastRuntimeServiceTierRequestValue,
modelFixture,
modelPendingIntentCases,
runtimeConfigFixture,
runtimeLayerCase,
runtimeSnapshot,
snapshotConfig,
supportedReasoningEfforts,
} from "./support";
describe("runtime control resolution", () => {
it("falls back to startup permissions until active thread permissions are reported", () => {
const configured = runtimeSnapshot({
runtimeConfig: runtimeConfigFixture({
default_permissions: ":workspace",
approval_policy: "on-request",
}),
});
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
permissionProfile: { effective: ":workspace", source: "config" },
sandboxPolicy: { effective: null, source: "none" },
approvalPolicy: { effective: "on-request", source: "config" },
});
const activeUnreported = runtimeSnapshot({
activeThreadId: "thread",
runtimeConfig: runtimeConfigFixture({
default_permissions: ":workspace",
approval_policy: "on-request",
}),
});
expect(resolveRuntimeControls(activeUnreported, snapshotConfig(activeUnreported))).toMatchObject({
permissionProfile: { configured: ":workspace", active: null, effective: ":workspace", source: "config" },
sandboxPolicy: { configured: null, active: null, effective: null, source: "none" },
approvalPolicy: { configured: "on-request", active: null, effective: "on-request", source: "config" },
});
const activeReported = runtimeSnapshot({
activeThreadId: "thread",
active: {
approvalPolicyKnown: true,
sandboxPolicyKnown: true,
permissionProfileKnown: true,
approvalPolicy: "never",
sandboxPolicy: { type: "readOnly", networkAccess: false },
activePermissionProfile: { id: ":read-only", extends: null },
approvalsReviewer: "user",
},
pending: { approvalsReviewer: setRuntimeIntentValue("auto_review") },
});
expect(resolveRuntimeControls(activeReported, snapshotConfig(activeReported))).toMatchObject({
approvalsReviewer: { effective: "auto_review", source: "pending" },
permissionProfile: { effective: ":read-only", source: "active-thread" },
sandboxPolicy: { effective: { type: "readOnly", networkAccess: false }, source: "active-thread" },
approvalPolicy: { effective: "never", source: "active-thread" },
});
const approvalOnlyReported = runtimeSnapshot({
activeThreadId: "thread",
runtimeConfig: runtimeConfigFixture({
default_permissions: ":workspace",
approval_policy: "on-request",
}),
active: {
approvalPolicyKnown: true,
approvalPolicy: "never",
},
});
expect(resolveRuntimeControls(approvalOnlyReported, snapshotConfig(approvalOnlyReported))).toMatchObject({
permissionProfile: { effective: ":workspace", source: "config" },
sandboxPolicy: { effective: null, source: "none" },
approvalPolicy: { effective: "never", source: "active-thread" },
});
});
it("marks the sandbox policy pending and unknown when selecting a different permission profile", () => {
const runtimeConfig = runtimeConfigFixture({});
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
runtimeConfig: {
...runtimeConfig,
startupPermissions: {
approvalPolicy: "on-request",
activePermissionProfile: { id: ":startup", extends: null },
sandboxPolicy: {
type: "workspaceWrite",
writableRoots: ["/vault"],
networkAccess: true,
excludeTmpdirEnvVar: true,
excludeSlashTmp: false,
},
},
},
active: {
sandboxPolicyKnown: true,
permissionProfileKnown: true,
sandboxPolicy: { type: "readOnly", networkAccess: false },
activePermissionProfile: { id: ":read-only", extends: null },
},
pending: { permissionProfile: setRuntimeIntentValue(":workspace") },
});
expect(resolveRuntimeControls(snapshot, snapshotConfig(snapshot))).toMatchObject({
permissionProfile: { effective: ":workspace", source: "pending" },
sandboxPolicy: {
confirmed: { type: "readOnly", networkAccess: false },
confirmedSource: "active-thread",
effective: null,
source: "pending",
},
});
});
it("uses the configured sandbox policy when reselecting the startup permission profile", () => {
const configuredPolicy = {
type: "workspaceWrite" as const,
writableRoots: ["/vault"],
networkAccess: true,
excludeTmpdirEnvVar: true,
excludeSlashTmp: false,
};
const runtimeConfig = runtimeConfigFixture({});
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
runtimeConfig: {
...runtimeConfig,
startupPermissions: {
approvalPolicy: "on-request",
activePermissionProfile: { id: ":workspace", extends: null },
sandboxPolicy: configuredPolicy,
},
},
active: {
sandboxPolicyKnown: true,
permissionProfileKnown: true,
sandboxPolicy: { type: "readOnly", networkAccess: false },
activePermissionProfile: { id: ":read-only", extends: null },
},
pending: { permissionProfile: setRuntimeIntentValue(":workspace") },
});
const config = snapshotConfig(snapshot);
const resolution = resolveRuntimeControls(snapshot, config);
expect(resolution.sandboxPolicy).toMatchObject({
confirmed: { type: "readOnly", networkAccess: false },
confirmedSource: "active-thread",
effective: configuredPolicy,
source: "pending",
});
});
it("resolves auto-review mode from requested, active, then effective config", () => {
const requested = runtimeSnapshot({
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
active: { approvalsReviewer: "auto_review" },
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
});
const active = runtimeSnapshot({
active: { approvalsReviewer: "user" },
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
});
const configured = runtimeSnapshot({
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
});
expect(autoReviewActive(requested, snapshotConfig(requested))).toBe(false);
expect(autoReviewActive(active, snapshotConfig(active))).toBe(false);
expect(autoReviewActive(configured, snapshotConfig(configured))).toBe(true);
});
it("uses the active reviewer before configured reviewer", () => {
const snapshot = runtimeSnapshot({
active: { approvalsReviewer: "user" },
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
});
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
});
it("treats guardian subagent reviewer as active auto-review", () => {
const snapshot = runtimeSnapshot({
active: { approvalsReviewer: "guardian_subagent" },
});
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
});
it("uses requested reviewer above active and configured reviewers", () => {
const snapshot = runtimeSnapshot({
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
active: { approvalsReviewer: "user" },
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
});
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
});
it("uses effective approval reviewer values and reports selected profile metadata", () => {
const runtimeConfig = runtimeConfigFixture({ approvals_reviewer: "auto_review" }, [
configLayer({}, null),
configLayer({ approvals_reviewer: "auto_review" }, "auto"),
]);
const snapshot = runtimeSnapshot({
runtimeConfig,
});
expect(runtimeConfigOrDefault(runtimeConfig).profile).toBe("auto");
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
});
it("uses effective model, effort, and fast mode config values", () => {
const snapshot = runtimeSnapshot({
runtimeConfig: runtimeConfigFixture(
{
model: "gpt-profile",
model_reasoning_effort: "high",
service_tier: "fast",
},
[
configLayer({}, null),
configLayer({ model: "gpt-profile", model_reasoning_effort: "high", service_tier: "fast" }, "fast-profile"),
],
),
});
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-profile");
expect(currentReasoningEffort(snapshot, snapshotConfig(snapshot))).toBe("high");
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("fast");
});
it("uses active service tier before configured service tier", () => {
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
active: { serviceTier: "flex" },
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
});
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("flex");
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
expect(resolution.serviceTier).toMatchObject({ effective: "flex", source: "active-thread" });
expect(resolution.fastMode).toMatchObject({ active: false, source: "active-thread", effectiveServiceTier: "flex" });
});
it("treats the catalog Fast service tier id as fast mode while preserving the id", () => {
const model = {
...modelFixture("gpt-5.5"),
serviceTiers: [{ id: "priority", name: "Fast" }],
};
// app-server may advertise Fast with an id such as "priority";
// last verified against codex app-server 0.142.0.
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
active: { model: "gpt-5.5", serviceTier: "priority" },
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
availableModels: [model],
});
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("priority");
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
expect(fastRuntimeServiceTierRequestValue(snapshot, snapshotConfig(snapshot))).toBe("priority");
});
it("treats the app-server reported default tier after clearing Fast as fast mode off", () => {
const model = {
...modelFixture("gpt-5.5"),
serviceTiers: [{ id: "priority", name: "Fast" }],
};
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
active: { model: "gpt-5.5", serviceTier: "default" },
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
availableModels: [model],
});
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("default");
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
});
it("uses requested Fast mode above active and configured service tiers", () => {
const snapshot = runtimeSnapshot({
active: { serviceTier: "flex" },
pending: { fastMode: setRuntimeIntentValue("disabled") },
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
});
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
expect(resolution.serviceTier).toMatchObject({ effective: null, source: "pending" });
expect(resolution.fastMode).toMatchObject({ active: false, source: "pending", effectiveServiceTier: null });
});
it("keeps a cleared active thread service tier above configured Fast mode", () => {
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
active: { serviceTier: null },
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
});
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
expect(resolution.serviceTier).toMatchObject({ effective: null, source: "active-thread" });
});
it("resolves all runtime controls through pending, active, and config layers", () => {
const configured = runtimeSnapshot({
runtimeConfig: runtimeConfigFixture({
model: "gpt-config",
model_reasoning_effort: "medium",
default_permissions: ":workspace",
approval_policy: "on-request",
sandbox_mode: "workspace-write",
sandbox_workspace_write: {
writable_roots: ["/vault"],
network_access: false,
exclude_tmpdir_env_var: false,
exclude_slash_tmp: false,
},
approvals_reviewer: "auto_review",
service_tier: "fast",
}),
});
const active = runtimeSnapshot({
...configured,
activeThreadId: "thread",
active: {
approvalPolicyKnown: true,
sandboxPolicyKnown: true,
permissionProfileKnown: true,
model: "gpt-active",
reasoningEffort: "high",
activePermissionProfile: { id: ":read-only", extends: null },
sandboxPolicy: { type: "readOnly", networkAccess: false },
approvalPolicy: "never",
approvalsReviewer: "user",
serviceTier: "flex",
},
});
const pending = runtimeSnapshot({
...active,
pending: {
...active.pending,
model: setRuntimeIntentValue("gpt-pending"),
reasoningEffort: setRuntimeIntentValue("low"),
permissionProfile: setRuntimeIntentValue(":workspace"),
approvalPolicy: setRuntimeIntentValue("on-request"),
approvalsReviewer: setRuntimeIntentValue("guardian_subagent"),
fastMode: setRuntimeIntentValue("enabled"),
},
});
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
model: { effective: "gpt-config", source: "config" },
reasoningEffort: { effective: "medium", source: "config" },
permissionProfile: { effective: ":workspace", source: "config" },
sandboxPolicy: { effective: null, source: "none" },
approvalPolicy: { effective: "on-request", source: "config" },
approvalsReviewer: { effective: "auto_review", source: "config" },
serviceTier: { effective: "fast", source: "config" },
});
expect(resolveRuntimeControls(active, snapshotConfig(active))).toMatchObject({
model: { effective: "gpt-active", source: "active-thread" },
reasoningEffort: { effective: "high", source: "active-thread" },
permissionProfile: { effective: ":read-only", source: "active-thread" },
sandboxPolicy: { effective: { type: "readOnly", networkAccess: false }, source: "active-thread" },
approvalPolicy: { effective: "never", source: "active-thread" },
approvalsReviewer: { effective: "user", source: "active-thread" },
serviceTier: { effective: "flex", source: "active-thread" },
});
expect(resolveRuntimeControls(pending, snapshotConfig(pending))).toMatchObject({
model: { confirmed: "gpt-active", confirmedSource: "active-thread", effective: "gpt-pending", source: "pending" },
reasoningEffort: { confirmed: "high", confirmedSource: "active-thread", effective: "low", source: "pending" },
permissionProfile: { confirmed: ":read-only", confirmedSource: "active-thread", effective: ":workspace", source: "pending" },
sandboxPolicy: {
confirmed: { type: "readOnly", networkAccess: false },
confirmedSource: "active-thread",
effective: null,
source: "pending",
},
approvalPolicy: { confirmed: "never", confirmedSource: "active-thread", effective: "on-request", source: "pending" },
approvalsReviewer: { confirmed: "user", confirmedSource: "active-thread", effective: "guardian_subagent", source: "pending" },
serviceTier: { confirmed: "flex", confirmedSource: "active-thread", effective: "fast", source: "pending" },
fastMode: {
active: true,
confirmedActive: false,
source: "pending",
confirmedSource: "active-thread",
serviceTierRequestValue: "fast",
},
});
});
it("model-checks runtime value precedence for configured, active, and pending model layers", () => {
for (const configured of [null, "gpt-config"] as const) {
for (const active of [null, "gpt-active"] as const) {
for (const pending of modelPendingIntentCases()) {
const snapshot = runtimeSnapshot({
runtimeConfig: runtimeConfigFixture(configured ? { model: configured } : {}),
active: { model: active },
pending: { model: pending.intent },
});
const model = resolveRuntimeControls(snapshot, snapshotConfig(snapshot)).model;
const expectedConfirmed = active ?? configured;
const expectedConfirmedSource = active ? "active-thread" : configured ? "config" : "none";
expect(model, runtimeLayerCase(configured, active, pending.name)).toMatchObject({
configured,
active,
pending: pending.intent,
confirmed: expectedConfirmed,
confirmedSource: expectedConfirmedSource,
effective: pending.name === "set" ? "gpt-pending" : pending.name === "resetToConfig" ? configured : expectedConfirmed,
source: pending.name === "set" ? "pending" : pending.name === "resetToConfig" ? "config" : expectedConfirmedSource,
});
}
}
}
});
it("reports collaboration mode dirtiness and missing model blockers from the resolved runtime", () => {
const blocked = runtimeSnapshot({
pending: { collaborationMode: setCollaborationModeIntent("plan") },
runtimeConfig: runtimeConfigFixture({}),
});
const ready = runtimeSnapshot({
pending: {
collaborationMode: setCollaborationModeIntent("plan"),
model: setRuntimeIntentValue("gpt-5.5"),
},
});
expect(resolveRuntimeControls(blocked, snapshotConfig(blocked)).collaborationMode).toMatchObject({
pending: setCollaborationModeIntent("plan"),
confirmed: "default",
effective: "plan",
dirty: true,
blockedReason: "missing-model",
});
expect(resolveRuntimeControls(ready, snapshotConfig(ready)).collaborationMode).toMatchObject({
pending: setCollaborationModeIntent("plan"),
confirmed: "default",
effective: "plan",
dirty: true,
blockedReason: null,
});
});
it("uses the explicit config when finding supported reasoning efforts", () => {
const snapshot = runtimeSnapshot({
pending: { model: resetRuntimeIntentToConfig() },
runtimeConfig: runtimeConfigFixture({ model: "snapshot-model" }),
availableModels: [
{ ...modelFixture("snapshot-model"), supportedReasoningEfforts: ["low"] },
{ ...modelFixture("explicit-model"), supportedReasoningEfforts: ["high"] },
],
});
const explicitConfig = runtimeConfigFixture({ model: "explicit-model" });
expect(supportedReasoningEfforts(snapshot, explicitConfig)).toEqual(["high"]);
});
it.each([
{ name: "catalog Fast tier", serviceTier: "catalog-fast", serviceTiers: [{ id: "catalog-fast", name: "Fast" }], expected: true },
{ name: "catalog Priority tier", serviceTier: "priority", serviceTiers: [{ id: "priority", name: "Priority" }], expected: false },
{ name: "catalog Flex tier", serviceTier: "flex", serviceTiers: [{ id: "flex", name: "Flex" }], expected: false },
])("classifies received $name from catalog metadata", ({ serviceTier, serviceTiers, expected }) => {
const snapshot = runtimeSnapshot({
activeThreadId: "thread",
active: { model: "gpt-5.5", serviceTier },
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
availableModels: [{ ...modelFixture("gpt-5.5"), serviceTiers }],
});
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(expected);
});
});