@lucern/sdk 0.2.0-alpha.4 → 0.2.0-alpha.6
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/README.md +31 -0
- package/dist/.generated +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -8894
- package/dist/lib/platform/auth/credentials.d.ts +5 -0
- package/dist/lib/platform/auth/credentials.js +40 -0
- package/dist/lib/platform/sdk/adminClient.d.ts +404 -0
- package/dist/lib/platform/sdk/adminClient.js +384 -0
- package/dist/lib/platform/sdk/answersClient.d.ts +16 -0
- package/dist/lib/platform/sdk/answersClient.js +21 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/audiencesClient.d.ts +6 -0
- package/dist/lib/platform/sdk/audiencesClient.js +111 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/auditClient.d.ts +3 -0
- package/dist/lib/platform/sdk/auditClient.js +21 -0
- package/dist/lib/platform/sdk/beliefsClient.d.ts +157 -0
- package/dist/lib/platform/sdk/beliefsClient.js +124 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/client.d.ts +957 -146
- package/dist/lib/platform/sdk/client.js +1831 -0
- package/dist/lib/platform/sdk/contextClient.d.ts +21 -0
- package/dist/lib/platform/sdk/contextClient.js +86 -0
- package/dist/lib/platform/sdk/contextFacade.d.ts +10 -0
- package/dist/lib/platform/sdk/contextFacade.js +10 -0
- package/dist/{lucern/packages/domain-context/src/context-pack-compiler.d.ts → lib/platform/sdk/contextPackCompiler.d.ts} +2 -3
- package/dist/lib/platform/sdk/contextPackCompiler.js +534 -0
- package/dist/lib/platform/sdk/contextTypes.d.ts +133 -0
- package/dist/lib/platform/sdk/contextTypes.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/controlObjectOwnership.d.ts +15 -0
- package/dist/lib/platform/sdk/controlObjectOwnership.js +220 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/coreClient.d.ts +19 -0
- package/dist/lib/platform/sdk/coreClient.js +366 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/customTools.d.ts +21 -3
- package/dist/lib/platform/sdk/customTools.js +247 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/decisionsClient.d.ts +9 -0
- package/dist/lib/platform/sdk/decisionsClient.js +129 -0
- package/dist/lib/platform/sdk/domainContext.d.ts +1 -0
- package/dist/lib/platform/sdk/domainContext.js +1 -0
- package/dist/lib/platform/sdk/events.d.ts +176 -0
- package/dist/lib/platform/sdk/events.js +261 -0
- package/dist/lib/platform/sdk/eventsCore.d.ts +13 -0
- package/dist/lib/platform/sdk/eventsCore.js +13 -0
- package/dist/lib/platform/sdk/gatewayFacades.d.ts +586 -0
- package/dist/lib/platform/sdk/gatewayFacades.js +845 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/graphClient.d.ts +75 -0
- package/dist/lib/platform/sdk/graphClient.js +235 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/harnessClient.d.ts +90 -1
- package/dist/lib/platform/sdk/harnessClient.js +219 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/identityClient.d.ts +45 -15
- package/dist/lib/platform/sdk/identityClient.js +131 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/index.d.ts +24 -3
- package/dist/lib/platform/sdk/index.js +49 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/learningClient.d.ts +3 -0
- package/dist/lib/platform/sdk/learningClient.js +53 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParityClient.d.ts +1 -0
- package/dist/lib/platform/sdk/mcpParityClient.js +196 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParitySurface.d.ts +2 -0
- package/dist/lib/platform/sdk/mcpParitySurface.js +57 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/ontologyClient.d.ts +16 -0
- package/dist/lib/platform/sdk/ontologyClient.js +161 -0
- package/dist/lib/platform/sdk/packRuntime.d.ts +1 -0
- package/dist/lib/platform/sdk/packRuntime.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/packsClient.d.ts +25 -0
- package/dist/lib/platform/sdk/packsClient.js +157 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/policyClient.d.ts +90 -1
- package/dist/lib/platform/sdk/policyClient.js +277 -0
- package/dist/lib/platform/sdk/promptCatalog.d.ts +1 -0
- package/dist/lib/platform/sdk/promptCatalog.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/reportsClient.d.ts +3 -0
- package/dist/lib/platform/sdk/reportsClient.js +64 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/schemaClient.d.ts +5 -0
- package/dist/lib/platform/sdk/schemaClient.js +71 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/sdkSurface.d.ts +1 -0
- package/dist/lib/platform/sdk/sdkSurface.js +140 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/topicsClient.d.ts +33 -0
- package/dist/lib/platform/sdk/topicsClient.js +118 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/types.d.ts +224 -2
- package/dist/lib/platform/sdk/types.js +1 -0
- package/dist/lib/platform/sdk/version.js +2 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/workflowClient.d.ts +63 -2
- package/dist/lib/platform/sdk/workflowClient.js +366 -0
- package/dist/lucern/contracts/src/api-enums.contract.d.ts +58 -0
- package/dist/lucern/contracts/src/api-enums.contract.js +147 -0
- package/dist/lucern/contracts/src/auth-context.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/auth-context.contract.js +8 -0
- package/dist/lucern/contracts/src/auth-session.contract.d.ts +5 -50
- package/dist/lucern/contracts/src/auth-session.contract.js +8 -0
- package/dist/lucern/contracts/src/auth.contract.d.ts +88 -0
- package/dist/lucern/contracts/src/auth.contract.js +57 -0
- package/dist/lucern/contracts/src/context-pack.contract.js +169 -0
- package/dist/lucern/contracts/src/convex-admin.contract.d.ts +5 -0
- package/dist/lucern/contracts/src/convex-admin.contract.js +1 -0
- package/dist/lucern/contracts/src/events-types.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/events-types.contract.js +8 -0
- package/dist/lucern/{packages/events/src/types.d.ts → contracts/src/events.contract.d.ts} +25 -0
- package/dist/lucern/contracts/src/events.contract.js +159 -0
- package/dist/lucern/contracts/src/gateway.contract.d.ts +74 -0
- package/dist/lucern/contracts/src/gateway.contract.js +19 -0
- package/dist/lucern/contracts/src/ids.contract.js +24 -0
- package/dist/lucern/contracts/src/index.d.ts +29 -0
- package/dist/lucern/contracts/src/index.js +29 -0
- package/dist/lucern/contracts/src/lens-filter.contract.js +95 -0
- package/dist/lucern/contracts/src/lens-workflow.contract.js +54 -0
- package/dist/lucern/contracts/src/mcp-tools.contract.js +3281 -0
- package/dist/lucern/contracts/src/ontology-matching.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/ontology-matching.contract.js +8 -0
- package/dist/lucern/contracts/src/prompt.contract.d.ts +24 -0
- package/dist/lucern/contracts/src/prompt.contract.js +24 -0
- package/dist/lucern/contracts/src/sdk-methods.contract.d.ts +358 -0
- package/dist/lucern/contracts/src/sdk-methods.contract.js +19 -0
- package/dist/lucern/contracts/src/sdk-tools.contract.d.ts +92 -0
- package/dist/lucern/contracts/src/sdk-tools.contract.js +1398 -0
- package/dist/lucern/contracts/src/text-matching.contract.js +277 -0
- package/dist/lucern/contracts/src/topic-scope.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/topic-scope.contract.js +8 -0
- package/dist/lucern/contracts/src/workflow-runtime.contract.js +257 -0
- package/dist/realtime-refs.d.ts +1 -0
- package/dist/realtime-refs.js +1 -0
- package/dist/realtime.d.ts +1 -0
- package/dist/realtime.js +1 -0
- package/package.json +18 -5
- package/dist/index.js.map +0 -1
- package/dist/lucern/mcp-server/src/context-pack-policy.d.ts +0 -119
- package/dist/lucern/mcp-server/src/context-pack-schema.d.ts +0 -18
- package/dist/lucern/modules/graph-primitives/src/ontology-matching.d.ts +0 -78
- package/dist/lucern/packages/client-core/src/beliefs.d.ts +0 -30
- package/dist/lucern/packages/client-core/src/context.d.ts +0 -29
- package/dist/lucern/packages/client-core/src/contradictions.d.ts +0 -11
- package/dist/lucern/packages/client-core/src/edges.d.ts +0 -11
- package/dist/lucern/packages/client-core/src/events.d.ts +0 -9
- package/dist/lucern/packages/client-core/src/evidence.d.ts +0 -21
- package/dist/lucern/packages/client-core/src/graph.d.ts +0 -17
- package/dist/lucern/packages/client-core/src/identity.d.ts +0 -7
- package/dist/lucern/packages/client-core/src/ontologies.d.ts +0 -13
- package/dist/lucern/packages/client-core/src/questions.d.ts +0 -39
- package/dist/lucern/packages/client-core/src/search.d.ts +0 -7
- package/dist/lucern/packages/client-core/src/tasks.d.ts +0 -13
- package/dist/lucern/packages/client-core/src/topics.d.ts +0 -17
- package/dist/lucern/packages/client-core/src/webhooks.d.ts +0 -35
- package/dist/lucern/packages/client-core/src/worktrees.d.ts +0 -17
- package/dist/lucern/packages/domain-beliefs/src/beliefs.d.ts +0 -283
- package/dist/lucern/packages/domain-beliefs/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-context/src/compile.d.ts +0 -11
- package/dist/lucern/packages/domain-context/src/index.d.ts +0 -4
- package/dist/lucern/packages/domain-context/src/ports.d.ts +0 -58
- package/dist/lucern/packages/domain-context/src/public-types.d.ts +0 -1
- package/dist/lucern/packages/domain-edges/src/contradictions.d.ts +0 -59
- package/dist/lucern/packages/domain-edges/src/edges.d.ts +0 -91
- package/dist/lucern/packages/domain-edges/src/index.d.ts +0 -2
- package/dist/lucern/packages/domain-evidence/src/evidence.d.ts +0 -115
- package/dist/lucern/packages/domain-evidence/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-graph/src/graph.d.ts +0 -150
- package/dist/lucern/packages/domain-identity/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-identity/src/whoami.d.ts +0 -13
- package/dist/lucern/packages/domain-ontologies/src/ontologies.d.ts +0 -123
- package/dist/lucern/packages/domain-questions/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-questions/src/questions.d.ts +0 -147
- package/dist/lucern/packages/domain-search/src/search.d.ts +0 -97
- package/dist/lucern/packages/domain-tasks/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-tasks/src/tasks.d.ts +0 -102
- package/dist/lucern/packages/domain-topics/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-topics/src/topics.d.ts +0 -147
- package/dist/lucern/packages/domain-worktrees/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-worktrees/src/worktrees.d.ts +0 -185
- package/dist/lucern/packages/events/src/index.d.ts +0 -4
- package/dist/lucern/packages/events/src/matching.d.ts +0 -3
- package/dist/lucern/packages/events/src/outbox.d.ts +0 -15
- package/dist/lucern/packages/events/src/webhooks.d.ts +0 -9
- package/dist/lucern/packages/sdk-typescript/src/facade/beliefs.d.ts +0 -15
- package/dist/lucern/packages/sdk-typescript/src/facade/context.d.ts +0 -12
- package/dist/lucern/packages/sdk-typescript/src/facade/contradictions.d.ts +0 -7
- package/dist/lucern/packages/sdk-typescript/src/facade/edges.d.ts +0 -7
- package/dist/lucern/packages/sdk-typescript/src/facade/events.d.ts +0 -6
- package/dist/lucern/packages/sdk-typescript/src/facade/evidence.d.ts +0 -21
- package/dist/lucern/packages/sdk-typescript/src/facade/graph.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/facade/identity.d.ts +0 -5
- package/dist/lucern/packages/sdk-typescript/src/facade/ontologies.d.ts +0 -8
- package/dist/lucern/packages/sdk-typescript/src/facade/questions.d.ts +0 -39
- package/dist/lucern/packages/sdk-typescript/src/facade/search.d.ts +0 -5
- package/dist/lucern/packages/sdk-typescript/src/facade/tasks.d.ts +0 -8
- package/dist/lucern/packages/sdk-typescript/src/facade/topics.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/facade/webhooks.d.ts +0 -16
- package/dist/lucern/packages/sdk-typescript/src/facade/worktrees.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/index.d.ts +0 -28
- package/dist/packages/sdk/src/adminClient.d.ts +0 -89
- package/dist/packages/sdk/src/answersClient.d.ts +0 -5
- package/dist/packages/sdk/src/beliefsClient.d.ts +0 -52
- package/dist/packages/sdk/src/contextClient.d.ts +0 -9
- package/dist/packages/sdk/src/contracts/api-enums.contract.d.ts +0 -79
- /package/dist/{packages/sdk/src → lib/platform/sdk}/version.d.ts +0 -0
- /package/dist/lucern/{packages/client-core/src/ids.d.ts → contracts/src/ids.contract.d.ts} +0 -0
- /package/dist/lucern/{modules/graph-primitives/src/text-matching.d.ts → contracts/src/text-matching.contract.d.ts} +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — auth (canonical support contract)
|
|
3
|
+
*
|
|
4
|
+
* Consolidated flat support surface for Lucern authentication:
|
|
5
|
+
* - Session primitives (auth modes, principal types, lifecycle)
|
|
6
|
+
* - AuthContext shape + McpTransportKind + LucernSdkClient alias
|
|
7
|
+
*
|
|
8
|
+
* Consolidated from src/auth-session.contract.ts and src/auth-context.contract.ts
|
|
9
|
+
* in EK-16 T1 PR 3a. Compat shims remain at both old paths until Lucern 1.0.0 (D12).
|
|
10
|
+
*/
|
|
11
|
+
export declare const SESSION_AUTH_MODES: readonly ["interactive_user", "service_principal", "tenant_api_key", "session_token"];
|
|
12
|
+
export type SessionAuthMode = (typeof SESSION_AUTH_MODES)[number];
|
|
13
|
+
export declare const SESSION_PRINCIPAL_TYPES: readonly ["human", "service", "agent"];
|
|
14
|
+
export type SessionPrincipalType = (typeof SESSION_PRINCIPAL_TYPES)[number];
|
|
15
|
+
export declare const SESSION_LIFECYCLE_STATUSES: readonly ["active", "expired", "revoked"];
|
|
16
|
+
export type SessionLifecycleStatus = (typeof SESSION_LIFECYCLE_STATUSES)[number];
|
|
17
|
+
export type SessionDelegationHop = {
|
|
18
|
+
principalId: string;
|
|
19
|
+
principalType: SessionPrincipalType;
|
|
20
|
+
authMode?: SessionAuthMode;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
delegatedAt?: number;
|
|
23
|
+
reason?: string;
|
|
24
|
+
};
|
|
25
|
+
export type SessionAuditOutcome = "accepted" | "rejected" | "revoked" | "expired";
|
|
26
|
+
export type SessionAuditEnvelope = {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
authMode: SessionAuthMode;
|
|
29
|
+
principalId: string;
|
|
30
|
+
principalType: SessionPrincipalType;
|
|
31
|
+
tenantId: string;
|
|
32
|
+
workspaceId?: string;
|
|
33
|
+
apiKeyId?: string;
|
|
34
|
+
scopes: readonly string[];
|
|
35
|
+
roles?: readonly string[];
|
|
36
|
+
delegationChain?: readonly SessionDelegationHop[];
|
|
37
|
+
sourceSessionId?: string;
|
|
38
|
+
expiresAt?: number;
|
|
39
|
+
request?: {
|
|
40
|
+
endpoint?: string;
|
|
41
|
+
method?: string;
|
|
42
|
+
correlationId?: string;
|
|
43
|
+
};
|
|
44
|
+
result?: {
|
|
45
|
+
outcome: SessionAuditOutcome;
|
|
46
|
+
reason?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export declare function inferSessionPrincipalType(principalId: string): SessionPrincipalType;
|
|
50
|
+
export declare function normalizeDelegationChain(args: {
|
|
51
|
+
delegationChain?: readonly SessionDelegationHop[];
|
|
52
|
+
delegatedBy?: string;
|
|
53
|
+
delegatedByType?: SessionPrincipalType;
|
|
54
|
+
delegatedAt?: number;
|
|
55
|
+
reason?: string;
|
|
56
|
+
}): SessionDelegationHop[] | undefined;
|
|
57
|
+
export declare function lastDelegator(delegationChain?: readonly SessionDelegationHop[]): string | undefined;
|
|
58
|
+
import type { ConvexAdminClient } from "./convex-admin.contract";
|
|
59
|
+
export type McpTransportKind = "stdio" | "hosted";
|
|
60
|
+
export type LucernSdkClient = unknown;
|
|
61
|
+
/**
|
|
62
|
+
* Session authentication context — injected by withAuth() middleware.
|
|
63
|
+
*
|
|
64
|
+
* Built from TenantConfig at dispatch time. Agent sessions get
|
|
65
|
+
* AGENT_IDENTITY + "agent:internal" role + unrestricted access.
|
|
66
|
+
* User sessions get Clerk userId + resolved role + tool ACLs.
|
|
67
|
+
*/
|
|
68
|
+
export type AuthContext = {
|
|
69
|
+
sessionType: "agent" | "user";
|
|
70
|
+
userId: string;
|
|
71
|
+
tenantId: string;
|
|
72
|
+
role: string;
|
|
73
|
+
allowedTopics: string[] | null;
|
|
74
|
+
groupIds: string[];
|
|
75
|
+
permittedPackKeys: string[];
|
|
76
|
+
sessionId: string;
|
|
77
|
+
principalId?: string;
|
|
78
|
+
principalType?: SessionPrincipalType;
|
|
79
|
+
workspaceId?: string;
|
|
80
|
+
scopes?: string[];
|
|
81
|
+
authMode?: SessionAuthMode;
|
|
82
|
+
roles?: string[];
|
|
83
|
+
transportKind?: McpTransportKind;
|
|
84
|
+
lucernClient?: LucernSdkClient;
|
|
85
|
+
convex?: ConvexAdminClient;
|
|
86
|
+
setDefaultScopeContext?: (scopeId: string) => Promise<unknown>;
|
|
87
|
+
matchesWorkspaceReasoningScope?: (node: unknown, scope: unknown) => boolean;
|
|
88
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — auth (canonical support contract)
|
|
3
|
+
*
|
|
4
|
+
* Consolidated flat support surface for Lucern authentication:
|
|
5
|
+
* - Session primitives (auth modes, principal types, lifecycle)
|
|
6
|
+
* - AuthContext shape + McpTransportKind + LucernSdkClient alias
|
|
7
|
+
*
|
|
8
|
+
* Consolidated from src/auth-session.contract.ts and src/auth-context.contract.ts
|
|
9
|
+
* in EK-16 T1 PR 3a. Compat shims remain at both old paths until Lucern 1.0.0 (D12).
|
|
10
|
+
*/
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// SESSION PRIMITIVES
|
|
13
|
+
// (Formerly src/auth-session.contract.ts)
|
|
14
|
+
// =============================================================================
|
|
15
|
+
export const SESSION_AUTH_MODES = [
|
|
16
|
+
"interactive_user",
|
|
17
|
+
"service_principal",
|
|
18
|
+
"tenant_api_key",
|
|
19
|
+
"session_token",
|
|
20
|
+
];
|
|
21
|
+
export const SESSION_PRINCIPAL_TYPES = ["human", "service", "agent"];
|
|
22
|
+
export const SESSION_LIFECYCLE_STATUSES = [
|
|
23
|
+
"active",
|
|
24
|
+
"expired",
|
|
25
|
+
"revoked",
|
|
26
|
+
];
|
|
27
|
+
export function inferSessionPrincipalType(principalId) {
|
|
28
|
+
if (principalId.startsWith("user:")) {
|
|
29
|
+
return "human";
|
|
30
|
+
}
|
|
31
|
+
if (principalId.startsWith("agent:")) {
|
|
32
|
+
return "agent";
|
|
33
|
+
}
|
|
34
|
+
return "service";
|
|
35
|
+
}
|
|
36
|
+
export function normalizeDelegationChain(args) {
|
|
37
|
+
if (args.delegationChain && args.delegationChain.length > 0) {
|
|
38
|
+
return [...args.delegationChain];
|
|
39
|
+
}
|
|
40
|
+
if (!args.delegatedBy) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
return [
|
|
44
|
+
{
|
|
45
|
+
principalId: args.delegatedBy,
|
|
46
|
+
principalType: args.delegatedByType ?? inferSessionPrincipalType(args.delegatedBy),
|
|
47
|
+
delegatedAt: args.delegatedAt,
|
|
48
|
+
reason: args.reason,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
export function lastDelegator(delegationChain) {
|
|
53
|
+
if (!delegationChain || delegationChain.length === 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
return delegationChain[delegationChain.length - 1]?.principalId;
|
|
57
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-Pack Contract v1
|
|
3
|
+
*
|
|
4
|
+
* Canonical TypeScript types and constants for the context-pack output schema.
|
|
5
|
+
* This is the external contract consumed by:
|
|
6
|
+
* - MCP tool `compile_context` (canonical compiler read)
|
|
7
|
+
* - SDK/HTTP consumers that read compiled context packs programmatically
|
|
8
|
+
* - Benchmark harnesses (context-pack-ab)
|
|
9
|
+
*
|
|
10
|
+
* BREAKING CHANGE RULES:
|
|
11
|
+
* - Adding optional fields to ContextPackV1 is NON-breaking
|
|
12
|
+
* - Removing fields or changing types is BREAKING (bump CONTEXT_PACK_SCHEMA_VERSION)
|
|
13
|
+
* - Changing section budget ratios or ranking weights is NON-breaking (tuning)
|
|
14
|
+
* - Changing the version string is BREAKING (consumers check it)
|
|
15
|
+
*/
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// SCHEMA VERSION
|
|
18
|
+
// =============================================================================
|
|
19
|
+
/** Canonical version string. Consumers MUST check this field for compatibility. */
|
|
20
|
+
export const CONTEXT_PACK_SCHEMA_VERSION = "1.0.0";
|
|
21
|
+
export const CONTEXT_RANKING_PROFILES = [
|
|
22
|
+
"baseline_v1",
|
|
23
|
+
"weighted_v1",
|
|
24
|
+
];
|
|
25
|
+
export const DEFAULT_RANKING_PROFILE = "weighted_v1";
|
|
26
|
+
export const DEFAULT_COMPILATION_MODE = "standard";
|
|
27
|
+
export const CONTEXT_PACK_SECTION_KEYS = [
|
|
28
|
+
"invariants",
|
|
29
|
+
"activeBeliefs",
|
|
30
|
+
"openQuestions",
|
|
31
|
+
"recentEvidence",
|
|
32
|
+
"contradictions",
|
|
33
|
+
];
|
|
34
|
+
// =============================================================================
|
|
35
|
+
// SECTION BUDGET RATIOS
|
|
36
|
+
// =============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Token budget allocation ratios per section.
|
|
39
|
+
* These sum to 1.0 and determine how the total tokenBudget is divided.
|
|
40
|
+
*
|
|
41
|
+
* Rationale:
|
|
42
|
+
* - invariants (0.28): Highest-priority constraints, injected first
|
|
43
|
+
* - activeBeliefs (0.30): Largest section, carries domain knowledge
|
|
44
|
+
* - openQuestions (0.17): Unresolved work items guide agent behavior
|
|
45
|
+
* - recentEvidence (0.17): Implementation context for grounding
|
|
46
|
+
* - contradictions (0.08): Tension signals, smallest section
|
|
47
|
+
*/
|
|
48
|
+
export const SECTION_BUDGET_RATIOS = {
|
|
49
|
+
invariants: 0.28,
|
|
50
|
+
activeBeliefs: 0.3,
|
|
51
|
+
openQuestions: 0.17,
|
|
52
|
+
recentEvidence: 0.17,
|
|
53
|
+
contradictions: 0.08,
|
|
54
|
+
};
|
|
55
|
+
// =============================================================================
|
|
56
|
+
// TOKEN BUDGET CONSTRAINTS
|
|
57
|
+
// =============================================================================
|
|
58
|
+
/** Minimum allowed token budget. Below this, context packs lose utility. */
|
|
59
|
+
export const MIN_TOKEN_BUDGET = 400;
|
|
60
|
+
/** Maximum allowed token budget. Above this, context packs bloat prompts. */
|
|
61
|
+
export const MAX_TOKEN_BUDGET = 8000;
|
|
62
|
+
/** Default token budget when caller does not specify. */
|
|
63
|
+
export const DEFAULT_TOKEN_BUDGET = 1800;
|
|
64
|
+
/** Default max items per section. */
|
|
65
|
+
export const DEFAULT_SECTION_LIMIT = 8;
|
|
66
|
+
/** Hard ceiling on items per section. */
|
|
67
|
+
export const MAX_SECTION_LIMIT = 25;
|
|
68
|
+
/** Minimum contradiction section budget floor (tokens). */
|
|
69
|
+
export const MIN_CONTRADICTION_BUDGET = 40;
|
|
70
|
+
export const RANKING_WEIGHTS = {
|
|
71
|
+
invariants: {
|
|
72
|
+
query: 0.35,
|
|
73
|
+
recency: 0.1,
|
|
74
|
+
confidence: 0.4,
|
|
75
|
+
beliefType: 0.15,
|
|
76
|
+
},
|
|
77
|
+
activeBeliefs: {
|
|
78
|
+
query: 0.5,
|
|
79
|
+
recency: 0.2,
|
|
80
|
+
confidence: 0.2,
|
|
81
|
+
beliefType: 0.1,
|
|
82
|
+
},
|
|
83
|
+
openQuestions: {
|
|
84
|
+
query: 0.55,
|
|
85
|
+
recency: 0.2,
|
|
86
|
+
priority: 0.25,
|
|
87
|
+
},
|
|
88
|
+
recentEvidence: {
|
|
89
|
+
query: 0.6,
|
|
90
|
+
recency: 0.4,
|
|
91
|
+
},
|
|
92
|
+
contradictions: {
|
|
93
|
+
query: 0.4,
|
|
94
|
+
recency: 0.2,
|
|
95
|
+
severity: 0.4,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
/** Recency decay half-life in days. After 30 days, recency score = 0.5. */
|
|
99
|
+
export const RECENCY_HALF_LIFE_DAYS = 30;
|
|
100
|
+
/**
|
|
101
|
+
* Ranking weight vector for the relatedEntities section.
|
|
102
|
+
* Entities are ranked by query relevance and connectivity (bridge edge count).
|
|
103
|
+
* Separate from RANKING_WEIGHTS because entities are not part of the
|
|
104
|
+
* token-budgeted injection plan.
|
|
105
|
+
*/
|
|
106
|
+
export const ENTITY_RANKING_WEIGHTS = {
|
|
107
|
+
query: 0.4,
|
|
108
|
+
connectivity: 0.6,
|
|
109
|
+
};
|
|
110
|
+
/** Default max entities to include in the context pack. */
|
|
111
|
+
export const DEFAULT_ENTITY_LIMIT = 10;
|
|
112
|
+
/** Hard ceiling on entities per context pack. */
|
|
113
|
+
export const MAX_ENTITY_LIMIT = 50;
|
|
114
|
+
// =============================================================================
|
|
115
|
+
// BELIEF TYPE BONUS MAP
|
|
116
|
+
// =============================================================================
|
|
117
|
+
/**
|
|
118
|
+
* Bonus multiplier for belief types in ranking.
|
|
119
|
+
* Invariants get 1.0, unknown types get 0.4.
|
|
120
|
+
*/
|
|
121
|
+
export const BELIEF_TYPE_BONUS = {
|
|
122
|
+
invariant: 1.0,
|
|
123
|
+
tenet: 0.8,
|
|
124
|
+
principle: 0.6,
|
|
125
|
+
};
|
|
126
|
+
export const DEFAULT_BELIEF_TYPE_BONUS = 0.4;
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// PRIORITY / SEVERITY SCORE MAPS
|
|
129
|
+
// =============================================================================
|
|
130
|
+
export const PRIORITY_SCORES = {
|
|
131
|
+
critical: 1.0,
|
|
132
|
+
high: 0.85,
|
|
133
|
+
medium: 0.55,
|
|
134
|
+
low: 0.35,
|
|
135
|
+
};
|
|
136
|
+
export const DEFAULT_PRIORITY_SCORE = 0.5;
|
|
137
|
+
export const SEVERITY_SCORES = {
|
|
138
|
+
critical: 1.0,
|
|
139
|
+
high: 0.85,
|
|
140
|
+
medium: 0.6,
|
|
141
|
+
low: 0.35,
|
|
142
|
+
};
|
|
143
|
+
export const DEFAULT_SEVERITY_SCORE = 0.5;
|
|
144
|
+
// =============================================================================
|
|
145
|
+
// RESOLVED QUESTION STATUSES
|
|
146
|
+
// =============================================================================
|
|
147
|
+
/**
|
|
148
|
+
* Question statuses that are considered "resolved" (not open).
|
|
149
|
+
* Used to filter which questions appear in the openQuestions section.
|
|
150
|
+
*/
|
|
151
|
+
export const RESOLVED_QUESTION_STATUSES = [
|
|
152
|
+
"answered",
|
|
153
|
+
"archived",
|
|
154
|
+
"closed",
|
|
155
|
+
"resolved",
|
|
156
|
+
"resolved_support",
|
|
157
|
+
"resolved_contra",
|
|
158
|
+
"belief_forked",
|
|
159
|
+
];
|
|
160
|
+
// =============================================================================
|
|
161
|
+
// TOKEN ESTIMATION
|
|
162
|
+
// =============================================================================
|
|
163
|
+
/**
|
|
164
|
+
* Tokens-per-word multiplier for rough token estimation.
|
|
165
|
+
* Conservative estimate: ~1.35 tokens per whitespace-delimited word.
|
|
166
|
+
*/
|
|
167
|
+
export const TOKENS_PER_WORD = 1.35;
|
|
168
|
+
/** Minimum token estimate for any non-empty string. */
|
|
169
|
+
export const MIN_TOKEN_ESTIMATE = 8;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export interface ConvexAdminClient {
|
|
2
|
+
query<T = unknown>(functionReference: unknown, args: Record<string, unknown>): Promise<T>;
|
|
3
|
+
mutation<T = unknown>(functionReference: unknown, args: Record<string, unknown>): Promise<T>;
|
|
4
|
+
action<T = unknown>(functionReference: unknown, args: Record<string, unknown>): Promise<T>;
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — events-types compat shim
|
|
3
|
+
*
|
|
4
|
+
* This file consolidated into ./events.contract.ts during EK-16 T1 PR 3b.
|
|
5
|
+
* Retained here until the Lucern 1.0.0 barrel-sunset cut (D12).
|
|
6
|
+
* New code should import from "@lucern/contracts" (barrel) or "./events.contract".
|
|
7
|
+
*/
|
|
8
|
+
export * from "./events.contract";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — events-types compat shim
|
|
3
|
+
*
|
|
4
|
+
* This file consolidated into ./events.contract.ts during EK-16 T1 PR 3b.
|
|
5
|
+
* Retained here until the Lucern 1.0.0 barrel-sunset cut (D12).
|
|
6
|
+
* New code should import from "@lucern/contracts" (barrel) or "./events.contract".
|
|
7
|
+
*/
|
|
8
|
+
export * from "./events.contract.js";
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — events (canonical support contract)
|
|
3
|
+
*
|
|
4
|
+
* Consolidated flat support surface for Lucern's domain event stream:
|
|
5
|
+
* - Event type definitions, constants, and shared enums
|
|
6
|
+
* - Event construction + cursor helpers
|
|
7
|
+
*
|
|
8
|
+
* Consolidated from the former split type-definition module
|
|
9
|
+
* and the prior src/events.contract.ts (helpers) in EK-16 T1 PR 3b.
|
|
10
|
+
* Compat shim remains at the old events-types path until Lucern 1.0.0 (D12).
|
|
11
|
+
*/
|
|
1
12
|
export declare const DOMAIN_EVENT_VERSION: "1.0";
|
|
2
13
|
export declare const EVENT_RETENTION_DEFAULT_DAYS = 30;
|
|
3
14
|
export declare const WEBHOOK_MAX_ATTEMPTS = 5;
|
|
@@ -149,3 +160,17 @@ export type ReplayEventsResult = EventListResult & {
|
|
|
149
160
|
replayedDeliveries?: number;
|
|
150
161
|
replayedWebhookId?: string;
|
|
151
162
|
};
|
|
163
|
+
export declare function createEventId(): string;
|
|
164
|
+
export declare function normalizeRetentionDays(value: number | undefined): number;
|
|
165
|
+
export declare function buildDomainEvent(input: CreateDomainEventInput): DomainEvent;
|
|
166
|
+
export declare function compareEventCursor(left: EventCursor, right: EventCursor): number;
|
|
167
|
+
export declare function encodeEventCursor(cursor: EventCursor): string;
|
|
168
|
+
export declare function decodeEventCursor(cursor: string | undefined): EventCursor | null;
|
|
169
|
+
export declare function isAfterCursor(event: Pick<DomainEvent, "timestamp" | "eventId">, cursor: EventCursor | null): boolean;
|
|
170
|
+
export declare function sortEventsByCursor<T extends Pick<DomainEvent, "timestamp" | "eventId">>(events: readonly T[]): T[];
|
|
171
|
+
export declare function inferActorType(args: {
|
|
172
|
+
sessionType?: "agent" | "user";
|
|
173
|
+
authMode?: string;
|
|
174
|
+
principalType?: string;
|
|
175
|
+
}): DomainActorType;
|
|
176
|
+
export declare function emitDomainEvent(invokeMutation: (reference: any, args: CreateDomainEventInput) => Promise<unknown>, input: CreateDomainEventInput): Promise<unknown>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lucern/contracts — events (canonical support contract)
|
|
3
|
+
*
|
|
4
|
+
* Consolidated flat support surface for Lucern's domain event stream:
|
|
5
|
+
* - Event type definitions, constants, and shared enums
|
|
6
|
+
* - Event construction + cursor helpers
|
|
7
|
+
*
|
|
8
|
+
* Consolidated from the former split type-definition module
|
|
9
|
+
* and the prior src/events.contract.ts (helpers) in EK-16 T1 PR 3b.
|
|
10
|
+
* Compat shim remains at the old events-types path until Lucern 1.0.0 (D12).
|
|
11
|
+
*/
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// EVENT TYPE DEFINITIONS & CONSTANTS
|
|
14
|
+
// (Formerly the split events type-definition module)
|
|
15
|
+
// =============================================================================
|
|
16
|
+
export const DOMAIN_EVENT_VERSION = "1.0";
|
|
17
|
+
export const EVENT_RETENTION_DEFAULT_DAYS = 30;
|
|
18
|
+
export const WEBHOOK_MAX_ATTEMPTS = 5;
|
|
19
|
+
export const WEBHOOK_RETRY_DELAYS_MS = [1_000, 5_000, 30_000, 300_000];
|
|
20
|
+
export const DOMAIN_EVENT_TYPES = [
|
|
21
|
+
"belief.created",
|
|
22
|
+
"belief.forked",
|
|
23
|
+
"belief.confidence_updated",
|
|
24
|
+
"belief.archived",
|
|
25
|
+
"belief.refined",
|
|
26
|
+
"belief.contract_created",
|
|
27
|
+
"belief.contract_evaluated",
|
|
28
|
+
"belief.lineage_queried",
|
|
29
|
+
"evidence.created",
|
|
30
|
+
"evidence.linked",
|
|
31
|
+
"evidence.search_executed",
|
|
32
|
+
"question.created",
|
|
33
|
+
"question.answered",
|
|
34
|
+
"question.refined",
|
|
35
|
+
"question.status_updated",
|
|
36
|
+
"question.archived",
|
|
37
|
+
"edge.created",
|
|
38
|
+
"contradiction.flagged",
|
|
39
|
+
"worktree.created",
|
|
40
|
+
"worktree.activated",
|
|
41
|
+
"worktree.merged",
|
|
42
|
+
"worktree.targets_updated",
|
|
43
|
+
"worktree.metadata_updated",
|
|
44
|
+
"topic.created",
|
|
45
|
+
"topic.updated",
|
|
46
|
+
"topic.archived",
|
|
47
|
+
"task.created",
|
|
48
|
+
"task.completed",
|
|
49
|
+
"task.updated",
|
|
50
|
+
"ontology.bound",
|
|
51
|
+
"context.compiled",
|
|
52
|
+
"identity.key_created",
|
|
53
|
+
"identity.key_rotated",
|
|
54
|
+
"identity.key_revoked",
|
|
55
|
+
"webhook.test",
|
|
56
|
+
];
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// EVENT HELPERS
|
|
59
|
+
// (Formerly the body of src/events.contract.ts)
|
|
60
|
+
// =============================================================================
|
|
61
|
+
function toBase64(value) {
|
|
62
|
+
if (typeof Buffer !== "undefined") {
|
|
63
|
+
return Buffer.from(value, "utf8").toString("base64url");
|
|
64
|
+
}
|
|
65
|
+
return btoa(unescape(encodeURIComponent(value)))
|
|
66
|
+
.replace(/\+/g, "-")
|
|
67
|
+
.replace(/\//g, "_")
|
|
68
|
+
.replace(/=+$/g, "");
|
|
69
|
+
}
|
|
70
|
+
function fromBase64(value) {
|
|
71
|
+
if (typeof Buffer !== "undefined") {
|
|
72
|
+
return Buffer.from(value, "base64url").toString("utf8");
|
|
73
|
+
}
|
|
74
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
75
|
+
return decodeURIComponent(escape(atob(normalized)));
|
|
76
|
+
}
|
|
77
|
+
export function createEventId() {
|
|
78
|
+
const random = crypto.randomUUID().replace(/-/g, "");
|
|
79
|
+
return `evt_${random}`;
|
|
80
|
+
}
|
|
81
|
+
export function normalizeRetentionDays(value) {
|
|
82
|
+
if (!Number.isFinite(value) || typeof value !== "number" || value <= 0) {
|
|
83
|
+
return EVENT_RETENTION_DEFAULT_DAYS;
|
|
84
|
+
}
|
|
85
|
+
return Math.max(1, Math.trunc(value));
|
|
86
|
+
}
|
|
87
|
+
export function buildDomainEvent(input) {
|
|
88
|
+
const timestamp = input.timestamp ?? Date.now();
|
|
89
|
+
const retentionDays = normalizeRetentionDays(input.retentionDays);
|
|
90
|
+
return {
|
|
91
|
+
eventId: input.eventId?.trim() || createEventId(),
|
|
92
|
+
type: input.type.trim(),
|
|
93
|
+
version: DOMAIN_EVENT_VERSION,
|
|
94
|
+
timestamp,
|
|
95
|
+
tenantId: input.tenantId?.trim() || undefined,
|
|
96
|
+
workspaceId: input.workspaceId?.trim() || undefined,
|
|
97
|
+
topicId: input.topicId.trim(),
|
|
98
|
+
resourceId: input.resourceId.trim(),
|
|
99
|
+
resourceType: input.resourceType.trim(),
|
|
100
|
+
actorId: input.actorId.trim(),
|
|
101
|
+
actorType: input.actorType,
|
|
102
|
+
data: input.data ?? {},
|
|
103
|
+
correlationId: input.correlationId?.trim() || undefined,
|
|
104
|
+
expiresAt: timestamp + retentionDays * 24 * 60 * 60 * 1000,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function compareEventCursor(left, right) {
|
|
108
|
+
if (left.timestamp !== right.timestamp) {
|
|
109
|
+
return left.timestamp - right.timestamp;
|
|
110
|
+
}
|
|
111
|
+
return left.eventId.localeCompare(right.eventId);
|
|
112
|
+
}
|
|
113
|
+
export function encodeEventCursor(cursor) {
|
|
114
|
+
return toBase64(JSON.stringify(cursor));
|
|
115
|
+
}
|
|
116
|
+
export function decodeEventCursor(cursor) {
|
|
117
|
+
if (!cursor || cursor.trim().length === 0) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const parsed = JSON.parse(fromBase64(cursor.trim()));
|
|
122
|
+
if (typeof parsed.timestamp !== "number" ||
|
|
123
|
+
!Number.isFinite(parsed.timestamp) ||
|
|
124
|
+
typeof parsed.eventId !== "string" ||
|
|
125
|
+
parsed.eventId.trim().length === 0) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
timestamp: parsed.timestamp,
|
|
130
|
+
eventId: parsed.eventId.trim(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export function isAfterCursor(event, cursor) {
|
|
138
|
+
if (!cursor) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
return compareEventCursor(event, cursor) > 0;
|
|
142
|
+
}
|
|
143
|
+
export function sortEventsByCursor(events) {
|
|
144
|
+
return [...events].sort((left, right) => compareEventCursor(left, right));
|
|
145
|
+
}
|
|
146
|
+
export function inferActorType(args) {
|
|
147
|
+
if (args.sessionType === "agent") {
|
|
148
|
+
return "agent";
|
|
149
|
+
}
|
|
150
|
+
if (args.authMode === "service_principal" ||
|
|
151
|
+
args.authMode === "tenant_api_key" ||
|
|
152
|
+
args.principalType === "service") {
|
|
153
|
+
return "service";
|
|
154
|
+
}
|
|
155
|
+
return "human";
|
|
156
|
+
}
|
|
157
|
+
export async function emitDomainEvent(invokeMutation, input) {
|
|
158
|
+
return await invokeMutation("events:recordEvent", input);
|
|
159
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gateway contract types — shared between Stack's gateway middleware and
|
|
3
|
+
* Lucern's server-core / gateway route handlers.
|
|
4
|
+
*
|
|
5
|
+
* These types describe the authenticated request context that flows from
|
|
6
|
+
* the gateway into Lucern route handlers. The gateway (Stack-side) creates
|
|
7
|
+
* the context; Lucern consumes it read-only.
|
|
8
|
+
*
|
|
9
|
+
* @module @lucern/contracts/src/gateway
|
|
10
|
+
*/
|
|
11
|
+
import type { SessionAuthMode, SessionDelegationHop, SessionPrincipalType } from "./auth-session.contract";
|
|
12
|
+
export type PlatformApiErrorCode = "AUTH_REQUIRED" | "AUTHENTICATION_REQUIRED" | "AUTH_TOKEN_MISSING" | "INVALID_REQUEST" | "IDEMPOTENCY_KEY_REQUIRED" | "FORBIDDEN" | "SCOPE_INSUFFICIENT" | "ENVIRONMENT_MISMATCH" | "KEY_EXPIRED" | "KEY_REVOKED" | "RATE_LIMIT_EXCEEDED" | "NOT_FOUND" | "CONFLICT" | "UPSTREAM_ERROR" | "INTERNAL_ERROR";
|
|
13
|
+
export type GatewayScope = {
|
|
14
|
+
tenantId?: string;
|
|
15
|
+
workspaceId?: string;
|
|
16
|
+
};
|
|
17
|
+
export type GatewayEnvironment = "sandbox" | "production";
|
|
18
|
+
export type GatewayAuthMode = "interactive_user" | "service_principal" | "tenant_api_key" | "session_token";
|
|
19
|
+
export type KeyLifecycleStatus = "active" | "rotating" | "rotated" | "expired" | "revoked";
|
|
20
|
+
export type CutoverDomain = "graph" | "schema" | "identity" | "policy" | "audit" | "admin" | "agent" | "tool" | "prompt" | "intelligence";
|
|
21
|
+
export type CutoverFlagState = "legacy" | "cutover" | "disabled";
|
|
22
|
+
/**
|
|
23
|
+
* Authenticated request context created by the gateway middleware.
|
|
24
|
+
* Lucern route handlers receive this as a read-only parameter.
|
|
25
|
+
*
|
|
26
|
+
* The `convex` field is typed as `unknown` in the contract because Lucern
|
|
27
|
+
* consumers should not use the gateway's Convex client directly — they
|
|
28
|
+
* have their own kernel client. The gateway (Stack-side) narrows this to
|
|
29
|
+
* `ConvexHttpClient` at the construction site.
|
|
30
|
+
*/
|
|
31
|
+
export type GatewayAuthContext = {
|
|
32
|
+
userId: string;
|
|
33
|
+
convexToken?: string;
|
|
34
|
+
/** Opaque in contract — narrowed to ConvexHttpClient at the gateway. */
|
|
35
|
+
convex: any;
|
|
36
|
+
authMode: GatewayAuthMode;
|
|
37
|
+
principalId?: string;
|
|
38
|
+
principalType?: SessionPrincipalType;
|
|
39
|
+
tenantId?: string;
|
|
40
|
+
workspaceId?: string;
|
|
41
|
+
roles?: string[];
|
|
42
|
+
sessionId?: string;
|
|
43
|
+
sessionAuthMode?: SessionAuthMode;
|
|
44
|
+
sessionExpiresAt?: number;
|
|
45
|
+
delegationChain?: SessionDelegationHop[];
|
|
46
|
+
servicePrincipalId?: string;
|
|
47
|
+
servicePrincipalKeyId?: string;
|
|
48
|
+
servicePrincipalTenantId?: string;
|
|
49
|
+
servicePrincipalWorkspaceId?: string;
|
|
50
|
+
requestEnvironment: GatewayEnvironment;
|
|
51
|
+
keyEnvironment?: GatewayEnvironment;
|
|
52
|
+
keyStatus: KeyLifecycleStatus | "unknown";
|
|
53
|
+
grantedScopes: Set<string>;
|
|
54
|
+
cutoverDomain: CutoverDomain;
|
|
55
|
+
cutoverState: CutoverFlagState;
|
|
56
|
+
};
|
|
57
|
+
export type GatewayErrorArgs = {
|
|
58
|
+
code: PlatformApiErrorCode;
|
|
59
|
+
message: string;
|
|
60
|
+
status: number;
|
|
61
|
+
correlationId: string;
|
|
62
|
+
policyTraceId?: string;
|
|
63
|
+
invariant?: string;
|
|
64
|
+
suggestion?: string;
|
|
65
|
+
details?: unknown;
|
|
66
|
+
headers?: HeadersInit;
|
|
67
|
+
};
|
|
68
|
+
export type GatewaySuccessArgs = {
|
|
69
|
+
status?: number;
|
|
70
|
+
correlationId: string;
|
|
71
|
+
policyTraceId?: string;
|
|
72
|
+
idempotentReplay?: boolean;
|
|
73
|
+
};
|
|
74
|
+
export declare function requireActorPrincipalId(authContext: GatewayAuthContext): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gateway contract types — shared between Stack's gateway middleware and
|
|
3
|
+
* Lucern's server-core / gateway route handlers.
|
|
4
|
+
*
|
|
5
|
+
* These types describe the authenticated request context that flows from
|
|
6
|
+
* the gateway into Lucern route handlers. The gateway (Stack-side) creates
|
|
7
|
+
* the context; Lucern consumes it read-only.
|
|
8
|
+
*
|
|
9
|
+
* @module @lucern/contracts/src/gateway
|
|
10
|
+
*/
|
|
11
|
+
export function requireActorPrincipalId(authContext) {
|
|
12
|
+
const principalId = typeof authContext.principalId === "string"
|
|
13
|
+
? authContext.principalId.trim()
|
|
14
|
+
: "";
|
|
15
|
+
if (principalId.length > 0) {
|
|
16
|
+
return principalId;
|
|
17
|
+
}
|
|
18
|
+
throw new Error("Access denied: federated principal context required.");
|
|
19
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const PREFIXED_ID_PATTERN = /^([a-z][a-z0-9]*)_(.+)$/;
|
|
2
|
+
export function encodePrefixedId(prefix, value) {
|
|
3
|
+
const normalizedPrefix = prefix.trim();
|
|
4
|
+
const normalizedValue = value.trim();
|
|
5
|
+
if (!normalizedPrefix || !normalizedValue) {
|
|
6
|
+
throw new Error("Both prefix and value are required to encode a prefixed ID.");
|
|
7
|
+
}
|
|
8
|
+
return `${normalizedPrefix}_${normalizedValue}`;
|
|
9
|
+
}
|
|
10
|
+
export function decodePrefixedId(id) {
|
|
11
|
+
const normalized = id.trim();
|
|
12
|
+
const match = PREFIXED_ID_PATTERN.exec(normalized);
|
|
13
|
+
if (!match) {
|
|
14
|
+
throw new Error(`Invalid prefixed ID: ${id}`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
prefix: match[1],
|
|
18
|
+
value: match[2],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function hasPrefixedIdPrefix(id, prefix) {
|
|
22
|
+
const decoded = decodePrefixedId(id);
|
|
23
|
+
return decoded.prefix === prefix.trim();
|
|
24
|
+
}
|