Zero-inference spike for a Quest Engineering Claude Code Mod control bridge

This is a zero-inference, non-production fixture for the Claude harness reassessment. It targets the Mods API embedded in Claude Code 2.1.292 and is kept because it records executable evidence that a Mod can:
turn.step, before a mocked provider request;qe-harness-bridge local-control transport for structured completion;The tests run under claude plugin test, which Anthropic documents as running without a session, sign-in, or network. They never invoke a model.
local-control-wait and the request_human_assistance_and_wait operation are a proposed generic control bridge extension, not current production behavior. The current bridge can create a HumanAttention request but cannot keep a Mod call waiting and return the eventual structured human response. A production Mod architecture would need that provider-neutral operation (including cancellation and process-loss semantics) before it could claim structured-attention parity.
No production adapter or bridge code is changed by this spike.
Using the exact pinned Claude Code binary:
claude plugin validate spikes/claude-mod-harness
workers/bun/node_modules/.bin/tsc -p spikes/claude-mod-harness/tsconfig.json
claude plugin test spikes/claude-mod-harness
The expected test result is 10 pass, 0 fail with Claude Code 2.1.292.
hooks/register.ts 348 lines1import type {
2 EngineInterface,
3 Register,
4 TurnStepChunk,
5 TurnStepInput,
6} from "claude-code";
7
8const PROTOCOL = "qe_claude_mod_spike_v1";
9const COMPLETE_TOOL = "mcp__qe-control-spike__qe_complete_step";
10const ATTENTION_TOOL =
11 "mcp__qe-control-spike__qe_request_human_assistance";
12const MAX_BRIDGE_OUTPUT = 65_536;
13
14function object(value: unknown): Record<string, unknown> {
15 if (typeof value !== "object" || value === null || Array.isArray(value))
16 throw new Error("Expected an object from the QE control bridge.");
17 return value as Record<string, unknown>;
18}
19
20function parseBridgeOutput(text: string): Record<string, unknown> {
21 if (text.length > MAX_BRIDGE_OUTPUT)
22 throw new Error("QE control bridge output exceeded the spike limit.");
23 return object(JSON.parse(text));
24}
25
26function parseEffort(value: string): NonNullable<TurnStepInput["effort"]> {
27 switch (value) {
28 case "low":
29 case "medium":
30 case "high":
31 case "xhigh":
32 case "max":
33 return value;
34 default: {
35 const numeric = Number(value);
36 if (Number.isFinite(numeric) && numeric >= 0) return numeric;
37 throw new Error("QE_CLAUDE_EFFORT is invalid.");
38 }
39 }
40}
41
42function parseAllowedTools(value: string): Set<string> {
43 const parsed = JSON.parse(value);
44 if (
45 !Array.isArray(parsed) ||
46 parsed.length === 0 ||
47 !parsed.every(
48 (entry) =>
49 typeof entry === "string" && entry.length > 0 && entry.length < 256,
50 )
51 )
52 throw new Error("QE_CLAUDE_ALLOWED_TOOLS_JSON is invalid.");
53 return new Set(parsed);
54}
55
56async function runControl(
57 $: EngineInterface,
58 bridge: string,
59 operation: Record<string, unknown>,
60): Promise<Record<string, unknown>> {
61 const execution = await $.process.run([bridge, "local-control"], {
62 stdin: JSON.stringify(operation),
63 timeoutMs: 30_000,
64 });
65 if (
66 execution.exitCode !== 0 ||
67 execution.isStdoutTruncated ||
68 execution.isStderrTruncated
69 )
70 throw new Error(
71 `QE control bridge failed (${execution.exitCode}): ${execution.stderr}`,
72 );
73 return parseBridgeOutput(execution.stdout);
74}
75
76async function waitForHuman(
77 $: EngineInterface,
78 bridge: string,
79 operation: Record<string, unknown>,
80): Promise<Record<string, unknown>> {
81 const stream = $.process.spawn({
82 argv: [bridge, "local-control-wait"],
83 input: JSON.stringify(operation),
84 });
85 let stdout = "";
86 let stderr = "";
87 let item = await stream.next();
88 while (item.done !== true) {
89 if (item.value.stream === "stdout") stdout += item.value.text;
90 else stderr += item.value.text;
91 if (stdout.length + stderr.length > MAX_BRIDGE_OUTPUT) {
92 await stream.return({ code: null, signal: "SIGTERM" });
93 throw new Error("QE control bridge output exceeded the spike limit.");
94 }
95 item = await stream.next();
96 }
97 if (item.value.code !== 0 || item.value.signal !== null)
98 throw new Error(
99 `QE control bridge wait failed (${item.value.code ?? item.value.signal}): ${stderr}`,
100 );
101 return parseBridgeOutput(stdout);
102}
103
104function invalidConfigurationReason(): string {
105 return "QE Claude Mod control configuration was not initialized; refusing the model turn.";
106}
107
108export const register: Register = (on) => {
109 let ready = false;
110 let bridge = "";
111 let expectedModel = "";
112 let expectedEffort: NonNullable<TurnStepInput["effort"]> | "" = "";
113 let allowedTools = new Set<string>();
114 let observedModel: string | undefined;
115 let completionReason = "unknown";
116
117 on("session.start", async ($, e, next) => {
118 ready = false;
119 const protocol = await $.env.get("QE_CLAUDE_MOD_PROTOCOL");
120 bridge = (await $.env.get("QE_BRIDGE")) ?? "";
121 expectedModel = (await $.env.get("QE_CLAUDE_MODEL")) ?? "";
122 expectedEffort = parseEffort(
123 (await $.env.get("QE_CLAUDE_EFFORT")) ?? "",
124 );
125 allowedTools = parseAllowedTools(
126 (await $.env.get("QE_CLAUDE_ALLOWED_TOOLS_JSON")) ?? "",
127 );
128 if (protocol !== PROTOCOL || bridge.length === 0 || expectedModel.length === 0)
129 throw new Error("QE Claude Mod control environment is incomplete.");
130
131 await $.tool.register({
132 name: "qe_complete_step",
133 description:
134 "Submit the declared structured outputs to Quest Engineering. Call exactly once when the step is complete.",
135 inputSchema: {
136 type: "object",
137 properties: {
138 outputs: {
139 type: "object",
140 additionalProperties: true,
141 },
142 },
143 required: ["outputs"],
144 additionalProperties: false,
145 },
146 });
147 await $.tool.register({
148 name: "qe_request_human_assistance",
149 description:
150 "Pause for a Quest Engineering human response when blocked on a decision or information.",
151 inputSchema: {
152 type: "object",
153 properties: {
154 category: {
155 type: "string",
156 enum: [
157 "needs_input",
158 "needs_permission",
159 "needs_authentication",
160 "needs_confirmation",
161 "blocked_external",
162 "interactive_prompt",
163 "unknown_interactive_block",
164 ],
165 },
166 message: { type: "string" },
167 interaction: {
168 type: "string",
169 enum: [
170 "confirmation",
171 "text",
172 "choice",
173 "multiline_response",
174 "conversational_intervention",
175 ],
176 },
177 responseSchema: {},
178 },
179 required: ["category", "message"],
180 additionalProperties: false,
181 },
182 });
183 await $.command.register({
184 name: "qe_mod_probe",
185 description: "Report QE Mod readiness without starting a model turn.",
186 });
187 allowedTools.add(COMPLETE_TOOL);
188 allowedTools.add(ATTENTION_TOOL);
189 ready = true;
190 return next(e);
191 });
192
193 on("command.run", { command: "qe_mod_probe" }, async ($, e) => ({
194 text: JSON.stringify({ protocol: PROTOCOL, ready, interactive: false }),
195 }));
196
197 on("prompt.submit", async ($, e, next) => {
198 if (!ready) return { drop: invalidConfigurationReason() };
199 return next({
200 ...e,
201 context: [
202 ...(e.context ?? []),
203 `Quest Engineering control contract: use ${COMPLETE_TOOL} exactly once with every declared output when complete. Use ${ATTENTION_TOOL} instead of AskUserQuestion when human input is required. Do not claim completion in prose before the completion tool is accepted.`,
204 ],
205 });
206 }).catch(() => ({ drop: invalidConfigurationReason() }));
207
208 on("agent.offer", () => ({ isOffered: false })).catch(() => ({
209 isOffered: false,
210 }));
211
212 on("agent.spawn", () => ({
213 deny: "QE disables Claude subagents until their authorization and accounting semantics are implemented.",
214 })).catch(() => ({
215 deny: "QE denied a subagent because the QE policy hook failed.",
216 }));
217
218 on("tool.call", async ($, e, next) => {
219 if (!ready)
220 return { deny: "QE control configuration is not initialized." };
221 if (e.agentId)
222 return { deny: "QE does not permit tool calls from Claude subagents." };
223 if (!allowedTools.has(e.tool))
224 return { deny: `QE did not authorize tool ${e.tool}.` };
225
226 if (e.tool === COMPLETE_TOOL) {
227 const input = object(e);
228 const result = await runControl($, bridge, {
229 type: "complete_step",
230 outputs: object(input.outputs),
231 });
232 if (result.accepted !== true)
233 throw new Error("QE rejected the structured completion.");
234 return {
235 result: JSON.stringify({
236 accepted: true,
237 duplicate: result.duplicate === true,
238 semanticAccepted: result.semanticAccepted === true,
239 }),
240 };
241 }
242
243 if (e.tool === ATTENTION_TOOL) {
244 const input = object(e);
245 const result = await waitForHuman($, bridge, {
246 type: "request_human_assistance_and_wait",
247 category: input.category,
248 message: input.message,
249 ...(input.interaction === undefined
250 ? {}
251 : { interaction: input.interaction }),
252 ...(input.responseSchema === undefined
253 ? {}
254 : { responseSchema: input.responseSchema }),
255 });
256 if (result.accepted !== true || result.humanResponse === undefined)
257 throw new Error("QE did not return a human response.");
258 return { result: JSON.stringify(result.humanResponse) };
259 }
260
261 return next(e);
262 }).catch(($, e, next) => ({
263 deny: `QE tool mediation failed closed: ${next.error.kind}.`,
264 }));
265
266 on("tool.check", async ($, e, next) => {
267 if (!ready || e.agentId || !allowedTools.has(e.tool))
268 return { decision: "deny", reason: "QE exact tool policy denied this call." };
269 const lower = await next(e);
270 if (lower.decision === "deny") return lower;
271 if (e.ceiling === "ask" || e.ceiling === "deny")
272 return { decision: e.ceiling, reason: "QE preserved the managed ceiling." };
273 return { decision: "allow", reason: "QE exact tool policy allowed this call." };
274 }).catch(() => ({
275 decision: "deny",
276 reason: "QE permission mediation failed closed.",
277 }));
278
279 on("turn.start", async ($, e, next) => next(e));
280
281 on("turn.step", async function* ($, e, next) {
282 if (
283 !ready ||
284 e.model !== expectedModel ||
285 e.effort !== expectedEffort
286 )
287 return {
288 turnId: e.turnId,
289 index: e.index,
290 answer: "",
291 toolUses: [],
292 stopReason: "refusal",
293 usage: null,
294 };
295 const chunks: TurnStepChunk[] = [];
296 const downstream = next(e);
297 let item = await downstream.next();
298 while (item.done !== true) {
299 chunks.push(item.value);
300 item = await downstream.next();
301 }
302 const result = item.value;
303 if (result.usage !== null && result.usage.model !== expectedModel)
304 return {
305 turnId: e.turnId,
306 index: e.index,
307 answer: "",
308 toolUses: [],
309 stopReason: "refusal",
310 usage: result.usage,
311 };
312 for (const chunk of chunks) yield chunk;
313 return result;
314 });
315
316 on("turn.complete", async ($, e, next) => {
317 observedModel = e.usage?.model;
318 completionReason = e.reason;
319 return next(e);
320 });
321
322 on("classic.Stop", async ($, e, next) => {
323 const execution = await $.process.run([bridge, "hook", "stop"], {
324 stdin: JSON.stringify({
325 terminationReason: completionReason,
326 fullyIdle: true,
327 ...(observedModel === undefined ? {} : { modelName: observedModel }),
328 }),
329 timeoutMs: 30_000,
330 });
331 if (
332 execution.exitCode !== 0 ||
333 execution.isStdoutTruncated ||
334 execution.isStderrTruncated
335 )
336 return {
337 block:
338 "QE completion enforcement failed. Continue without repeating finished work and retry the QE completion tool.",
339 };
340 const decision = parseBridgeOutput(execution.stdout);
341 if (decision.decision === "continue")
342 return { block: String(decision.reason ?? "Continue.") };
343 return next(e);
344 }).catch(() => ({
345 block: "QE completion enforcement failed closed. Retry the QE completion tool.",
346 }));
347};
348