Files
stack/packages/conversation/src/text-policy.mjs
T
jason.woltjeandClaude Opus 5.5 243e153c8b feat(conversation): CHAT-03 I1, mediated control of a sealed headless Pi (#1507)
Controller, claim store, live-session guard, engine link and seal,
turn tracker, cohort force stop and recovery, client library,
transcript and mediated terminal, with the fake engine and tests.
Fixtures only; no live cutover.

Dewey built it. Darkwing (comment 26690) and Filbert (comment 26694)
approved round 2. Manifest I1-r2-manifest.sha256 (2b48e333, 27 files).
Suites on an export: conversation 152/152, control-board 124, webui 14,
seat 19, chat-00/01/01c checks, and all nine scripts/test-*.sh green.
Follow-ups for I3 are in DEFERRED. Gate E stays with Jason.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 15:47:53 -05:00

42 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The text policy for mediated prompts (#1507, CHAT-03 §4).
//
// CHAT-01 lines 181–183 refuse `text-policy` when the first non-whitespace
// character is `/`. CHAT-01 lines 368–370 leave `!`, `@` and slashes on later
// lines open; CHAT-03 settles them from the pinned Pi 0.85.1 source. The RPC
// `prompt` command calls AgentSession.prompt(message) (rpc-mode.js 298–318),
// and that path interprets text only through three checks, all on the exact
// first character:
//
// - extension commands: `text.startsWith("/")` (agent-session.js 828);
// - skills: `text.startsWith("/skill:")` (agent-session.js 984);
// - prompt templates: `text.startsWith("/")` (prompt-templates.js 222).
//
// The bundle `pi` runs (dist/bundle/chunks/chunk-JVUZSMYM.js) carries the same
// three checks. `!` and `!!` are shell shortcuts of the interactive editor only
// (interactive-mode.js 2502), and `@` is a file argument of the command line
// only (cli/args.js 214); neither is on the RPC prompt path. Pi never trims
// before its checks, so a slash after leading whitespace or on a later line is
// plain text to Pi. CHAT-01's rule still refuses the leading-whitespace case.
//
// Every prefix is therefore classified: a first non-whitespace `/` is refused,
// and everything else is text. PREFIXES is the list the tests read (S2).
export const TEXT_POLICY = "text-policy";
export const PREFIXES = Object.freeze([
Object.freeze({ prefix: "/", interpreted: true, example: "/goal x", basis: "agent-session.js 828: extension commands run immediately" }),
Object.freeze({ prefix: "/skill:", interpreted: true, example: "/skill:ms-unslop", basis: "agent-session.js 984: skills expand" }),
Object.freeze({ prefix: "/<template>", interpreted: true, example: "/review this", basis: "prompt-templates.js 222: templates expand" }),
Object.freeze({ prefix: "!", interpreted: false, example: "!ls", basis: "interactive-mode.js 2502 only; not on the RPC prompt path" }),
Object.freeze({ prefix: "!!", interpreted: false, example: "!!ls", basis: "interactive-mode.js 2503 only; not on the RPC prompt path" }),
Object.freeze({ prefix: "@", interpreted: false, example: "@README.md", basis: "cli/args.js 214 only; not on the RPC prompt path" }),
]);
// Later-line slashes are not interpreted: every check is at index 0 (S3).
export const LATER_LINE_SLASH_INTERPRETED = false;
export function textPolicy(text) {
if (typeof text !== "string") return TEXT_POLICY;
return text.trimStart().startsWith("/") ? TEXT_POLICY : null;
}