@sanctuary-framework/mcp-server 1.0.0-rc.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
3
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
4
4
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
5
+ import { Writable } from 'node:stream';
5
6
 
6
7
  interface SanctuaryConfig {
7
8
  version: string;
@@ -68,6 +69,12 @@ interface SanctuaryConfig {
68
69
  /** Whether to auto-publish on successful handshake_respond calls. */
69
70
  auto_publish_handshakes: boolean;
70
71
  };
72
+ privacy_filter: {
73
+ mode: "local" | "opf" | "off";
74
+ fail_mode: "closed" | "fallback";
75
+ command: string;
76
+ timeout_ms: number;
77
+ };
71
78
  }
72
79
  /**
73
80
  * Load configuration from file, falling back to defaults.
@@ -761,6 +768,28 @@ interface EncryptedPayload {
761
768
  * - Secure deletion overwrites before unlinking
762
769
  */
763
770
 
771
+ /** On-disk format for an encrypted state entry */
772
+ interface StateEntry {
773
+ /** Format version */
774
+ v: number;
775
+ /** Encrypted payload */
776
+ payload: EncryptedPayload;
777
+ /** Version number (monotonically increasing) */
778
+ ver: number;
779
+ /** Signature over ciphertext by the writing identity (base64url) */
780
+ sig: string;
781
+ /** Identity that wrote this entry */
782
+ kid: string;
783
+ /** SHA-256 of the plaintext value (base64url, for client-side verification) */
784
+ integrity_hash: string;
785
+ /** Metadata */
786
+ metadata: {
787
+ content_type?: string;
788
+ ttl_seconds?: number;
789
+ tags?: string[];
790
+ written_at: string;
791
+ };
792
+ }
764
793
  /** Result of a state write operation */
