@datasynx/agentic-ai-cartography 2.6.0 → 2.7.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
@@ -982,6 +982,12 @@ interface NodeAttribution {
982
982
 
983
983
  /** Default tenant for single-user / pre-migration installs. */
984
984
  declare const DEFAULT_TENANT = "local";
985
+ /**
986
+ * The current catalog schema version. A fresh DB initializes here and the migration
987
+ * chain advances to it; the collector readiness probe (4.7) asserts a reopened DB
988
+ * reports exactly this. Keep in lockstep with the final `user_version` set in `migrate()`.
989
+ */
990
+ declare const SCHEMA_VERSION = 15;
985
991
  /**
986
992
  * Normalize an untrusted tenant id: strip invisible/control characters, trim,
987
993
  * cap length, and enforce a conservative key charset. Falls back to DEFAULT_TENANT
@@ -1352,6 +1358,12 @@ declare class CartographyDB {
1352
1358
  * Prune sessions older than the given ISO date string. Returns count of deleted sessions.
1353
1359
  */
1354
1360
  pruneSessions(olderThan: string): number;
1361
+ /**
1362
+ * Retention/compaction (4.7): delete audit events older than `olderThan` (ISO 8601).
1363
+ * The audit trail grows unbounded on a busy collector; this bounds it without touching
1364
+ * sessions/nodes/edges. Returns the number of events removed.
1365
+ */
1366
+ pruneEventsOlderThan(olderThan: string): number;
1355
1367
  /** Fetch a single node by id within a session. */
1356
1368
  getNode(sessionId: string, nodeId: string): NodeRow | undefined;
1357
1369
  /** Batch-fetch nodes by id, keyed for O(1) lookup. Chunked to stay under SQLite's bind-variable limit. */
@@ -1760,6 +1772,37 @@ interface IngestOptions {
1760
1772
  */
1761
1773
  declare function ingestEnvelope(store: StoreBackend, envelope: IngestEnvelope, opts?: IngestOptions): IngestResult;
1762
1774
 
1775
+ /**
1776
+ * Ingest backpressure for the central collector (4.7).
1777
+ *
1778
+ * A pure, in-memory **per-org token-bucket** rate limiter. The networked `POST /ingest`
1779
+ * write endpoint must protect the shared store from a runaway or hostile client; over-quota
1780
+ * requests are refused with `429 + Retry-After` rather than admitted. Deterministic given an
1781
+ * injected clock, so it is unit-testable without real time. In-process only (a multi-replica
1782
+ * deployment would front it with a shared limiter; documented in the runbook).
1783
+ */
1784
+ interface QuotaConfig {
1785
+ /** Bucket capacity = max burst, and the number of tokens refilled over one `refillMs` window. */
1786
+ capacity: number;
1787
+ /** Milliseconds over which a fully-drained bucket refills to `capacity`. */
1788
+ refillMs: number;
1789
+ }
1790
+ /** Sensible default: 120 ingests / minute / org (burst 120). */
1791
+ declare const DEFAULT_INGEST_QUOTA: QuotaConfig;
1792
+ interface QuotaDecision {
1793
+ allowed: boolean;
1794
+ /** Seconds to wait before retrying — populated only when `!allowed` (≥1). */
1795
+ retryAfterSec: number;
1796
+ }
1797
+ declare class RateLimiter {
1798
+ private readonly cfg;
1799
+ private readonly now;
1800
+ private readonly buckets;
1801
+ constructor(cfg?: QuotaConfig, now?: () => number);
1802
+ /** Consume one token for `key`. Returns whether the request is allowed (+ Retry-After when not). */
1803
+ take(key: string): QuotaDecision;
1804
+ }
1805
+
1763
1806
  /**
1764
1807
  * The central-collector ingest HTTP surface (2.12).
1765
1808
  *
@@ -1775,12 +1818,18 @@ declare function ingestEnvelope(store: StoreBackend, envelope: IngestEnvelope, o
1775
1818
  * handler ever runs, so the handler never sees (and never logs) the token.
1776
1819
  */
1777
1820
 
1778
- /** A transport-agnostic HTTP-ish response: a status code and a JSON-serializable body. */
1821
+ /** A transport-agnostic HTTP-ish response: a status code, a JSON-serializable body, optional headers. */
1779
1822
  interface IngestResponse {
1780
1823
  status: number;
1781
1824
  body: unknown;
1825
+ /** Extra response headers (e.g. `Retry-After` on a 429). */
1826
+ headers?: Record<string, string>;
1782
1827
  }
1783
1828
  type IngestHandler = (body: unknown) => IngestResponse;
1829
+ interface IngestHandlerOptions extends IngestOptions {
1830
+ /** Per-org ingest rate limiter (4.7 backpressure). Over-quota → 429 + Retry-After. */
1831
+ quota?: RateLimiter;
1832
+ }
1784
1833
  /**
1785
1834
  * Build the `/ingest` handler over a {@link StoreBackend}. The handler validates the
1786
1835
  * 2.11 push envelope, runs ingest (re-validating anonymization first), and maps the
@@ -1789,7 +1838,7 @@ type IngestHandler = (body: unknown) => IngestResponse;
1789
1838
  * - 500 — ingest threw (the store's per-node transaction rolls that node back).
1790
1839
  * - 200 — {@link IngestResult}.
1791
1840
  */
1792
- declare function createIngestHandler(store: StoreBackend, opts?: IngestOptions): IngestHandler;
1841
+ declare function createIngestHandler(store: StoreBackend, opts?: IngestHandlerOptions): IngestHandler;
1793
1842
 
1794
1843
  /**
1795
1844
  * Org-key lifecycle for the 2.10 anonymization layer.
@@ -2183,6 +2232,7 @@ interface HttpOptions {
2183
2232
  onIngest?: (body: unknown) => {
2184
2233
  status: number;
2185
2234
  body: unknown;
2235
+ headers?: Record<string, string>;
2186
2236
  };
2187
2237
  /**
2188
2238
  * RBAC (4.5). When `store` holds credentials, the transport runs in RBAC mode: a
@@ -2197,6 +2247,14 @@ interface HttpOptions {
2197
2247
  };
2198
2248
  /** Tenant assigned to implicit (shared/loopback) admin principals. */
2199
2249
  defaultTenant?: string;
2250
+ /**
2251
+ * Readiness probe (4.7). When set, `GET /readyz` calls it: 200 when `ready`, else 503.
2252
+ * `GET /healthz` (liveness) is always 200. Both are PUBLIC (no auth) for k8s/LB probes.
2253
+ */
2254
+ readiness?: () => {
2255
+ ready: boolean;
2256
+ detail?: Record<string, unknown>;
2257
+ };
2200
2258
  }
2201
2259
  /**
2202
2260
  * Start a Streamable HTTP server. A fresh MCP server instance is created per
@@ -4128,4 +4186,4 @@ declare function logInfo(message: string, context?: Record<string, unknown>): vo
4128
4186
  declare function logWarn(message: string, context?: Record<string, unknown>): void;
4129
4187
  declare function logError(message: string, context?: Record<string, unknown>): void;
4130
4188
 
4131
- export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, CLIENTS, CONFIDENCE, COST_PERIODS, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, RELATION_TO_DIRECTION, ROLES, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
4189
+ export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, CLIENTS, CONFIDENCE, COST_PERIODS, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
package/dist/index.d.ts CHANGED
@@ -982,6 +982,12 @@ interface NodeAttribution {
982
982
 
983
983
  /** Default tenant for single-user / pre-migration installs. */
984
984
  declare const DEFAULT_TENANT = "local";
985
+ /**
986
+ * The current catalog schema version. A fresh DB initializes here and the migration
987
+ * chain advances to it; the collector readiness probe (4.7) asserts a reopened DB
988
+ * reports exactly this. Keep in lockstep with the final `user_version` set in `migrate()`.
989
+ */
990
+ declare const SCHEMA_VERSION = 15;
985
991
  /**
986
992
  * Normalize an untrusted tenant id: strip invisible/control characters, trim,
987
993
  * cap length, and enforce a conservative key charset. Falls back to DEFAULT_TENANT
@@ -1352,6 +1358,12 @@ declare class CartographyDB {
1352
1358
  * Prune sessions older than the given ISO date string. Returns count of deleted sessions.
1353
1359
  */
1354
1360
  pruneSessions(olderThan: string): number;
1361
+ /**
1362
+ * Retention/compaction (4.7): delete audit events older than `olderThan` (ISO 8601).
1363
+ * The audit trail grows unbounded on a busy collector; this bounds it without touching
1364
+ * sessions/nodes/edges. Returns the number of events removed.
1365
+ */
1366
+ pruneEventsOlderThan(olderThan: string): number;
1355
1367
  /** Fetch a single node by id within a session. */
1356
1368
  getNode(sessionId: string, nodeId: string): NodeRow | undefined;
1357
1369
  /** Batch-fetch nodes by id, keyed for O(1) lookup. Chunked to stay under SQLite's bind-variable limit. */
@@ -1760,6 +1772,37 @@ interface IngestOptions {
1760
1772
  */
1761
1773
  declare function ingestEnvelope(store: StoreBackend, envelope: IngestEnvelope, opts?: IngestOptions): IngestResult;
1762
1774
 
1775
+ /**
1776
+ * Ingest backpressure for the central collector (4.7).
1777
+ *
1778
+ * A pure, in-memory **per-org token-bucket** rate limiter. The networked `POST /ingest`
1779
+ * write endpoint must protect the shared store from a runaway or hostile client; over-quota
1780
+ * requests are refused with `429 + Retry-After` rather than admitted. Deterministic given an
1781
+ * injected clock, so it is unit-testable without real time. In-process only (a multi-replica
1782
+ * deployment would front it with a shared limiter; documented in the runbook).
1783
+ */
1784
+ interface QuotaConfig {
1785
+ /** Bucket capacity = max burst, and the number of tokens refilled over one `refillMs` window. */
1786
+ capacity: number;
1787
+ /** Milliseconds over which a fully-drained bucket refills to `capacity`. */
1788
+ refillMs: number;
1789
+ }
1790
+ /** Sensible default: 120 ingests / minute / org (burst 120). */
1791
+ declare const DEFAULT_INGEST_QUOTA: QuotaConfig;
1792
+ interface QuotaDecision {
1793
+ allowed: boolean;
1794
+ /** Seconds to wait before retrying — populated only when `!allowed` (≥1). */
1795
+ retryAfterSec: number;
1796
+ }
1797
+ declare class RateLimiter {
1798
+ private readonly cfg;
1799
+ private readonly now;
1800
+ private readonly buckets;
1801
+ constructor(cfg?: QuotaConfig, now?: () => number);
1802
+ /** Consume one token for `key`. Returns whether the request is allowed (+ Retry-After when not). */
1803
+ take(key: string): QuotaDecision;
1804
+ }
1805
+
1763
1806
  /**
1764
1807
  * The central-collector ingest HTTP surface (2.12).
1765
1808
  *
@@ -1775,12 +1818,18 @@ declare function ingestEnvelope(store: StoreBackend, envelope: IngestEnvelope, o
1775
1818
  * handler ever runs, so the handler never sees (and never logs) the token.
1776
1819
  */
1777
1820
 
1778
- /** A transport-agnostic HTTP-ish response: a status code and a JSON-serializable body. */
1821
+ /** A transport-agnostic HTTP-ish response: a status code, a JSON-serializable body, optional headers. */
1779
1822
  interface IngestResponse {
1780
1823
  status: number;
1781
1824
  body: unknown;
1825
+ /** Extra response headers (e.g. `Retry-After` on a 429). */
1826
+ headers?: Record<string, string>;
1782
1827
  }
1783
1828
  type IngestHandler = (body: unknown) => IngestResponse;
1829
+ interface IngestHandlerOptions extends IngestOptions {
1830
+ /** Per-org ingest rate limiter (4.7 backpressure). Over-quota → 429 + Retry-After. */
1831
+ quota?: RateLimiter;
1832
+ }
1784
1833
  /**
1785
1834
  * Build the `/ingest` handler over a {@link StoreBackend}. The handler validates the
1786
1835
  * 2.11 push envelope, runs ingest (re-validating anonymization first), and maps the
@@ -1789,7 +1838,7 @@ type IngestHandler = (body: unknown) => IngestResponse;
1789
1838
  * - 500 — ingest threw (the store's per-node transaction rolls that node back).
1790
1839
  * - 200 — {@link IngestResult}.
1791
1840
  */
1792
- declare function createIngestHandler(store: StoreBackend, opts?: IngestOptions): IngestHandler;
1841
+ declare function createIngestHandler(store: StoreBackend, opts?: IngestHandlerOptions): IngestHandler;
1793
1842
 
1794
1843
  /**
1795
1844
  * Org-key lifecycle for the 2.10 anonymization layer.
@@ -2183,6 +2232,7 @@ interface HttpOptions {
2183
2232
  onIngest?: (body: unknown) => {
2184
2233
  status: number;
2185
2234
  body: unknown;
2235
+ headers?: Record<string, string>;
2186
2236
  };
2187
2237
  /**
2188
2238
  * RBAC (4.5). When `store` holds credentials, the transport runs in RBAC mode: a
@@ -2197,6 +2247,14 @@ interface HttpOptions {
2197
2247
  };
2198
2248
  /** Tenant assigned to implicit (shared/loopback) admin principals. */
2199
2249
  defaultTenant?: string;
2250
+ /**
2251
+ * Readiness probe (4.7). When set, `GET /readyz` calls it: 200 when `ready`, else 503.
2252
+ * `GET /healthz` (liveness) is always 200. Both are PUBLIC (no auth) for k8s/LB probes.
2253
+ */
2254
+ readiness?: () => {
2255
+ ready: boolean;
2256
+ detail?: Record<string, unknown>;
2257
+ };
2200
2258
  }
2201
2259
  /**
2202
2260
  * Start a Streamable HTTP server. A fresh MCP server instance is created per
@@ -4128,4 +4186,4 @@ declare function logInfo(message: string, context?: Record<string, unknown>): vo
4128
4186
  declare function logWarn(message: string, context?: Record<string, unknown>): void;
4129
4187
  declare function logError(message: string, context?: Record<string, unknown>): void;
4130
4188
 
4131
- export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, CLIENTS, CONFIDENCE, COST_PERIODS, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, RELATION_TO_DIRECTION, ROLES, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
4189
+ export { ACTIONS, ANOMALY_KINDS, ANOMALY_SEVERITIES, type Action, ActionSchema, type AgentProvider, type AgentRunContext, type AgentTool, type Anomaly, type AnomalyConfig, type AnomalyKind, type AnomalySeverity, type AnomalyThresholds, type AnonViolation, type AnonymizationLevel, type ApiServerOptions, type AskUserFn, type AuthConfig, AuthConfigSchema, AuthorizationError, type BackstageEntity, type BackstageMapOptions, type BindGuardOptions, CLIENTS, CONFIDENCE, COST_PERIODS, type CartographyConfig, CartographyDB, type CartographyMapData, type CentralDbConfig, CentralDbConfigSchema, type ClassifiedItem, type ClassifyInput, type ClassifyResult, type ClientSpec, type Cluster, ClusterSchema, type ComplianceInput, type ComplianceReport, ComplianceReportSchema, type ComplianceRule, ComplianceRuleSchema, type Condition, ConditionSchema, ConfigError, type ConfigFile, ConfigFileSchema, type ConfigFormat, type Connection, ConnectionSchema, type Contributor, type ControlResult, ControlResultSchema, type CostEntry, CostEntrySchema, type CostPeriod, type CostRecord, type CostSource, type CreateMcpServerOptions, type CredentialConfig, CredentialConfigSchema, type CredentialDb, type CredentialRecord, type CredentialStore, type CronFields, CsvCostSource, type CsvCostSourceOptions, DEFAULT_ANOMALY_THRESHOLDS, DEFAULT_FAST_MODEL, DEFAULT_INGEST_QUOTA, DEFAULT_LEAD_MODEL, DEFAULT_SERVER_NAME, DEFAULT_TENANT, DOMAIN_COLORS, DOMAIN_PALETTE, DRIFT_FIELDS, type DataAsset, DataAssetSchema, type DependencyQuery, type DiscoveryEdge, type DiscoveryEvent, type DiscoveryFn, type DiscoveryNode, type DriftAlert, type DriftAlertItem, type DriftConfig, DriftConfigSchema, type DriftField, type DriftItemKind, type DriftRunRow, type DriftSink, type DriftSinkConfig, EDGE_RELATIONSHIPS, type EdgeRelationship, type EdgeRow, EdgeSchema, type EmbeddingProvider, type EnrichResult, type EntryOptions, type EstablishedConn, type EvidenceKind, type FetchLike, type FragmentKind, type GraphSummary, type HealthResult, type HttpOptions, INGEST_SCHEMA_VERSION, type IngestEnvelope, IngestEnvelopeSchema, type IngestHandler, type IngestHandlerOptions, type IngestOptions, type IngestResponse, type IngestResult, type InstallPlan, InvalidTenantError, type JiraIssue, type JiraOptions, JiraSink, type JiraSinkOptions, LOOPBACK_HOSTS, type LocalDiscoveryOptions, type LocalDiscoveryResult, type LogEntry, type LogLevel, MCP_BIN, type MatchStrategy, NODE_TYPES, NODE_TYPE_GROUPS, type NlIntent, type NlQueryOptions, type NlQueryResult, type NlRelation, type NodeAttribution, type NodeChange, type NodeIdentity, type NodeQuery, type NodeRow, NodeSchema, type NodeType, type NodesResult, NotFoundError, OUTPUT_FORMATS, type OrgKeyOptions, type OrgSummary, type OsKind, type OutputFormat, PACKAGE_NAME, PAGERDUTY_ENQUEUE_URL, PENDING_STATUSES, PERSONAL, PORT_MAP, PRIVATE_IP, PUSH_SCHEMA_VERSION, type PagerDutyEvent, PagerDutySink, type PagerDutySinkOptions, type ParsedApiArgs, type PendingShareRow, type PendingStatus, type PlanOptions, type PolicyResult, type PostJsonOptions, type Principal, PrincipalSchema, type ProviderFactory, type ProviderName, ProviderRegistry, type PushItem, type PushOptions, type PushResult, type QueryBackend, type QuotaConfig, type QuotaDecision, RELATION_TO_DIRECTION, ROLES, RateLimiter, type ResolveContext, type ResolveOptions, type Role, RoleSchema, type RuleCheck, RuleCheckSchema, type RuleScope, type Ruleset, RulesetSchema, type RunDriftOptions, SCAN_ARG_PATTERNS, SCHEMA_VERSION, SDL, SECURITY_METADATA_KEYS, SEVERITIES, SEVERITY_WEIGHT, SHARING_LEVELS, type ScanArgKind, type ScanContext, type ScanHintParams, type ScanResult, type Scanner, type ScannerPlugin, type ScannerPluginApi, ScannerRegistry, ScannerShape, type ScheduleConfig, ScheduleConfigSchema, type ScheduledRunResult, type Scope, type SearchFn, type SemanticSearchOptions, type ServerEntry, type SessionRow, type Severity, type SharePreview, type SharePreviewEntry, type SharingLevel, SharingLevelSchema, type SharingPolicy, type ShellKind, type SlackMessage, SlackSink, SqliteCredentialStore, SqliteQueryBackend, SqliteStoreBackend, type StartApiOptions, StdoutSink, type StoreBackend, type SyncClassifyOptions, type SyncClassifyResult, TENANT_HEADER, type TenantContext, TenantMismatchError, type TenantOptions, type ToolResult, type TopologyDelta, type TopologyDiff, type TopologyInput, type TraversalResult, VectorStore, WebhookSink, type WebhookSinkOptions, applyInstall, applySharingLevel, assertReadOnly, assertSafeBind, assertSafeScanArg, assertSameTenant, assignColors, authorize, bearerToken, bookmarksScanner, buildCartographyToolHandlers, buildMapData, buildOpenApiDocument, buildReport, buildSinks, can, centralDbFromEnv, checkBearer, checkPrerequisites, checkReadOnly, clampText, classify, classifyDrift, cleanupTempFiles, cloudAwsScanner, cloudAzureScanner, cloudGcpScanner, codeAddMcpCommand, computeCentroid, computeClusterBounds, computeIdentity, connectionsScanner, contentHash, createBashTool, createCartographyTools, createClaudeProvider, createDefaultRegistry, createHashEmbedder, createIngestHandler, createLocalEmbedder, createMcpServer, createOllamaProvider, createOpenAIProvider, createScanRunner, createSemanticSearch, createSqliteQueryBackend, currentOs, cursorDeeplink, databasesScanner, deepMerge, defaultAllowedHosts, defaultConfig, defaultContext, defaultProviderRegistry, defaultRegistry, defaultServerEntry, definePlugin, deriveSessionName, detectAnomalies, detectOrphans, detectShadowIt, diffTopology, edgesToConnections, enrichCosts, entitiesToYaml, evaluateCheck, evaluateRule, evidenceLine, executeGraphql, executeNlQuery, exportAll, exportBackstageYAML, exportComplianceReport, exportCostCSV, exportCostSummary, exportDiscoveryApp, exportJGF, exportJSON, extractListeningPorts, filterBySeverity, findAnonViolations, formatComplianceText, formatJira, formatPagerDuty, formatSlack, generateDependencyMermaid, generateDiffMermaid, generateTopologyMermaid, getClient, getRuleset, globalId, groupByDomain, handleGraphqlGet, hashToken, hexCorners, hexDistance, hexNeighbors, hexRing, hexSpiral, hexToPixel, hmacKey, hostname, ingestEnvelope, installedAppsScanner, isLoopbackHost, isPersonalHost, isReadOnlyCommand, isRemembered, isSecureWebhookUrl, k8sScanner, keyMetaOf, layoutClusters, listClients, listRulesets, loadConfig, loadOrgKey, loadPlugins, loadRuleset, localDiscoveryFn, log, logDebug, logError, logInfo, logWarn, machineId, maxSeverity, mcpServerObject, newAnomalies, nextRun, nodesToAssets, normalizeId, normalizeTenant, orgKeyPath, osUser, parseApiArgs, parseComposeDeps, parseConfig, parseConnectionString, parseCostCsv, parseCron, parseEstablished, parseNginxUpstreams, parseNlQuery, parseScanHint, pixelToHex, planInstall, portsScanner, postJson, previewShare, pseudonymize, pseudonymizeFragment, pseudonymizeString, pushDeltas, readConfigFile, redactConnectionString, redactSecrets, redactValue, renderDiff, resolveEffectiveLevel, resolveNlQuery, resolvePrincipal, resolveSharingLevel, resolveTenant, revalidateAnonymized, reversalKey, reversePseudonym, rotateOrgKey, runApi, runDiscovery, runDrift, runHttp, runLocalDiscovery, runOnce, runStdio, runSyncClassify, safeEnv, safeJson, safetyHook, sanitizeUntrusted, sanitizeValue, scopeReads, scoreTopology, securityRelevantChange, serializeConfig, serviceConfigScanner, setVerbose, shadeVariant, shapeToJsonSchema, shareHash, splitSegments, stableStringify, startApi, stripSensitive, timingSafeEqual, toBackstageEntities, validateScanner, vscodeDeeplink, zodToJsonSchema };
package/dist/index.js CHANGED
@@ -2562,6 +2562,7 @@ function newAnomalies(base, current) {
2562
2562
 
2563
2563
  // src/db.ts
2564
2564
  var DEFAULT_TENANT = "local";
2565
+ var SCHEMA_VERSION = 15;
2565
2566
  function normalizeTenant(raw) {
2566
2567
  if (raw == null) return DEFAULT_TENANT;
2567
2568
  const cleaned = sanitizeUntrusted(String(raw)).trim().slice(0, 128);
@@ -3966,6 +3967,14 @@ var CartographyDB = class {
3966
3967
  }
3967
3968
  return rows.length;
3968
3969
  }
3970
+ /**
3971
+ * Retention/compaction (4.7): delete audit events older than `olderThan` (ISO 8601).
3972
+ * The audit trail grows unbounded on a busy collector; this bounds it without touching
3973
+ * sessions/nodes/edges. Returns the number of events removed.
3974
+ */
3975
+ pruneEventsOlderThan(olderThan) {
3976
+ return this.db.prepare("DELETE FROM activity_events WHERE timestamp < ?").run(olderThan).changes;
3977
+ }
3969
3978
  // ── Graph queries (read-only context layer) ─────────────────────────────────
3970
3979
  /** Fetch a single node by id within a session. */
3971
3980
  getNode(sessionId, nodeId) {
@@ -4657,7 +4666,7 @@ var ContributorSchema = z5.object({
4657
4666
  });
4658
4667
  var IngestEnvelopeSchema = z5.object({
4659
4668
  schemaVersion: z5.literal(INGEST_SCHEMA_VERSION),
4660
- org: z5.string().min(1).optional(),
4669
+ org: z5.string().min(1).max(128).optional(),
4661
4670
  items: z5.array(z5.object({
4662
4671
  contentHash: z5.string(),
4663
4672
  kind: z5.enum(["node", "edge"]),
@@ -4745,6 +4754,7 @@ function ingestEnvelope(store, envelope, opts = {}) {
4745
4754
 
4746
4755
  // src/central/server.ts
4747
4756
  function createIngestHandler(store, opts = {}) {
4757
+ const quota = opts.quota;
4748
4758
  return (body) => {
4749
4759
  const parsed = IngestEnvelopeSchema.safeParse(body);
4750
4760
  if (!parsed.success) {
@@ -4752,6 +4762,14 @@ function createIngestHandler(store, opts = {}) {
4752
4762
  logWarn("ingest: rejected invalid envelope", { issues });
4753
4763
  return { status: 400, body: { error: "invalid envelope", issues } };
4754
4764
  }
4765
+ if (quota) {
4766
+ const org = normalizeTenant(parsed.data.org ?? opts.defaultOrg);
4767
+ const decision = quota.take(org);
4768
+ if (!decision.allowed) {
4769
+ logWarn("ingest: rate limited", { org, retryAfterSec: decision.retryAfterSec });
4770
+ return { status: 429, body: { error: "too many requests" }, headers: { "retry-after": String(decision.retryAfterSec) } };
4771
+ }
4772
+ }
4755
4773
  try {
4756
4774
  const result = ingestEnvelope(store, parsed.data, opts);
4757
4775
  return { status: 200, body: result };
@@ -4762,6 +4780,39 @@ function createIngestHandler(store, opts = {}) {
4762
4780
  };
4763
4781
  }
4764
4782
 
4783
+ // src/central/quota.ts
4784
+ var DEFAULT_INGEST_QUOTA = { capacity: 120, refillMs: 6e4 };
4785
+ var MAX_KEYS = 1e4;
4786
+ var RateLimiter = class {
4787
+ constructor(cfg = DEFAULT_INGEST_QUOTA, now = () => Date.now()) {
4788
+ this.cfg = cfg;
4789
+ this.now = now;
4790
+ }
4791
+ buckets = /* @__PURE__ */ new Map();
4792
+ /** Consume one token for `key`. Returns whether the request is allowed (+ Retry-After when not). */
4793
+ take(key) {
4794
+ const t = this.now();
4795
+ const ratePerMs = this.cfg.capacity / this.cfg.refillMs;
4796
+ let b = this.buckets.get(key);
4797
+ if (!b) {
4798
+ if (this.buckets.size >= MAX_KEYS) {
4799
+ const oldest = this.buckets.keys().next().value;
4800
+ if (oldest !== void 0) this.buckets.delete(oldest);
4801
+ }
4802
+ b = { tokens: this.cfg.capacity, last: t };
4803
+ this.buckets.set(key, b);
4804
+ }
4805
+ b.tokens = Math.min(this.cfg.capacity, b.tokens + Math.max(0, t - b.last) * ratePerMs);
4806
+ b.last = t;
4807
+ if (b.tokens >= 1) {
4808
+ b.tokens -= 1;
4809
+ return { allowed: true, retryAfterSec: 0 };
4810
+ }
4811
+ const waitMs = (1 - b.tokens) / ratePerMs;
4812
+ return { allowed: false, retryAfterSec: Math.max(1, Math.ceil(waitMs / 1e3)) };
4813
+ }
4814
+ };
4815
+
4765
4816
  // src/scanners/bookmarks.ts
4766
4817
  var PERSONAL = [
4767
4818
  "facebook.",
@@ -5649,7 +5700,7 @@ async function resolveNlQuery(db, sessionId, search, raw, opts) {
5649
5700
 
5650
5701
  // src/mcp/server.ts
5651
5702
  var SERVER_NAME = "cartography";
5652
- var SERVER_VERSION = "2.6.0";
5703
+ var SERVER_VERSION = "2.7.0";
5653
5704
  var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
5654
5705
  var DATA_TYPES = NODE_TYPE_GROUPS.data;
5655
5706
  var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
@@ -6292,6 +6343,16 @@ async function runHttp(factory, opts = {}) {
6292
6343
  const httpServer = http.createServer(async (req, res) => {
6293
6344
  try {
6294
6345
  const url = req.url ?? "";
6346
+ const probePath = new URL(url || "/", "http://probe").pathname;
6347
+ if (probePath === "/healthz") {
6348
+ res.writeHead(200, { "content-type": "application/json" }).end('{"status":"ok"}');
6349
+ return;
6350
+ }
6351
+ if (probePath === "/readyz") {
6352
+ const r = opts.readiness ? opts.readiness() : { ready: true };
6353
+ res.writeHead(r.ready ? 200 : 503, { "content-type": "application/json" }).end(JSON.stringify({ status: r.ready ? "ready" : "unready" }));
6354
+ return;
6355
+ }
6295
6356
  const isIngest = url.startsWith("/ingest") && opts.onIngest !== void 0;
6296
6357
  if (!url.startsWith("/mcp") && !isIngest) {
6297
6358
  res.writeHead(404, { "content-type": "application/json" }).end('{"error":"not found"}');
@@ -6319,7 +6380,7 @@ async function runHttp(factory, opts = {}) {
6319
6380
  return;
6320
6381
  }
6321
6382
  const out = onIngest(value);
6322
- res.writeHead(out.status, { "content-type": "application/json" }).end(JSON.stringify(out.body));
6383
+ res.writeHead(out.status, { "content-type": "application/json", ...out.headers ?? {} }).end(JSON.stringify(out.body));
6323
6384
  return;
6324
6385
  }
6325
6386
  const sessionId = req.headers["mcp-session-id"];
@@ -11569,6 +11630,7 @@ export {
11569
11630
  CredentialConfigSchema,
11570
11631
  CsvCostSource,
11571
11632
  DEFAULT_ANOMALY_THRESHOLDS,
11633
+ DEFAULT_INGEST_QUOTA,
11572
11634
  DEFAULT_SERVER_NAME,
11573
11635
  DEFAULT_TENANT,
11574
11636
  DriftConfigSchema,
@@ -11590,10 +11652,12 @@ export {
11590
11652
  ProviderRegistry,
11591
11653
  RELATION_TO_DIRECTION,
11592
11654
  ROLES,
11655
+ RateLimiter,
11593
11656
  RoleSchema,
11594
11657
  RuleCheckSchema,
11595
11658
  RulesetSchema,
11596
11659
  SCAN_ARG_PATTERNS,
11660
+ SCHEMA_VERSION,
11597
11661
  SDL,
11598
11662
  SEVERITY_WEIGHT,
11599
11663
  SHARING_LEVELS,