docs: document agent policy tests

This commit is contained in:
Peter Steinberger
2026-06-04 15:06:04 -04:00
parent 023427b1d5
commit 85b4bd6c7b
6 changed files with 26 additions and 0 deletions

View File

@@ -1,3 +1,4 @@
// Verifies exec host, sandbox, and approval-default resolution for embedded agents.
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { SessionEntry } from "../config/sessions.js";
import * as execApprovals from "../infra/exec-approvals.js";
@@ -139,6 +140,8 @@ describe("resolveExecDefaults", () => {
sandboxAvailable: true,
});
// Sandbox mode is intentionally self-contained: gateway approval floors
// must not leak into the local deny-by-default sandbox contract.
expect(defaults.effectiveHost).toBe("sandbox");
expect(defaults.security).toBe("deny");
expect(defaults.ask).toBe("off");
@@ -174,6 +177,8 @@ describe("resolveExecDefaults", () => {
agents: {},
});
// Approval floors clamp normalized mode upward/downward after config mode
// mapping so persisted host policy remains the final safety boundary.
expect(
resolveExecDefaults({
cfg: {
@@ -223,6 +228,8 @@ describe("resolveExecDefaults", () => {
});
it("keeps legacy security overrides ahead of higher-scope normalized mode", () => {
// Legacy security/ask overrides are still a shipped config shape. They win
// when scoped directly to the agent that is being resolved.
expect(
resolveExecDefaults({
cfg: {

View File

@@ -1,3 +1,4 @@
// Covers provider/model gates for strict agentic execution-contract activation.
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import {
@@ -122,6 +123,8 @@ describe("resolveEffectiveExecutionContract", () => {
});
it("collapses to default on unsupported providers even with gpt-5 model ids", () => {
// Model naming alone is insufficient; unsupported providers must not
// inherit OpenAI-specific strict-agentic handling by accident.
expect(
resolveEffectiveExecutionContract({
config: emptyConfig,

View File

@@ -1,3 +1,4 @@
// Documents how failover reasons map to cooldown probe slot decisions.
import { describe, expect, it } from "vitest";
import type { FailoverReason } from "./embedded-agent-helpers.js";
import {
@@ -13,6 +14,8 @@ type ReasonCase = {
preserveTransientProbeSlot: boolean;
};
// Keep the three decisions in one matrix so reason additions update cooldown
// eligibility, transient-slot use, and slot preservation together.
const CASES: ReasonCase[] = [
{
reason: "rate_limit",

View File

@@ -1,3 +1,4 @@
// Exercises per-session fallback skip markers, TTL expiry, and opt-in cache defaults.
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
DEFAULT_FALLBACK_SKIP_TTL_MS,
@@ -29,6 +30,8 @@ describe("fallback-skip-cache", () => {
});
it("treats falsy sessionId as a no-op for both mark and check", () => {
// Session scope is required. Without it, a permanent provider/auth failure
// could suppress fallback candidates across unrelated conversations.
markFallbackCandidateSkipped({
sessionId: undefined,
provider: "anthropic",

View File

@@ -1,3 +1,4 @@
// Verifies fast-mode precedence across session, agent, and model defaults.
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { resolveFastModeState } from "./fast-mode.js";
@@ -76,6 +77,8 @@ describe("resolveFastModeState", () => {
});
it("uses canonical provider/model config for slash-containing model ids", () => {
// OpenRouter-style models can contain slashes, so matching must build the
// canonical provider/model key instead of splitting on the first slash.
const cfg = {
agents: {
defaults: {
@@ -97,6 +100,8 @@ describe("resolveFastModeState", () => {
});
it("does not use another provider's slash-containing model config", () => {
// Provider qualification prevents a model-id substring from borrowing
// another provider's fast-mode setting.
const cfg = {
agents: {
defaults: {

View File

@@ -1,3 +1,4 @@
// Covers Copilot token exchange, cache shape, and proxy-derived API host behavior.
import { describe, expect, it, vi } from "vitest";
import { COPILOT_INTEGRATION_ID, buildCopilotIdeHeaders } from "./copilot-dynamic-headers.js";
import {
@@ -7,6 +8,8 @@ import {
describe("resolveCopilotApiToken", () => {
it("derives native Copilot base URLs from Copilot proxy hints", () => {
// Native Copilot tokens advertise proxy hosts; the chat endpoint lives on
// the sibling api host and ignores proxy ports.
expect(
deriveCopilotApiBaseUrlFromToken(
"copilot-token;proxy-ep=https://proxy.individual.githubcopilot.com;",
@@ -89,6 +92,8 @@ describe("resolveCopilotApiToken", () => {
const saveJsonFileImpl = vi.fn();
try {
// The integration id is part of Copilot's routing contract. Legacy cache
// entries without it must be refreshed even if the token is not expired.
const result = await resolveCopilotApiToken({
githubToken: "github-token",
cachePath: "/tmp/github-copilot-token-test.json",