765
794
  interface WriteResult {
766
795
  key: string;
@@ -2122,6 +2151,109 @@ declare const MODEL_PRESETS: {
2122
2151
  mistral7bLocal: () => ModelProvenance;
2123
2152
  };
2124
2153
 
2154
+ /**
2155
+ * Signature scheme identifier embedded on every signed v1.1 record.
2156
+ *
2157
+ * v1.1 only accepts "ed25519-v1". Mirrors the mesh module: this field is the
2158
+ * forward-compat hinge for v1.4+ post-quantum migration. Verifiers MUST reject
2159
+ * unknown schemes. Do not optimize this field away.
2160
+ *
2161
+ * Mirror of: server/src/mesh/constants.ts SignatureScheme.
2162
+ */
2163
+ type SignatureScheme = "ed25519-v1";
2164
+ /**
2165
+ * Detector classes for the privacy filter. Workstreams MUST use this enum so
2166
+ * the dashboard privacy panel and audit consumers can group consistently.
2167
+ *
2168
+ * "custom" is reserved for operator-defined detectors via policy.
2169
+ */
2170
+ declare const PRIVACY_DETECTOR_CLASSES: readonly ["person", "client", "project", "secret", "credential", "account", "file_path", "domain_term", "custom"];
2171
+ type PrivacyDetectorClass = (typeof PRIVACY_DETECTOR_CLASSES)[number];
2172
+ /**
2173
+ * Outbound destination categories. The privacy filter and the remote-bound
2174
+ * enforcement workstream agree on this enum so events compose end-to-end.
2175
+ *
2176
+ * Categories deliberately mirror the L2 `ProviderCategory` taxonomy in
2177
+ * `server/src/l2-operational/context-gate.ts` (hyphen form) so JSON-stable
2178
+ * strings flow through both layers without translation. If the L2 category
2179
+ * set grows, keep this v1.1 list in lockstep through coordinator review.
2180
+ */
2181
+ declare const PRIVACY_DESTINATION_CATEGORIES: readonly ["inference", "tool-api", "logging", "analytics", "peer-agent", "custom"];
2182
+ type PrivacyDestinationCategory = (typeof PRIVACY_DESTINATION_CATEGORIES)[number];
2183
+ /**
2184
+ * Privacy actions taken on a single field. Uses the L2 vocabulary.
2185
+ *
2186
+ * "rehydrate" is v1.1-new and applies to inbound responses, not outbound calls.
2187
+ */
2188
+ declare const PRIVACY_ACTIONS: readonly ["allow", "redact", "hash", "summarize", "deny", "rehydrate"];
2189
+ type PrivacyAction = (typeof PRIVACY_ACTIONS)[number];
2190
+ /**
2191
+ * Hash algorithm identifier embedded in every privacy event content_hash.
2192
+ *
2193
+ * v1.1 ships ONLY `hmac-sha256-fortress-keyed-v1`: HMAC-SHA-256 over the
2194
+ * raw field value, using a per-fortress secret derived from the master key
2195
+ * via HKDF info string `sanctuary-v1.1-privacy-content-hmac`. Plain SHA-256
2196
+ * is NOT permitted because privacy field values (PII, project names, client
2197
+ * names, file paths) are low-entropy and dictionary-attackable. The keyed
2198
+ * hash makes content hashes meaningful for equality checks across events
2199
+ * within a fortress while remaining opaque to anyone without the per-
2200
+ * fortress key.
2201
+ *
2202
+ * Forward-compat: a future v1.x privacy hardening pass may add ML-DSA-keyed
2203
+ * variants. Verifiers MUST reject unknown algorithms.
2204
+ */
2205
+ declare const PRIVACY_HASH_ALGS: readonly ["hmac-sha256-fortress-keyed-v1"];
2206
+ type PrivacyHashAlg = (typeof PRIVACY_HASH_ALGS)[number];
2207
+ /**
2208
+ * Exit-bundle manifest version. v1 is the only valid value at v1.1 ship.
2209
+ * v1.x bumps require coordinator-approved manifest amendment.
2210
+ */
2211
+ declare const EXIT_BUNDLE_MANIFEST_VERSION: "SANCTUARY_EXIT_BUNDLE_V1";
2212
+ type ExitBundleManifestVersion = typeof EXIT_BUNDLE_MANIFEST_VERSION;
2213
+ /**
2214
+ * Artifact kinds enumerated by the exit-bundle manifest. The export command
2215
+ * MUST list every included artifact under one of these kinds. The verifier
2216
+ * CLI rejects unknown kinds.
2217
+ */
2218
+ declare const EXIT_BUNDLE_ARTIFACT_KINDS: readonly ["public_identity", "encrypted_state", "policy_set", "audit_receipts", "reputation_bundle", "commitments", "placeholder_vault_metadata"];
2219
+ type ExitBundleArtifactKind = (typeof EXIT_BUNDLE_ARTIFACT_KINDS)[number];
2220
+
2221
+ /**
2222
+ * Lightweight local privacy filter for outbound context.
2223
+ *
2224
+ * This is not a replacement for a full detector such as OpenAI privacy-filter.
2225
+ * It gives Sanctuary a deterministic baseline that catches common high-risk
2226
+ * spans inside otherwise-allowed fields, so policy gates are not limited to
2227
+ * top-level field names.
2228
+ */
2229
+
2230
+ type PrivacySpanClass = "email" | "phone" | "ssn" | "credit_card" | "secret_assignment" | "secret" | "credential" | "account_number" | "address" | "person" | "client" | "project" | "file_path" | "domain_term" | "url" | "date" | "custom";
2231
+ declare class PrivacyPlaceholderVault {
2232
+ private storage;
2233
+ private encryptionKey;
2234
+ private lookupKey;
2235
+ private cache;
2236
+ private pathCache;
2237
+ constructor(storage: StorageBackend, masterKey: Uint8Array);
2238
+ placeholderFor(spanClass: PrivacySpanClass, rawValue: string, scope?: string): Promise<string>;
2239
+ resolvePlaceholder(placeholder: string, scope?: string): Promise<string | null>;
2240
+ aliasForFieldPath(path: string, scope?: string): Promise<string>;
2241
+ resolveFieldPathAlias(alias: string, scope?: string): Promise<string | null>;
2242
+ private recordKey;
2243
+ private indexKey;
2244
+ private pathRecordKey;
2245
+ private pathIndexKey;
2246
+ private readIndex;
2247
+ private writeIndex;
2248
+ private readRecord;
2249
+ private writeRecord;
2250
+ private readPathIndex;
2251
+ private writePathIndex;
2252
+ private readPathRecord;
2253
+ private writePathRecord;
2254
+ private hmacString;
2255
+ }
2256
+
2125
2257
  /**
2126
2258
  * Sanctuary MCP Server — L2 Context Gating: Automatic Enforcer
2127
2259
  *
@@ -2170,9 +2302,10 @@ interface EnforcerStatus {
2170
2302
  declare class ContextGateEnforcer {
2171
2303
  private policyStore;
2172
2304
  private auditLog;
2305
+ private privacyVault?;
2173
2306
  private config;
2174
2307
  private stats;
2175
- constructor(policyStore: ContextGatePolicyStore, auditLog: AuditLog, config: EnforcerConfig);
2308
+ constructor(policyStore: ContextGatePolicyStore, auditLog: AuditLog, config: EnforcerConfig, privacyVault?: PrivacyPlaceholderVault);
2176
2309
  /**
2177
2310
  * Wrap a tool handler to apply automatic context gating.
2178
2311
  *
@@ -2274,6 +2407,9 @@ interface UpstreamServer {
2274
2407
  tool_overrides?: Record<string, {
2275
2408
  tier: 1 | 2 | 3;
2276
2409
  }>;
2410
+ destination_category?: "inference" | "tool-api" | "logging" | "analytics" | "peer-agent" | "custom";
2411
+ privacy_policy_id?: string;
2412
+ privacy_identity_id?: string;
2277
2413
  }
2278
2414
  interface SovereigntyProfile {
2279
2415
  version: 1;
@@ -2581,6 +2717,483 @@ declare class CallGovernor {
2581
2717
  private pruneDuplicateCache;
2582
2718
  }
2583
2719
 
2720
+ /**
2721
+ * Sanctuary v1.1 — Privacy Audit Payload Contracts
2722
+ *
2723
+ * Shared payload shapes emitted by the privacy core (Prompt 3) and consumed by
2724
+ * the remote-bound enforcement workstream (Prompt 4), the operator hub API
2725
+ * (Prompt 5), and the dashboard privacy panel (Prompt 8).
2726
+ *
2727
+ * Local-only invariant:
2728
+ * Payloads describe outbound traffic from a single fortress on a single
2729
+ * operator's machine. v1.1 ships local-only, single-operator scope.
2730
+ *
2731
+ * Enclosure-and-signing model:
2732
+ * Privacy events are NOT signed objects on their own. They are payloads
2733
+ * carried inside an enclosing audit-chain entry (`l2-operational/audit-log`
2734
+ * AuditEntry encrypted-at-rest under L1, plus `mesh/audit-batch`
2735
+ * SignedAuditBatch where federation propagation applies). The enclosing
2736
+ * audit entry carries the signature scheme; this file deliberately does not
2737
+ * declare a signature field on any payload type.
2738
+ *
2739
+ * When an enforcement path emits a privacy event:
2740
+ * 1. Build a `PrivacyAuditPayload` from this file.
2741
+ * 2. Append it as the `details` (or equivalent payload field) of an
2742
+ * `AuditEntry` in the L2 audit log.
2743
+ * 3. The mesh-layer batch envelope (`SIGNATURE_SCHEME_V1`) signs the
2744
+ * batch that carries this entry.
2745
+ *
2746
+ * Safe-metadata invariant:
2747
+ * Raw sensitive content MUST NEVER appear in any field of any payload defined
2748
+ * in this file. Only safe metadata is permitted: detector class, field path,
2749
+ * action, content hash, policy id, destination category, identity id,
2750
+ * placeholder labels.
2751
+ *
2752
+ * If a future workstream needs to surface a sensitive value to the operator,
2753
+ * it MUST go through the encrypted placeholder vault — not through these
2754
+ * payload shapes.
2755
+ */
2756
+
2757
+ /**
2758
+ * Common metadata header on every v1.1 privacy audit payload.
2759
+ *
2760
+ * `event_id` is the audit-chain id assigned by the enclosing AuditEntry.
2761
+ * `policy_id` is the bound privacy policy that produced the decision.
2762
+ * `identity_id` is the operator identity the policy is bound to.
2763
+ */
2764
+ interface PrivacyAuditPayloadHeader {
2765
+ /** v1.1 payload-shape version. */
2766
+ version: "1.1";
2767
+ /** Unique event id; SHOULD match the enclosing audit-chain id. */
2768
+ event_id: string;
2769
+ /** ISO8601 timestamp of the decision. */
2770
+ emitted_at: string;
2771
+ /** Policy id that produced this decision. */
2772
+ policy_id: string;
2773
+ /** Identity the policy is bound to. */
2774
+ identity_id: string;
2775
+ /** Wrapped agent the outbound traffic originates from. */
2776
+ agent_id: string;
2777
+ /** Destination category for the outbound payload. */
2778
+ destination_category: PrivacyDestinationCategory;
2779
+ }
2780
+ /**
2781
+ * Per-field decision recorded inside a privacy audit payload. Field-level
2782
+ * decisions bubble up into the rolled-up payload kinds below.
2783
+ *
2784
+ * Path-and-hash safety:
2785
+ * `field_path` MUST be sanitized — see `PRIVACY_FIELD_PATH_PATTERN` in
2786
+ * constants.ts. Raw object keys (which can themselves leak sensitive
2787
+ * information) MUST NOT appear on the wire. `content_hash` MUST use a keyed
2788
+ * hash algorithm (`hmac-sha256-fortress-keyed-v1` at v1.1) to defeat
2789
+ * dictionary attacks against low-entropy field values.
2790
+ */
2791
+ interface PrivacyFieldDecision {
2792
+ /**
2793
+ * Sanitized field path. Conforms to `PRIVACY_FIELD_PATH_PATTERN`:
2794
+ * positional references like "$0" / "$1.$2" or typed positional like
2795
+ * "obj:0" / "key:1.val:0". The fortress-local mapping back to the real
2796
+ * path is held in the placeholder vault. Real object keys MUST NOT
2797
+ * appear here.
2798
+ */
2799
+ field_path: string;
2800
+ /** Detector class that fired on this field. */
2801
+ detector_class: PrivacyDetectorClass;
2802
+ /** Action taken on this field. */
2803
+ action: PrivacyAction;
2804
+ /**
2805
+ * Keyed hash of the original field value. Hex-encoded.
2806
+ * Algorithm pinned via `hash_alg`; v1.1 only accepts
2807
+ * `hmac-sha256-fortress-keyed-v1`. The HMAC key is fortress-local
2808
+ * (HKDF-derived from the master key); equality of two `content_hash`
2809
+ * values within the same fortress means equal field values, but the
2810
+ * hash is opaque to any verifier outside the fortress and resists
2811
+ * dictionary attacks against low-entropy values. Plain SHA-256 is NOT
2812
+ * permitted. The original value MUST NOT appear anywhere in the payload.
2813
+ */
2814
+ content_hash: string;
2815
+ /** Hash algorithm identifier. v1.1 only accepts the keyed HMAC variant. */
2816
+ hash_alg: PrivacyHashAlg;
2817
+ /**
2818
+ * Stable placeholder label this field was substituted with on the outbound
2819
+ * payload, if applicable. Examples: "PERSON_1", "CLIENT_3", "SECRET_2".
2820
+ */
2821
+ placeholder_label?: string;
2822
+ }
2823
+ /**
2824
+ * Outbound payload was filtered. At least one field was redacted, hashed, or
2825
+ * substituted with a placeholder, and the call proceeded.
2826
+ */
2827
+ interface PrivacyFilteredPayload extends PrivacyAuditPayloadHeader {
2828
+ kind: "filtered";
2829
+ field_decisions: PrivacyFieldDecision[];
2830
+ /**
2831
+ * Keyed hash of the canonicalized outbound payload after filtering.
2832
+ * Same `hash_alg` constraint as `PrivacyFieldDecision.content_hash`.
2833
+ */
2834
+ outbound_payload_hash: string;
2835
+ /** Hash algorithm. v1.1 only accepts `hmac-sha256-fortress-keyed-v1`. */
2836
+ payload_hash_alg: PrivacyHashAlg;
2837
+ }
2838
+ /**
2839
+ * Outbound payload was allowed unchanged. No detector fired, or every fired
2840
+ * detector resolved to "allow" under the bound policy.
2841
+ */
2842
+ interface PrivacyAllowedPayload extends PrivacyAuditPayloadHeader {
2843
+ kind: "allowed";
2844
+ /**
2845
+ * Keyed hash of the canonicalized outbound payload.
2846
+ * Same `hash_alg` constraint as `PrivacyFieldDecision.content_hash`.
2847
+ */
2848
+ outbound_payload_hash: string;
2849
+ /** Hash algorithm. v1.1 only accepts `hmac-sha256-fortress-keyed-v1`. */
2850
+ payload_hash_alg: PrivacyHashAlg;
2851
+ }
2852
+ /**
2853
+ * Outbound payload was denied. Either a "deny" rule fired on a field, or the
2854
+ * fail-closed default applied because the policy or vault was unavailable.
2855
+ *
2856
+ * The `denial_reason_class` is a machine-friendly label, NOT a free-text
2857
+ * explanation. Operator-facing UIs may render a generic message keyed by this
2858
+ * label; raw policy-rule details MUST NOT be revealed.
2859
+ */
2860
+ interface PrivacyDeniedPayload extends PrivacyAuditPayloadHeader {
2861
+ kind: "denied";
2862
+ /**
2863
+ * Coarse denial reason class. Permitted values:
2864
+ * - "policy_deny_rule" — at least one field had a deny rule
2865
+ * - "fail_closed_no_policy" — fail-closed because policy missing
2866
+ * - "fail_closed_filter_error" — fail-closed because filter raised
2867
+ * - "fail_closed_vault_error" — fail-closed because vault unavailable
2868
+ * - "operator_override_denied" — explicit operator override path failed
2869
+ */
2870
+ denial_reason_class: "policy_deny_rule" | "fail_closed_no_policy" | "fail_closed_filter_error" | "fail_closed_vault_error" | "operator_override_denied";
2871
+ }
2872
+ /**
2873
+ * Privacy filter raised an unrecoverable error and outbound traffic failed
2874
+ * closed. Distinct from PrivacyDeniedPayload because the operator may want to
2875
+ * surface error events as alerts rather than as policy decisions.
2876
+ */
2877
+ interface PrivacyErrorPayload extends PrivacyAuditPayloadHeader {
2878
+ kind: "error";
2879
+ /** Stable error code. Implementation-specific catalog. No raw stack traces. */
2880
+ error_code: string;
2881
+ }
2882
+ /**
2883
+ * Inbound provider response was rehydrated using the placeholder vault. Only
2884
+ * fires when the bound policy permits rehydration for the destination category.
2885
+ */
2886
+ interface PrivacyRehydratedPayload extends PrivacyAuditPayloadHeader {
2887
+ kind: "rehydrated";
2888
+ /**
2889
+ * Number of placeholders successfully rehydrated. The placeholders themselves
2890
+ * are NOT logged.
2891
+ */
2892
+ rehydrated_count: number;
2893
+ /** Number of placeholders that could not be rehydrated (e.g., vault entry expired). */
2894
+ unresolvable_count: number;
2895
+ /**
2896
+ * Keyed hash of the canonicalized rehydrated response.
2897
+ * Same `hash_alg` constraint as `PrivacyFieldDecision.content_hash`.
2898
+ */
2899
+ response_hash: string;
2900
+ /** Hash algorithm. v1.1 only accepts `hmac-sha256-fortress-keyed-v1`. */
2901
+ response_hash_alg: PrivacyHashAlg;
2902
+ }
2903
+ /**
2904
+ * Discriminated union of every v1.1 privacy audit payload. The hub API and
2905
+ * dashboard privacy panel switch on `kind`. Integrity of these payloads
2906
+ * derives from the enclosing audit entry (encrypted-at-rest, plus signed at
2907
+ * the mesh-batch layer where applicable). No payload in this file carries a
2908
+ * self-signature.
2909
+ */
2910
+ type PrivacyAuditPayload = PrivacyFilteredPayload | PrivacyAllowedPayload | PrivacyDeniedPayload | PrivacyErrorPayload | PrivacyRehydratedPayload;
2911
+
2912
+ /**
2913
+ * Sanctuary v1.1 — Exit Bundle Manifest Contract
2914
+ *
2915
+ * `SANCTUARY_EXIT_BUNDLE_V1` is the canonical manifest produced by the v1.1
2916
+ * exit-bundle workstream (Prompt 7) and consumed by the standalone verifier
2917
+ * CLI plus the import command.
2918
+ *
2919
+ * Local-only invariant:
2920
+ * The bundle is produced by a single fortress on a single operator's machine
2921
+ * and consumed by another single-operator destination. v1.1 ships local-only,
2922
+ * single-operator scope. Cross-operator transfer is deferred to v1.3.
2923
+ *
2924
+ * Identity-binding invariant:
2925
+ * The manifest is signed by the operator's fortress-master identity. The
2926
+ * verifier MUST refuse to activate any artifact whose hash chain does not
2927
+ * match the manifest, and MUST refuse to activate any manifest whose
2928
+ * signature does not verify against the bound public identity.
2929
+ *
2930
+ * Public-only invariant:
2931
+ * The bundle MUST NOT contain private keys, raw passphrases, or recovery
2932
+ * seeds. Encrypted state may travel inside the bundle, but the master key
2933
+ * MUST NOT. Re-keying happens on import using new operator-supplied
2934
+ * material.
2935
+ *
2936
+ * Manifest-version invariant:
2937
+ * v1.1 ships only "SANCTUARY_EXIT_BUNDLE_V1". Future versions land through
2938
+ * coordinator-approved spec amendments. v1.1 verifiers MUST reject unknown
2939
+ * manifest versions rather than silently accept.
2940
+ */
2941
+
2942
+ /**
2943
+ * Hashing algorithm identifier embedded in every artifact entry. v1.1 uses
2944
+ * SHA-256. Forward-compat: a future bundle version may add SHA-3 or BLAKE3.
2945
+ */
2946
+ type ExitBundleHashAlg = "sha256";
2947
+ /**
2948
+ * One artifact entry inside the manifest. Each artifact lives at a relative
2949
+ * path inside the bundle archive. The verifier reads the file at that path
2950
+ * and confirms its hash. See `EXIT_BUNDLE_PATH_PATTERN` and the safe-path
2951
+ * rules block above for the full set of constraints.
2952
+ */
2953
+ interface ExitBundleArtifactEntry {
2954
+ /** Coarse artifact kind. */
2955
+ kind: ExitBundleArtifactKind;
2956
+ /**
2957
+ * Relative path inside the bundle, POSIX-style. MUST satisfy
2958
+ * `EXIT_BUNDLE_PATH_PATTERN` and the safe-path rules block above.
2959
+ * The verifier rejects any entry whose path is absolute, contains "..",
2960
+ * contains backslashes, or duplicates another entry's path. The verifier
2961
+ * does NOT follow symlinks or hardlinks during extraction.
2962
+ */
2963
+ path: string;
2964
+ /** Hash algorithm. v1.1 ships only "sha256". */
2965
+ hash_alg: ExitBundleHashAlg;
2966
+ /** Hex-encoded artifact hash. */
2967
+ hash: string;
2968
+ /** Size in bytes. Verifier MAY independently re-size and reject on mismatch. */
2969
+ size_bytes: number;
2970
+ /**
2971
+ * Optional discriminator inside the kind, e.g., "audit-receipt-2026-Q2".
2972
+ * Verifier does not interpret this; the import command may use it to order
2973
+ * artifacts. Same path-pattern constraints DO NOT apply to subkind, but
2974
+ * subkind MUST NOT contain control characters.
2975
+ */
2976
+ subkind?: string;
2977
+ }
2978
+ /**
2979
+ * Identity binding embedded in the manifest. Carries only public material.
2980
+ */
2981
+ interface ExitBundleIdentityBinding {
2982
+ /** Operator identity id. */
2983
+ identity_id: string;
2984
+ /** Fortress id. */
2985
+ fortress_id: string;
2986
+ /** Base64url-encoded Ed25519 public key of the fortress-master. */
2987
+ fortress_master_pubkey: string;
2988
+ /** Optional DID, when one is bound to this identity. */
2989
+ did?: string;
2990
+ }
2991
+ /**
2992
+ * v1 manifest body — what the operator's fortress-master signs.
2993
+ *
2994
+ * `signature_scheme` lives INSIDE the body deliberately so the scheme is
2995
+ * covered by the fortress-master signature. Without this, an attacker who
2996
+ * substituted both `signature` and `signature_scheme` on the wrapper could
2997
+ * present a valid-looking manifest with a different scheme. Pinning the
2998
+ * scheme inside the signed bytes makes the crypto-agility hinge non-
2999
+ * substitutable.
3000
+ */
3001
+ interface ExitBundleManifestBody {
3002
+ /** Manifest version constant. */
3003
+ manifest_version: ExitBundleManifestVersion;
3004
+ /** ISO8601 timestamp at export time. */
3005
+ exported_at: string;
3006
+ /** Source fortress / operator identity binding. */
3007
+ identity_binding: ExitBundleIdentityBinding;
3008
+ /**
3009
+ * Sanctuary version string at export time. Verifier surfaces version skew
3010
+ * to the operator if the destination fortress is older.
3011
+ */
3012
+ source_sanctuary_version: string;
3013
+ /** Every artifact carried in the bundle. */
3014
+ artifacts: ExitBundleArtifactEntry[];
3015
+ /**
3016
+ * Aggregate hash over canonicalize(artifacts[]). Lets the verifier perform
3017
+ * a fast sanity check before walking each entry.
3018
+ */
3019
+ artifacts_aggregate_hash: string;
3020
+ /** Aggregate hash algorithm. v1.1 ships only "sha256". */
3021
+ artifacts_aggregate_hash_alg: ExitBundleHashAlg;
3022
+ /**
3023
+ * Tier 1 audit-event id that captured the export approval. Consumers MAY
3024
+ * cross-reference with the source fortress audit chain.
3025
+ */
3026
+ export_approval_audit_id: string;
3027
+ /**
3028
+ * Signature scheme covering the wrapper's `signature` field. v1.1 ships
3029
+ * only "ed25519-v1". Embedded inside the signed body so the scheme cannot
3030
+ * be substituted independently of the signature.
3031
+ */
3032
+ signature_scheme: SignatureScheme;
3033
+ }
3034
+ /**
3035
+ * Full signed manifest. Top-level shape that ships in the bundle archive.
3036
+ *
3037
+ * The wrapper carries only the `signature` and a pointer to the body. The
3038
+ * scheme that produced the signature lives inside `body.signature_scheme`,
3039
+ * so the signature itself attests to which scheme produced it.
3040
+ */
3041
+ interface ExitBundleManifest {
3042
+ /** Body — what the signature covers. */
3043
+ body: ExitBundleManifestBody;
3044
+ /**
3045
+ * Base64url-encoded Ed25519 signature over canonicalize(body) by the
3046
+ * fortress-master private key. The bundle archive is otherwise unsigned;
3047
+ * artifact integrity comes from artifact hashes inside the body. The
3048
+ * signing scheme is `body.signature_scheme`.
3049
+ */
3050
+ signature: string;
3051
+ }
3052
+ /**
3053
+ * Verifier output shape. The standalone verifier CLI emits this structure on
3054
+ * stdout (or as JSON for tool consumers) so import commands can branch
3055
+ * cleanly. v1.1 ships one VerifierResult shape; future versions extend.
3056
+ */
3057
+ interface ExitBundleVerifierResult {
3058
+ version: "1.1";
3059
+ /** True iff manifest signature, every artifact hash, and the aggregate hash all verify. */
3060
+ passed: boolean;
3061
+ /** ISO8601 timestamp of verification. */
3062
+ verified_at: string;
3063
+ /** Reference to the verified manifest body. */
3064
+ manifest_summary: {
3065
+ manifest_version: ExitBundleManifestVersion;
3066
+ fortress_id: string;
3067
+ identity_id: string;
3068
+ exported_at: string;
3069
+ artifact_count: number;
3070
+ };
3071
+ /**
3072
+ * Per-artifact verification result. Order matches `manifest.body.artifacts`.
3073
+ */
3074
+ artifact_results: Array<{
3075
+ path: string;
3076
+ kind: ExitBundleArtifactKind;
3077
+ hash_passed: boolean;
3078
+ size_passed: boolean;
3079
+ }>;
3080
+ /**
3081
+ * Coarse failure-class enum, when `passed` is false. Distinct from a free-text
3082
+ * error message so import commands can branch.
3083
+ */
3084
+ failure_class?: "manifest_signature_invalid" | "manifest_unknown_version" | "manifest_signature_scheme_invalid" | "artifact_hash_mismatch" | "artifact_missing" | "artifact_size_mismatch" | "aggregate_hash_mismatch" | "artifact_path_unsafe" | "artifact_path_duplicate" | "artifact_path_escapes_root" | "archive_contains_symlink" | "private_material_present" | "other";
3085
+ }
3086
+
3087
+ /**
3088
+ * Sanctuary v1.1 — local query privacy core.
3089
+ *
3090
+ * This module is intentionally independent of dashboard UI and transport
3091
+ * enforcement. Enforcement paths call it with a payload, destination category,
3092
+ * identity-bound policy, and encrypted placeholder vault; the module returns a
3093
+ * filtered payload or a fail-closed denial plus a shared privacy audit payload.
3094
+ */
3095
+
3096
+ type PrivacyPolicyAction = "placeholder" | Extract<PrivacyAction, "allow" | "redact" | "hash" | "deny">;
3097
+ interface PrivacyPolicy {
3098
+ version: 1;
3099
+ policy_id: string;
3100
+ policy_name?: string;
3101
+ identity_id: string;
3102
+ detector_actions?: Partial<Record<PrivacyDetectorClass, PrivacyPolicyAction>>;
3103
+ destination_detector_actions?: Partial<Record<PrivacyDestinationCategory, Partial<Record<PrivacyDetectorClass, PrivacyPolicyAction>>>>;
3104
+ client_names?: string[];
3105
+ project_names?: string[];
3106
+ domain_terms?: string[];
3107
+ person_names?: string[];
3108
+ placeholder_scope?: "identity" | "policy";
3109
+ rehydration?: {
3110
+ default_action?: "allow" | "deny";
3111
+ allowed_destinations?: PrivacyDestinationCategory[];
3112
+ denied_destinations?: PrivacyDestinationCategory[];
3113
+ };
3114
+ max_depth?: number;
3115
+ max_payload_bytes?: number;
3116
+ max_string_bytes?: number;
3117
+ operator_override?: {
3118
+ allow_on_policy_error?: boolean;
3119
+ allow_on_filter_error?: boolean;
3120
+ allow_on_vault_error?: boolean;
3121
+ allow_on_detector_error?: boolean;
3122
+ };
3123
+ created_at: string;
3124
+ updated_at: string;
3125
+ }
3126
+ interface PrivacyCoreFinding {
3127
+ raw_path: string;
3128
+ detector_class: PrivacyDetectorClass;
3129
+ span_class: PrivacySpanClass;
3130
+ action: PrivacyAction;
3131
+ content_hash: string;
3132
+ placeholder_label?: string;
3133
+ }
3134
+ interface PrivacyFilterRequest {
3135
+ payload: unknown;
3136
+ policy: PrivacyPolicy | null;
3137
+ identity_id?: string;
3138
+ agent_id: string;
3139
+ destination_category: PrivacyDestinationCategory;
3140
+ audit_log?: AuditLog;
3141
+ event_id?: string;
3142
+ }
3143
+ type PrivacyFilterDecision = {
3144
+ status: "allowed";
3145
+ payload: unknown;
3146
+ findings: [];
3147
+ audit_payload: PrivacyAuditPayload;
3148
+ } | {
3149
+ status: "filtered";
3150
+ payload: unknown;
3151
+ findings: PrivacyCoreFinding[];
3152
+ audit_payload: PrivacyAuditPayload;
3153
+ } | {
3154
+ status: "denied";
3155
+ payload: undefined;
3156
+ findings: PrivacyCoreFinding[];
3157
+ audit_payload: PrivacyDeniedPayload;
3158
+ };
3159
+ interface PrivacyRehydrationRequest {
3160
+ response: unknown;
3161
+ policy: PrivacyPolicy | null;
3162
+ identity_id?: string;
3163
+ agent_id: string;
3164
+ destination_category: PrivacyDestinationCategory;
3165
+ audit_log?: AuditLog;
3166
+ event_id?: string;
3167
+ }
3168
+ type PrivacyRehydrationDecision = {
3169
+ status: "rehydrated";
3170
+ response: unknown;
3171
+ rehydrated_count: number;
3172
+ unresolvable_count: number;
3173
+ audit_payload: PrivacyAuditPayload;
3174
+ } | {
3175
+ status: "denied";
3176
+ response: unknown;
3177
+ rehydrated_count: 0;
3178
+ unresolvable_count: 0;
3179
+ audit_payload: PrivacyDeniedPayload;
3180
+ };
3181
+ declare class LocalPrivacyEngine {
3182
+ private vault;
3183
+ private hmacKey;
3184
+ constructor(vault: PrivacyPlaceholderVault, masterKey: Uint8Array);
3185
+ filterOutbound(request: PrivacyFilterRequest): Promise<PrivacyFilterDecision>;
3186
+ rehydrateResponse(request: PrivacyRehydrationRequest): Promise<PrivacyRehydrationDecision>;
3187
+ private filterNode;
3188
+ private filterString;
3189
+ private fieldDecisionsForFindings;
3190
+ private rehydrateNode;
3191
+ private rehydrateString;
3192
+ private assertPayloadWithinBounds;
3193
+ private deniedPayload;
3194
+ private keyedHash;
3195
+ }
3196
+
2584
3197
  /**
2585
3198
  * Sanctuary MCP Server — Proxy Router
2586
3199
  *
@@ -2603,6 +3216,27 @@ interface ProxyRouterOptions {
2603
3216
  contextGateFilter?: (toolName: string, args: Record<string, unknown>) => Promise<Record<string, unknown>>;
2604
3217
  /** Optional call governor for runtime governance */
2605
3218
  governor?: CallGovernor;
3219
+ /**
3220
+ * Optional v1.1 remote-bound privacy enforcement.
3221
+ *
3222
+ * When set, every proxied tool call is routed through
3223
+ * `engine.filterOutbound` before the upstream forward. The bound
3224
+ * `PrivacyPolicy` is resolved per-server via `policyResolver`, and the
3225
+ * destination category comes from the server's `destination_category`
3226
+ * field (defaulting to `tool-api` when absent).
3227
+ *
3228
+ * Fail-closed semantics:
3229
+ * - `policyResolver` returns null when no policy is bound for the server;
3230
+ * the privacy engine treats that as `fail_closed_no_policy` and denies.
3231
+ * - `policyResolver` rejecting (vault unreachable, decrypt failure, etc.)
3232
+ * is treated as `fail_closed_filter_error` and denies.
3233
+ * - Operator overrides on the policy (`operator_override.allow_on_*`)
3234
+ * are honored by the engine itself.
3235
+ */
3236
+ privacyEnforcement?: {
3237
+ engine: LocalPrivacyEngine;
3238
+ policyResolver: (server: string, identityId: string | undefined) => Promise<PrivacyPolicy | null>;
3239
+ };
2606
3240
  /** Optional callback after each proxy call decision (for dashboard feed) */
2607
3241
  onProxyCall?: (data: {
2608
3242
  tool: string;
@@ -2720,6 +3354,246 @@ declare class FilesystemStorage implements StorageBackend {
2720
3354
  totalSize(): Promise<number>;
2721
3355
  }
2722
3356
 
3357
+ /**
3358
+ * Sanctuary MCP Server — Key Derivation
3359
+ *
3360
+ * Two-tier key derivation:
3361
+ * 1. Master key from passphrase via Argon2id (memory-hard, GPU-resistant)
3362
+ * 2. Namespace keys from master key via HKDF-SHA256
3363
+ *
3364
+ * This ensures:
3365
+ * - Passphrase brute-force is expensive (Argon2id)
3366
+ * - Compromise of one namespace key doesn't expose others (HKDF domain separation)
3367
+ */
3368
+ /** Stored key derivation parameters (for re-deriving the master key) */
3369
+ interface KeyDerivationParams {
3370
+ /** Algorithm */
3371
+ alg: "argon2id";
3372
+ /** Salt (base64url) */
3373
+ salt: string;
3374
+ /** Memory cost in KiB */
3375
+ m: number;
3376
+ /** Time cost (iterations) */
3377
+ t: number;
3378
+ /** Parallelism */
3379
+ p: number;
3380
+ /** Output length in bytes */
3381
+ l: number;
3382
+ }
3383
+
3384
+ /**
3385
+ * Sanctuary v1.1 exit-bundle export/import implementation.
3386
+ *
3387
+ * The public bundle is a directory containing `manifest.json` and hashed JSON
3388
+ * artifacts. Private keys and passphrases are never emitted. Encrypted user
3389
+ * state can be re-keyed on import when the operator supplies source key
3390
+ * material and the destination has a signing identity.
3391
+ */
3392
+
3393
+ interface ExitEncryptedStateBundle {
3394
+ format: "SANCTUARY_EXIT_ENCRYPTED_STATE_V1";
3395
+ exported_at: string;
3396
+ key_source: "passphrase" | "recovery-key" | "unknown";
3397
+ source_key_derivation?: KeyDerivationParams;
3398
+ namespaces: string[];
3399
+ total_keys: number;
3400
+ contains_reserved_namespaces: false;
3401
+ entries: Array<{
3402
+ namespace: string;
3403
+ key: string;
3404
+ entry: StateEntry;
3405
+ }>;
3406
+ }
3407
+ interface ExitPublicIdentityArtifact {
3408
+ bundle: {
3409
+ format: "SANCTUARY_IDENTITY_BUNDLE_V1";
3410
+ publicKey: string;
3411
+ did: string;
3412
+ identity_id: string;
3413
+ label: string;
3414
+ key_type: "ed25519";
3415
+ key_protection: string;
3416
+ rotation_history: StoredIdentity["rotation_history"];
3417
+ exported_at: string;
3418
+ };
3419
+ signature: string;
3420
+ signed_by: string;
3421
+ }
3422
+ interface ExitPolicySetArtifact {
3423
+ format: "SANCTUARY_EXIT_POLICY_SET_V1";
3424
+ exported_at: string;
3425
+ principal_policy: PrincipalPolicy;
3426
+ config_summary: {
3427
+ version: string;
3428
+ state: SanctuaryConfig["state"];
3429
+ execution: SanctuaryConfig["execution"];
3430
+ disclosure: SanctuaryConfig["disclosure"];
3431
+ reputation: SanctuaryConfig["reputation"];
3432
+ privacy_filter: SanctuaryConfig["privacy_filter"];
3433
+ };
3434
+ }
3435
+ interface ExitAuditReceiptsArtifact {
3436
+ format: "SANCTUARY_AUDIT_RECEIPTS_V1";
3437
+ exported_at: string;
3438
+ total: number;
3439
+ individual_entry_signatures: false;
3440
+ entries: AuditEntry[];
3441
+ }
3442
+ interface ExitCommitmentsArtifact {
3443
+ format: "SANCTUARY_EXIT_COMMITMENTS_V1";
3444
+ exported_at: string;
3445
+ public_commitments: Array<{
3446
+ commitment_id: string;
3447
+ commitment: string;
3448
+ committed_at: string;
3449
+ revealed: boolean;
3450
+ revealed_at?: string;
3451
+ }>;
3452
+ unreadable_count: number;
3453
+ redacted_fields: ["value", "blinding_factor"];
3454
+ }
3455
+ interface ExitPlaceholderVaultMetadataArtifact {
3456
+ format: "SANCTUARY_PLACEHOLDER_VAULT_METADATA_V1";
3457
+ exported_at: string;
3458
+ entries: Array<Record<string, unknown>>;
3459
+ unreadable_count: number;
3460
+ redacted_fields: ["raw_value", "raw_path"];
3461
+ }
3462
+ interface ExportExitBundleOptions {
3463
+ bundleDir: string;
3464
+ storage: StorageBackend;
3465
+ masterKey: Uint8Array;
3466
+ identityManager: IdentityManager;
3467
+ auditLog: AuditLog;
3468
+ policy: PrincipalPolicy;
3469
+ config?: SanctuaryConfig;
3470
+ reputationStore?: ReputationStore;
3471
+ stateStoragePath?: string;
3472
+ stateNamespaces?: string[];
3473
+ keySource?: "passphrase" | "recovery-key" | "unknown";
3474
+ /**
3475
+ * When the export is gated by a Tier 1 approval flow (e.g. the hub's
3476
+ * fortress-scope export endpoint), the caller supplies the approval's
3477
+ * audit id here. The value is embedded in the manifest's
3478
+ * `export_approval_audit_id` field and as the `approval_id` of the L1
3479
+ * "exit_bundle_export" audit entry, tying the manifest to the operator's
3480
+ * actual approval rather than an internally-generated id (v1.0.2 (j)).
3481
+ * When omitted, the export self-generates an id.
3482
+ */
3483
+ exportApprovalAuditId?: string;
3484
+ }
3485
+ interface ExportExitBundleResult {
3486
+ bundle_dir: string;
3487
+ manifest: ExitBundleManifest;
3488
+ manifest_hash: string;
3489
+ artifact_count: number;
3490
+ unsupported_artifacts: string[];
3491
+ }
3492
+ interface ImportExitBundleOptions {
3493
+ bundleDir: string;
3494
+ storage: StorageBackend;
3495
+ masterKey: Uint8Array;
3496
+ identityManager: IdentityManager;
3497
+ auditLog: AuditLog;
3498
+ reputationStore?: ReputationStore;
3499
+ activate?: boolean;
3500
+ conflictResolution?: "skip" | "overwrite" | "version";
3501
+ sourcePassphrase?: string;
3502
+ sourceRecoveryKey?: string;
3503
+ sourceMasterKey?: Uint8Array;
3504
+ destinationSignerIdentityId?: string;
3505
+ }
3506
+ interface ExitBundleConflictReport {
3507
+ public_identity_exists: boolean;
3508
+ state_conflicts: Array<{
3509
+ namespace: string;
3510
+ key: string;
3511
+ }>;
3512
+ reputation_conflicts: string[];
3513
+ policy_set_exists: boolean;
3514
+ audit_receipts_exist: boolean;
3515
+ }
3516
+ interface ImportExitBundleResult {
3517
+ verified: boolean;
3518
+ activated: boolean;
3519
+ conflicts: ExitBundleConflictReport;
3520
+ state: {
3521
+ status: "not_requested" | "rekeyed" | "staged_requires_source_key" | "skipped_no_destination_signer";
3522
+ imported_keys: number;
3523
+ skipped_keys: number;
3524
+ skipped_invalid_sig: number;
3525
+ skipped_unknown_kid: number;
3526
+ conflicts: number;
3527
+ };
3528
+ reputation: {
3529
+ imported_attestations: number;
3530
+ invalid_attestations: number;
3531
+ unverifiable_attestations: number;
3532
+ };
3533
+ staged_artifacts: string[];
3534
+ warnings: string[];
3535
+ unsupported_artifacts: string[];
3536
+ }
3537
+ declare function exportExitBundle(opts: ExportExitBundleOptions): Promise<ExportExitBundleResult>;
3538
+ declare function importExitBundle(opts: ImportExitBundleOptions): Promise<ImportExitBundleResult>;
3539
+ declare function exitBundleManifestShape(): Record<string, unknown>;
3540
+
3541
+ /**
3542
+ * Sanctuary v1.1 exit-bundle verifier.
3543
+ *
3544
+ * Verifies the signed SANCTUARY_EXIT_BUNDLE_V1 manifest, every artifact hash,
3545
+ * and the exported identity / reputation signatures that are independently
3546
+ * verifiable from public material in the bundle.
3547
+ */
3548
+
3549
+ interface ExitBundleDetailedVerifierResult extends ExitBundleVerifierResult {
3550
+ manifest_path: string;
3551
+ manifest_hash: string | null;
3552
+ warnings: string[];
3553
+ unsupported_artifacts: string[];
3554
+ identity?: {
3555
+ signature_valid: boolean;
3556
+ identity_id?: string;
3557
+ did?: string;
3558
+ };
3559
+ audit?: {
3560
+ receipt_count: number;
3561
+ individual_signatures_verified: boolean;
3562
+ };
3563
+ reputation?: {
3564
+ bundle_signature_valid: boolean | "unverifiable";
3565
+ attestation_count: number;
3566
+ verified_attestations: number;
3567
+ invalid_attestations: number;
3568
+ unverifiable_attestations: number;
3569
+ };
3570
+ }
3571
+ interface LoadedExitArtifact<T = unknown> {
3572
+ entry: ExitBundleArtifactEntry;
3573
+ path: string;
3574
+ json: T;
3575
+ bytes: Uint8Array;
3576
+ }
3577
+ declare function readManifest(bundleDir: string): Promise<ExitBundleManifest>;
3578
+ declare function loadExitArtifact<T = unknown>(bundleDir: string, manifest: ExitBundleManifest, kind: ExitBundleArtifactKind): Promise<LoadedExitArtifact<T> | null>;
3579
+ declare function verifyExitBundle(bundleDir: string): Promise<ExitBundleDetailedVerifierResult>;
3580
+
3581
+ /**
3582
+ * `sanctuary exit` CLI.
3583
+ *
3584
+ * Operator-facing export/import/verifier path for SANCTUARY_EXIT_BUNDLE_V1.
3585
+ * Dashboard wizard work consumes the same module APIs later.
3586
+ */
3587
+
3588
+ interface ExitCommandArgs {
3589
+ argv: string[];
3590
+ out?: Writable;
3591
+ err?: Writable;
3592
+ stdin?: NodeJS.ReadableStream;
3593
+ env?: NodeJS.ProcessEnv;
3594
+ }
3595
+ declare function runExitCommand(args: ExitCommandArgs): Promise<number>;
3596
+
2723
3597
  /**
2724
3598
  * Sanctuary MCP Server — Principal Policy Loader
2725
3599
  *
@@ -3631,6 +4505,12 @@ interface UpstreamServerStatus {
3631
4505
  tool_count: number;
3632
4506
  error?: string;
3633
4507
  }
4508
+ interface PrivacySummary {
4509
+ filtered_events: number;
4510
+ filtered_spans: number;
4511
+ classes: Record<string, number>;
4512
+ last_filtered_at: string | null;
4513
+ }
3634
4514
  interface ProtectionSnapshot {
3635
4515
  overall: {
3636
4516
  status: OverallStatus;
@@ -3647,6 +4527,7 @@ interface ProtectionSnapshot {
3647
4527
  activity: ActivityEntry[];
3648
4528
  pending_approvals: PendingApproval[];
3649
4529
  audit: AuditEntry[];
4530
+ privacy: PrivacySummary;
3650
4531
  upstream_servers: UpstreamServerStatus[];
3651
4532
  mode: "co-located" | "standalone";
3652
4533
  server_version: string;
@@ -3700,8 +4581,19 @@ interface ApprovalHandlers {
3700
4581
  allow: (id: string) => Promise<boolean>;
3701
4582
  deny: (id: string) => Promise<boolean>;
3702
4583
  }
4584
+ /**
4585
+ * SSE event taxonomy.
4586
+ *
4587
+ * v1.0 event names: `snapshot` (initial hydration), `activity` (audit feed
4588
+ * append), `approval` (pending approval surfaced).
4589
+ *
4590
+ * v1.1 added: `inbox` (HubInboxItem replace-or-prepend by item_id) and
4591
+ * `agent_status` (HubAgentStatusSnapshot replace by agent_id). The hub
4592
+ * service emits these via the existing `publish` interface; the producer
4593
+ * wires every name verbatim through `event: <type>` SSE frames.
4594
+ */
3703
4595
  interface StreamEvent {
3704
- type: "snapshot" | "activity" | "approval";
4596
+ type: "snapshot" | "activity" | "approval" | "inbox" | "agent_status";
3705
4597
  data: unknown;
3706
4598
  }
3707
4599
 
@@ -3739,6 +4631,18 @@ interface DashboardHandle {
3739
4631
  publishActivity: (entry: ActivityEntry) => void;
3740
4632
  /** Push a new pending approval (already added by the approval channel). */
3741
4633
  publishApproval: (approval: PendingApproval) => void;
4634
+ /**
4635
+ * Push a v1.1 hub inbox item update. Producers (HubService) call this
4636
+ * on inbox writes (Tier 1 enqueue, Tier 1 resolve, source-pulled item
4637
+ * surfaced). Consumers replace-or-prepend by `item_id`.
4638
+ */
4639
+ publishInbox: (item: unknown) => void;
4640
+ /**
4641
+ * Push a v1.1 per-agent status update. Producers call this when the
4642
+ * agent registry's `updateStatus` transitions. Consumers replace by
4643
+ * `agent_id`.
4644
+ */
4645
+ publishAgentStatus: (snapshot: unknown) => void;
3742
4646
  }
3743
4647
  declare function startDashboardServer(options: DashboardServerOptions): Promise<DashboardHandle>;
3744
4648
 
@@ -3835,4 +4739,4 @@ declare function createSanctuaryServer(options?: {
3835
4739
  storage?: StorageBackend;
3836
4740
  }): Promise<SanctuaryServer>;
3837
4741
 
3838
- export { ATTESTATION_VERSION, type ActivityEntry, type AggregatorSources, ApprovalGate, type ApprovalHandlers, type AttestationBody, type AttestationVerificationResult, AuditLog, AutoApproveChannel, BaselineTracker, type BridgeAttestationRequest, type BridgeAttestationResult, type BridgeCommitment, type BridgeVerificationResult, TEMPLATES as CONTEXT_GATE_TEMPLATES, CallbackApprovalChannel, ClientManager, CommitmentStore, type ConcordiaOutcome, type ConnectionState, type ContextAction, type ContextFilterResult, ContextGateEnforcer, type ContextGatePolicy, ContextGatePolicyStore, type ContextGateRule, type ContextGateTemplate, DashboardApprovalChannel, type DashboardConfig, type DashboardHandle, type DashboardServerOptions, type DetectionResult, type EnforcerConfig, type FederationCapabilities, type FederationPeer, FederationRegistry, type FieldClassification, type FieldFilterResult, FilesystemStorage, type GateResult, HERO_COPY, type HandshakeChallenge, type HandshakeCompletion, type HandshakeResponse, type HandshakeResult, InMemoryModelProvenanceStore, InjectionDetector, type InjectionDetectorConfig, type InjectionSignal, type L1Status, type L2Status, type L3Status, type L4Status, MODEL_PRESETS, MemoryStorage, type ModelProvenance, type ModelProvenanceStore, type PedersenCommitment, type PeerTrustEvaluation, type PendingApproval, type PolicyRecommendation, PolicyStore, type PrincipalPolicy, type ProtectionSnapshot, type ProviderCategory, ProxyRouter, type ProxyRouterOptions, type ReputationLookup, ReputationStore, type SHRBody, type SHRGeneratorOptions, type SHRVerificationResult, type SanctuaryConfig, type SanctuaryServer, type SignedAttestation, type SignedSHR, type SovereigntyProfile, SovereigntyProfileStore, type SovereigntyProfileUpdate, type SovereigntyTier, type StartDashboardOptions, StateStore, StderrApprovalChannel, type StreamEvent, TIER_WEIGHTS, type TierMetadata, type TieredAttestation, type UpstreamConnection, type UpstreamServer, type UpstreamTool, WebhookApprovalChannel, type WebhookCallbackPayload, type WebhookConfig, type WebhookPayload, type ZKProofOfKnowledge, type ZKRangeProof, canonicalize, classifyField, completeHandshake, computeWeightedScore, createBridgeCommitment, createDefaultProfile, createPedersenCommitment, createProofOfKnowledge, createRangeProof, createSanctuaryServer, evaluateField, filterContext, generateAttestation, generateSHR, generateSystemPrompt, getProtectionSnapshot, getTemplate, initiateHandshake, listTemplateIds, loadConfig, loadPrincipalPolicy, recommendPolicy, renderDashboardHTML, resolveTier, respondToHandshake, signPayload, startDashboard, startDashboardServer, tierDistribution, verifyAttestation, verifyBridgeCommitment, verifyCompletion, verifyPedersenCommitment, verifyProofOfKnowledge, verifyRangeProof, verifySHR, verifySignature };
4742
+ export { ATTESTATION_VERSION, type ActivityEntry, type AggregatorSources, ApprovalGate, type ApprovalHandlers, type AttestationBody, type AttestationVerificationResult, AuditLog, AutoApproveChannel, BaselineTracker, type BridgeAttestationRequest, type BridgeAttestationResult, type BridgeCommitment, type BridgeVerificationResult, TEMPLATES as CONTEXT_GATE_TEMPLATES, CallbackApprovalChannel, ClientManager, CommitmentStore, type ConcordiaOutcome, type ConnectionState, type ContextAction, type ContextFilterResult, ContextGateEnforcer, type ContextGatePolicy, ContextGatePolicyStore, type ContextGateRule, type ContextGateTemplate, DashboardApprovalChannel, type DashboardConfig, type DashboardHandle, type DashboardServerOptions, type DetectionResult, type EnforcerConfig, type ExitAuditReceiptsArtifact, type ExitBundleDetailedVerifierResult, type ExitCommandArgs, type ExitCommitmentsArtifact, type ExitEncryptedStateBundle, type ExitPlaceholderVaultMetadataArtifact, type ExitPolicySetArtifact, type ExitPublicIdentityArtifact, type ExportExitBundleOptions, type ExportExitBundleResult, type FederationCapabilities, type FederationPeer, FederationRegistry, type FieldClassification, type FieldFilterResult, FilesystemStorage, type GateResult, HERO_COPY, type HandshakeChallenge, type HandshakeCompletion, type HandshakeResponse, type HandshakeResult, type ImportExitBundleOptions, type ImportExitBundleResult, InMemoryModelProvenanceStore, InjectionDetector, type InjectionDetectorConfig, type InjectionSignal, type L1Status, type L2Status, type L3Status, type L4Status, type LoadedExitArtifact, MODEL_PRESETS, MemoryStorage, type ModelProvenance, type ModelProvenanceStore, type PedersenCommitment, type PeerTrustEvaluation, type PendingApproval, type PolicyRecommendation, PolicyStore, type PrincipalPolicy, type ProtectionSnapshot, type ProviderCategory, ProxyRouter, type ProxyRouterOptions, type ReputationLookup, ReputationStore, type SHRBody, type SHRGeneratorOptions, type SHRVerificationResult, type SanctuaryConfig, type SanctuaryServer, type SignedAttestation, type SignedSHR, type SovereigntyProfile, SovereigntyProfileStore, type SovereigntyProfileUpdate, type SovereigntyTier, type StartDashboardOptions, StateStore, StderrApprovalChannel, type StreamEvent, TIER_WEIGHTS, type TierMetadata, type TieredAttestation, type UpstreamConnection, type UpstreamServer, type UpstreamTool, WebhookApprovalChannel, type WebhookCallbackPayload, type WebhookConfig, type WebhookPayload, type ZKProofOfKnowledge, type ZKRangeProof, canonicalize, classifyField, completeHandshake, computeWeightedScore, createBridgeCommitment, createDefaultProfile, createPedersenCommitment, createProofOfKnowledge, createRangeProof, createSanctuaryServer, evaluateField, exitBundleManifestShape, exportExitBundle, filterContext, generateAttestation, generateSHR, generateSystemPrompt, getProtectionSnapshot, getTemplate, importExitBundle, initiateHandshake, listTemplateIds, loadConfig, loadExitArtifact, loadPrincipalPolicy, readManifest, recommendPolicy, renderDashboardHTML, resolveTier, respondToHandshake, runExitCommand, signPayload, startDashboard, startDashboardServer, tierDistribution, verifyAttestation, verifyBridgeCommitment, verifyCompletion, verifyExitBundle, verifyPedersenCommitment, verifyProofOfKnowledge, verifyRangeProof, verifySHR, verifySignature };