/**
 * Zero-LLM deliver-only webhook path (SCHED.2).
 *
 * Subscriptions declared `deliver_only: true` skip the runtime evaluator
 * entirely: the webhook body is rendered through a Mustache template
 * directly into the `NotificationRouter`. No model invocation, no dispatch
 * into the skill evaluator — sub-second response, zero LLM cost. Matches
 * Hermes's `--deliver-only` competitive feature.
 *
 * Mustache is locked to its logic-less default: no Handlebars helpers,
 * no scripting, no `Mustache.Writer` overrides that would add eval risk.
 * HTML escaping is disabled (`Mustache.escape = identity`) because the
 * downstream sink is Telegram / Discord / Slack / Claude Code chat —
 * none of which want `&amp;` substitutions. Pack authors that want HTML
 * escaping ship a downstream channel adapter that does it explicitly.
 *
 * Empty-render handling: if the rendered text trims to empty (template
 * referenced fields that were all absent / null / empty arrays), we
 * SKIP the multicast and audit as `empty_template`. Posting empty
 * messages to alerts channels is worse than dropping — it teaches users
 * to ignore the channel.
 *
 * Secret-stripping (defense-in-depth): template authors might
 * accidentally interpolate `{{api_key}}` or `{{token}}` from a payload
 * that carries credentials. A post-render regex pass redacts likely
 * secret-bearing key/value pairs before the text leaves this module.
 *
 * Imports from: mustache, ../channels/router.js, ./webhook_subscriptions.js.
 * Imported by: src/runtime/webhook_server.ts (via daemon wiring).
 */
import type { MulticastResult, NotificationRouter } from '../channels/router.js';
import type { RoutingConfig } from '../channels/types.js';
import type { Subscription } from './webhook_subscriptions.js';
export interface DeliverOnlyAuditPayload {
    subscriptionId: string;
    pack: string;
    receivedAt: string;
    rendered: boolean;
    reason?: 'empty_template' | 'multicast_error' | 'misconfigured';
    emptyFieldCount?: number;
    redactedSecrets?: number;
    multicast?: MulticastResult;
}
export type DeliverOnlyAuditSink = (entry: DeliverOnlyAuditPayload) => void;
export interface DeliverOnlyResult {
    rendered: boolean;
    text?: string;
    reason?: 'empty_template' | 'multicast_error' | 'misconfigured';
    multicast?: MulticastResult;
    emptyFieldCount: number;
    redactedSecrets: number;
}
/**
 * Render `sub.template` against `body` and multicast through `router`.
 * Returns the rendered + multicast result; the caller decides response
 * shape (the webhook server always returns 200 — partial-success
 * surfaces in the audit log, never the HTTP status).
 *
 * Pre-condition: caller has verified `sub.deliverOnly === true`.
 */
export declare function handleDeliverOnly(sub: Subscription, body: unknown, router: NotificationRouter, routing: RoutingConfig): Promise<DeliverOnlyResult>;
/** Defense-in-depth: redact obvious secret-bearing patterns from the
 *  rendered text. Returns the (possibly mutated) text + redaction count. */
export declare function stripSecrets(text: string): {
    text: string;
    redactedSecrets: number;
};
//# sourceMappingURL=deliver_only.d.ts.map