import express from "express";
import { type GuestIdentity } from "./services/access_policy.js";
import { type AgentIdentity } from "./crypto/agent_identity.js";
import { type StoreInterpretationInput } from "./shared/action_schemas.js";
export declare const app: import("express-serve-static-core").Express;
/**
 * Returns true when the given IP is within the configured NEOTOMA_TRUSTED_PROXY_IPS.
 * Supports exact IPv4 match, IPv4 /8–/32 CIDR notation, and ::ffff:<ipv4> mapped addresses.
 * When NEOTOMA_TRUSTED_PROXY_IPS is not set this always returns false.
 */
export declare function isTrustedProxyIP(ip: string, env?: NodeJS.ProcessEnv): boolean;
/**
 * True when the request is genuinely local to this process.
 *
 * SECURITY: a same-host reverse proxy (Caddy, nginx, Cloudflare tunnel, etc.)
 * connects to Node over loopback even for public internet callers. In
 * production, loopback alone is therefore not enough to grant local-dev auth.
 *
 * NEOTOMA_TRUSTED_PROXY_IPS: comma-separated list of IPs or IPv4 CIDRs whose
 * XFF entries are trusted and do not disqualify a loopback-socket request from
 * being considered local. Use this for tunnel setups where cloudflared (or
 * similar) injects a non-loopback XFF entry that represents a controlled
 * internal hop, not a public internet caller.
 *
 * The XFF IP that cloudflared injects depends on its forwarding mode:
 * - Warp / CGNAT mode: typically 100.64.x.x (CGNAT range, NEOTOMA_TRUSTED_PROXY_IPS=100.64.0.0/10)
 * - Passthrough mode: the upstream client IP (Vercel egress, CDN edge, etc.)
 *
 * To find the actual IP: start the server, make a request through the tunnel,
 * and check Neotoma stderr for "isLocalRequest rejected: XFF contains <ip>".
 * Set NEOTOMA_TRUSTED_PROXY_IPS to that IP or its enclosing CIDR.
 *
 * NEOTOMA_TRUSTED_PROXY_IPS and NEOTOMA_TRUST_PROD_LOOPBACK=1 are independent
 * and can coexist. NEOTOMA_TRUST_PROD_LOOPBACK=1 bypasses the XFF check
 * entirely and remains valid for single-host deployments without a tunnel.
 */
export declare function isLocalRequest(req: express.Request): boolean;
/**
 * Derive the canonical `@authority` the AAuth profile requires (AAuth §10.3.1).
 * We trust explicit configuration first, then fall back to the host the
 * process is actually listening on. We must NOT trust `Host:` headers from
 * the request path — an attacker could smuggle signatures authored against
 * a different authority. See src/middleware/aauth_verify.ts.
 */
export declare function canonicalAauthAuthority(): string;
type UserPrincipal = {
    kind: "user";
    userId: string;
};
type GuestPrincipal = {
    kind: "guest";
    guestId: GuestIdentity;
    agentIdentity?: AgentIdentity | null;
    accessToken?: string;
};
type RoutePrincipal = UserPrincipal | GuestPrincipal;
/** Exported for unit tests: routes where guest (AAuth / guest token) may be stamped before handlers run. */
export declare function routeAcceptsGuestPrincipal(req: Pick<express.Request, "method" | "path">): boolean;
/** Exported for unit tests: guest-capable routes that mutate state and should consume a guest write-rate budget. */
export declare function routeConsumesGuestWriteBudget(req: Pick<express.Request, "method" | "path">): boolean;
/** Exported for unit tests: guest-rate-limit key precedence is thumbprint -> guest token -> IP. */
export declare function guestWriteRateLimitKey(req: express.Request): string;
/**
 * Derive a userId for a guest principal from the validated token grant.
 *
 * Resolution order:
 *   1. `(req as any).authenticatedUserId` — set by earlier auth middleware
 *      (covers the rare case where user-level auth was stamped before the
 *      guest branch).
 *   2. The `user_id` stored on the `guest_access_token` entity that matches
 *      the guest's access token. This is the owner who generated the token.
 *   3. Local-only fallback: when the request originates from localhost and
 *      does not carry a Bearer token, use the local dev user. This keeps
 *      local-only developer flows working without a real token grant.
 *
 * Returns `null` for non-guest principals so callers can fall through to
 * `getAuthenticatedUserId`. Throws for remote/hosted guests that cannot
 * be resolved — prevents silent mis-attribution.
 */
export declare function resolveGuestUserId(req: express.Request, principal: RoutePrincipal): Promise<string | null>;
type StoreRelationshipRef = {
    relationship_type: string;
    source_index?: number;
    target_index?: number;
    source_entity_id?: string;
    target_entity_id?: string;
    metadata?: Record<string, unknown>;
};
export declare function storeStructuredForApi(params: {
    userId: string;
    entities: Record<string, unknown>[];
    sourcePriority: number;
    observationSource?: import("./shared/action_schemas.js").ObservationSource;
    /** When set, written observations carry this peer id for sync loop prevention. */
    sourcePeerId?: string | null;
    idempotencyKey: string;
    originalFilename?: string;
    relationships?: StoreRelationshipRef[];
    interpretation?: StoreInterpretationInput;
    interpretationSourceId?: string;
    commit?: boolean;
    strict?: boolean;
}): Promise<{
    success: boolean;
    replayed: boolean;
    source_id: any;
    entities_created: number;
    observations_created: number;
    entities: {
        entity_id: string;
        entity_type: string;
        observation_id: string;
    }[];
} | {
    store_warnings?: {
        code: string;
        message: string;
        observation_index: number;
        entity_type: string;
        entity_id: string;
    }[] | undefined;
    warnings?: {
        code: string;
        policy: string;
        observation_index: number;
        entity_type: string;
        entity_id: string;
        identity_basis: string;
        identity_rule: string;
    }[] | undefined;
    entities_created: number;
    observations_created: number;
    entities: {
        entity_id: string;
        entity_type: string;
        observation_id: string | null;
        observation_index: number;
        action: "created" | "matched_existing" | "would_create" | "would_match_existing" | "extended";
        canonical_name: string;
        resolver_path: string[];
        identity_basis: string;
        identity_rule: string;
        warnings?: {
            code: string;
            policy: string;
            entity_type: string;
            identity_basis: string;
            identity_rule: string;
        }[] | undefined;
        entity_snapshot_after: Record<string, unknown> | null;
    }[];
    relationships_created: {
        relationship_type: string;
        source_entity_id: string;
        target_entity_id: string;
    }[];
    interpretation_id?: string | undefined;
    interpretation_source_id?: string | undefined;
    success: boolean;
    replayed: boolean;
    commit: boolean;
    source_id: string | null;
}>;
export declare function startHTTPServer(): Promise<{
    server: import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
    port: number;
} | undefined>;
export {};
//# sourceMappingURL=actions.d.ts.map