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]>
42 lines
2.5 KiB
JavaScript
42 lines
2.5 KiB
JavaScript
// 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;
|
||
}
|