/** * Operator report-run wiring + tool-use audit (M3 "Operator Hands"). * * PURE half (this file, Task 1): classify the gateway tools the persona agent actually EXECUTED * during a report. Claude text-gateway calls and Codex native host calls are both recorded by * AgentLoop as assistant tool_use followed by user tool_result history entries. We pair * tool_use.id with its tool_result and count executions only - errored results and envelope * denials ("success":false / * envelope_missing, gateway-tool-executor.ts:1090-1142) do NOT count. History is read * structurally (no agent-internal imports) so the audit is trivially unit-testable. * * The audit powers two M3 guarantees: * - no-fallback (GAP 1): a FULL report that EXECUTED no gateway gather tool (none emitted, or * every call denied/errored) is WARNED loudly, never silently accepted as if it had * task-board substance. * - observability (GAP 2): every write (mama_save) is logged loudly. * * ASCII-only. No personal strings. */ import type { AskAgent } from './trigger-author.js'; import type { ArtifactProvenance } from './report-carry.js'; /** Dedicated persona session lane for operator reports; isolates the multi-turn gather loop from * chat. runWithContent honors options.sessionKey (agent-loop.ts:879). */ export declare const OPERATOR_REPORT_SESSION_KEY = "operator:report"; /** * Gateway READ tools classified as gathers for the run audit. This is the * classification SUPERSET, not the instruction list: since the 2026-07-30 * native-board flip the gather instructs `task_list` and the four * `kagemusha_*` tools are granted-but-silent (owner's personal deployment * only - the lane-wiring test pins that split). */ export declare const GATHER_TOOLS: Set; /** Gateway WRITE tools. mama_save is the M3 hand; the rest are classified only for honest * observability if they ever appear (report_publish/wiki_publish are NOT instructed in M3 - * see plan finding F6). */ export declare const WRITE_TOOLS: Set; /** * Strip the `mcp____` prefix an MCP transport puts on tool names. * * Measured on the live install, 2026-07-29: every full report logged * "agent executed NO gateway gather tools - task-board substance NOT verified" while the * SAME run's trace rows showed task_list, trello_search, context_compile and * kagemusha_messages executing. The audit compared `block.name === 'code_act'` and the * history carried `mcp__code-act__code_act`, so the branch never ran, hostToolsInvoked was * never parsed, and the gather set stayed empty. The warning was not observing a silent * report - it was the audit failing to recognise the transport, and saying so in the report's * own voice every single time. */ export declare function stripMcpPrefix(name: string): string; /** Minimal structural view of AgentLoopResult.history (types.ts:1105). Structural on purpose: * keeps this module free of agent-internal imports so tests use plain synthetic objects. */ export interface ReportHistoryMessage { role: string; content: unknown; } export interface ReportToolAudit { gatherTools: string[]; writeTools: string[]; all: string[]; } /** Pair assistant tool_use blocks with their tool_result and classify EXECUTIONS as gather vs * write. `all` inventories every emission (executed or not) for honest logging. */ export declare function summarizeReportToolUse(history: ReadonlyArray): ReportToolAudit; /** * Build the operator-log lines for one report. * isFullReport gates the no-fallback gather WARNING (only the FULL report is instructed to gather; * the digest is intentionally tool-free, so absence of gather tools there is normal). */ export declare function formatReportToolAudit(audit: ReportToolAudit, isFullReport: boolean): string[]; export interface PersonaReportRunResult { response: string; history: ReadonlyArray; /** The run that produced this text. Absent when the backend records no run. */ modelRunId?: string | null; /** Set by the agent loop when a run existed but its handle could not be committed. */ modelRunProvenance?: string; } /** E = the envelope type; generic keeps this module free of agent/envelope imports while start.ts * gets full inference (no casts): E is inferred from the injected issuer's return type. */ export interface PersonaReportRunner { (prompt: string, envelope?: E): Promise; } export interface PersonaReportAskDeps { run: PersonaReportRunner; log: (line: string) => void; /** Marker that identifies a FULL report prompt (situation-report.OPERATOR_FULL_REPORT_TAG). */ fullReportTag: string; /** * Issue a per-report scoped worker envelope. Gateway 'model_tool' executions are envelope-gated * (gateway-tool-executor.ts:252-256): without an envelope every call is denied with code * 'envelope_missing' (:1090-1142). Injected from start.ts (envelopeAuthority.buildAndPersist); * omit ONLY when issuance mode is 'off'. Failures propagate (no-fallback). */ issueEnvelope?: () => Promise; /** * Receives the provenance of each composed report, so the delivered artifact can record * what produced it. The runner already knows this and the boundary used to drop it on * the floor - the report went out and nothing downstream could say which run stood * behind it, which is the same defect the gateway turn seam had. */ onRunProvenance?: (provenance: ArtifactProvenance) => void; } /** * Build the report-composition AskAgent (M3). Envelope-first: gateway 'model_tool' executions are * envelope-gated (gateway-tool-executor.ts:252-256), so issue the per-report scoped envelope * BEFORE running - without one every call is denied with code 'envelope_missing' (:1090-1142), * the enforcement that killed the ancestor scheduled-report path. Issuance failure propagates * loudly (no-fallback; the buffer is kept and the next cadence retries). Then run the persona * agent (injected runner isolates the report into its own session lane and carries the envelope), * audit + log the gateway tools it actually EXECUTED (no-fallback WARNING when a full report * executed none; observability line for every write), and enforce the empty-report guard * (M2 semantics). */ export declare function createPersonaReportAsk(deps: PersonaReportAskDeps): AskAgent; /** Last non-empty assistant TEXT across the run history (structural walk; text * blocks on the gateway path carry prose only - tool_call JSON is parsed out * before history assembly, agent-loop.ts removeToolCallBlocks). */ export declare function lastAssistantText(history: ReadonlyArray): string; //# sourceMappingURL=report-run.d.ts.map