/**
 * `ensure_umbrella_topic` primitive (T-CHAT-AS-TERMINAL CAT.7 — SessionStart
 * topic assurance, umbrella-level ≤1 topic).
 *
 * The SECOND consumer of the SessionStart hook mechanism (HH6.1) and the FIRST
 * one sanctioned to take an ACTION on `session_start`. Where
 * `check_chat_connection` is REPORT-ONLY, CAT.7 — under the remote-terminal
 * override [[project_opensquid_chat_is_remote_terminal]] — guarantees the
 * session's UMBRELLA owns exactly one telegram forum topic so inbound/outbound
 * chat lands in an isolated thread.
 *
 * The assurance, on `session_start`:
 *
 *   1. Resolve cwd → umbrella via `loadChannelsConfig` + `resolveUmbrellaForCwd`.
 *      - cwd in NO umbrella  → NO-OP. We never fabricate an umbrella row; that
 *        is the setup wizard's job. The session simply has no chat binding.
 *   2. Inspect the resolved umbrella's `telegram` binding:
 *      - already has a `topic_id`  → NO-OP (use the existing one topic). This is
 *        the umbrella-level ≤1:1 invariant in action: an opensquid-cwd session
 *        and a loop-cwd session both resolve to the SAME loop umbrella row, so
 *        the second session sees `topic_id` already set and NEVER creates a 2nd.
 *      - no `telegram` binding at all (no `chat_id`)  → NO-OP. Nothing to attach
 *        a topic to; the wizard hasn't wired the supergroup yet.
 *      - has `chat_id` but NO `topic_id`  → the ZERO-topic case: proceed.
 *   3. Gate on the chat-daemon being LIVE (a `ping` over its socket). No daemon
 *      → NO-OP. The assurance only runs when chat is live (a live remote
 *      terminal); we never spawn the daemon here.
 *   4. Create EXACTLY ONE topic via the daemon `create_topic` RPC
 *      ({platform:'telegram', chat_id, name} → {message_thread_id, name}), with
 *      an umbrella-derived name, then write `topic_id` back into THAT umbrella's
 *      row in `channels.json` via an atomic write that preserves every other
 *      field/row. Once `topic_id` is set, step 2 makes every subsequent run a
 *      no-op — idempotent, ≤1 topic per umbrella by construction.
 *
 * Fail-quiet: every failure mode (no daemon, RPC error, IO error, malformed
 * config) returns `ok(null)` and NEVER blocks session start. CAT.7 emits no
 * inject_context — it is a pure side-effecting assurance, so `null` (the
 * no-verdict branch) is the only return.
 *
 * Seams (test injection, no socket / no Telegram in unit tests):
 *   - `createTopic`  — the daemon `create_topic` RPC dial. Default dials the
 *     daemon socket one-shot (mirrors `chat_send.ts defaultDaemonSend`).
 *   - `daemonRunning` — the live-daemon gate. Default `ping`s the socket.
 *   - `now`          — clock (unused today; reserved for name stamping).
 *
 * Imports from: zod, node:net, node:os, node:path, ../channels/routing.js,
 *   ../runtime/atomic_write.js, ../runtime/result.js.
 * Imported by: src/runtime/bootstrap.ts (registry wiring).
 */
import type { FunctionRegistry } from './registry.js';
/** The daemon `create_topic` RPC: chat_id + name → the new thread id. */
export type CreateTopicFn = (args: {
    chatId: string;
    name: string;
}) => Promise<{
    message_thread_id: number;
    name: string;
}>;
/** The live-daemon gate: true iff a chat-daemon answers on its socket. */
export type DaemonRunningFn = () => Promise<boolean>;
export interface EnsureUmbrellaTopicDeps {
    createTopic?: CreateTopicFn;
    daemonRunning?: DaemonRunningFn;
}
export declare function registerEnsureUmbrellaTopicFunction(registry: FunctionRegistry, deps?: EnsureUmbrellaTopicDeps): void;
//# sourceMappingURL=ensure_umbrella_topic.d.ts.map