@lucern/mcp 0.3.0-alpha.15 → 0.3.0-alpha.17

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 CHANGED
@@ -85,7 +85,8 @@ This package is the **external package MCP** surface (`packages/mcp`) intended f
85
85
 
86
86
  It is intentionally separate from the **internal Convex MCP** runtime under `convex/mcp/*` used by StackOS internals.
87
87
 
88
- See `docs/lucern-replatform/api/mcp-surface-separation.md` for boundary details.
88
+ See `docs/reference/mcp-event-packages.md` for package-boundary details and
89
+ `docs/reference/mcp.md` for the generated callable MCP inventory.
89
90
 
90
91
  ## Claude Code config
91
92
 
package/dist/cli.js CHANGED
@@ -130,13 +130,9 @@ function loadProfile(options) {
130
130
  const localEnv = options.readLocalEnv === false ? {} : readLocalEnvFiles(options.cwd);
131
131
  const mergedEnv = { ...localEnv, ...options.env };
132
132
  const envProfile = profileFromEnvironment(mergedEnv);
133
- const hasEnvCredentials = Boolean(
134
- envProfile.apiKey || envProfile.userToken || envProfile.packKey
135
- );
136
- const explicitProfileSelected = options.profileName !== void 0 || mergedEnv.LUCERN_PROFILE !== void 0;
137
133
  const selectedProfile = options.profileName ?? mergedEnv.LUCERN_PROFILE ?? profiles.activeProfile ?? credentials.LUCERN_PROFILE ?? "default";
138
- const selected = hasEnvCredentials && !explicitProfileSelected ? "env" : selectedProfile;
139
- const savedProfile = hasEnvCredentials && !explicitProfileSelected ? {} : profiles.profiles?.[selectedProfile] ?? {};
134
+ const selected = selectedProfile;
135
+ const savedProfile = profiles.profiles?.[selectedProfile] ?? {};
140
136
  const credentialsProfile = {
141
137
  apiKey: credentials.LUCERN_API_KEY,
142
138
  userToken: readFirst(credentials, ["LUCERN_SESSION_TOKEN", "LUCERN_USER_TOKEN"]),
@@ -1170,6 +1166,7 @@ defineTable({
1170
1166
  shape: z.object({
1171
1167
  "tenantId": idOf("tenants"),
1172
1168
  "workspaceId": idOf("workspaces").optional(),
1169
+ "environment": z.enum(["dev", "staging", "prod"]).optional(),
1173
1170
  "keyPrefix": z.enum(["luc", "stk"]),
1174
1171
  "keyHash": z.string(),
1175
1172
  "keyHint": z.string(),
@@ -1197,7 +1194,7 @@ defineTable({
1197
1194
  shape: z.object({
1198
1195
  "tenantId": idOf("tenants").optional(),
1199
1196
  "apiKeyId": idOf("apiKeys").optional(),
1200
- "action": z.enum(["key_created", "key_revoked", "key_expired", "key_used", "tenant_secret_created", "tenant_secret_rotated", "tenant_secret_revoked", "tenant_slot_binding_upserted", "tenant_slot_binding_revoked", "proxy_token_minted", "proxy_token_lease_issued", "proxy_token_lease_renewed", "proxy_token_lease_revoked", "proxy_request_recorded", "tenant_created", "tenant_updated", "tenant_suspended", "tenant_archived", "tenant_reactivated", "principal_created", "principal_updated", "principal_suspended", "principal_identity_alias_upserted", "principal_identity_alias_revoked", "membership_created", "membership_updated", "membership_revoked", "group_created", "group_updated", "group_deleted", "group_member_added", "group_member_removed", "workspace_created", "workspace_updated", "workspace_archived", "workspace_deployment_set", "workspace_deployment_removed", "deployment_host_registered", "deployment_host_revoked", "service_key_created", "service_key_rotated", "service_key_revoked", "service_key_used", "service_key_auth_failed", "session_created", "session_validated", "session_revoked", "session_cascade_revoked", "session_expired", "sandbox_created", "sandbox_secret_injected", "sandbox_execution_started", "sandbox_execution_completed", "sandbox_limit_violated", "policy_created", "policy_updated", "policy_enforced", "policy_archived", "permit_sync_enqueued", "permit_sync_succeeded", "permit_sync_failed", "permit_sync_skipped", "agent_registered", "agent_updated", "tool_registered", "tool_updated", "pack_entitled", "pack_installed", "pack_enabled", "pack_disabled", "pack_entitlement_revoked", "pack_upgraded", "pack_upgrade_committed", "pack_upgrade_rolled_back", "pack_group_assigned", "pack_group_unassigned", "methodology_pack_created", "methodology_pack_updated", "methodology_pack_assigned", "methodology_pack_removed", "pack_assigned_to_group", "pack_revoked_from_group", "pack_ontology_materialized", "pack_ontology_topic_bound", "cutover_flag_set", "cutover_flag_cleared"]),
1197
+ "action": z.enum(["key_created", "key_revoked", "key_expired", "key_used", "tenant_secret_created", "tenant_secret_rotated", "tenant_secret_revoked", "tenant_slot_binding_upserted", "tenant_slot_binding_revoked", "proxy_token_minted", "proxy_token_lease_issued", "proxy_token_lease_renewed", "proxy_token_lease_revoked", "proxy_request_recorded", "tenant_created", "tenant_updated", "tenant_suspended", "tenant_archived", "tenant_reactivated", "tenant_clerk_organization_linked", "principal_created", "principal_updated", "principal_suspended", "principal_identity_alias_upserted", "principal_identity_alias_revoked", "membership_created", "membership_updated", "membership_revoked", "group_created", "group_updated", "group_deleted", "group_member_added", "group_member_removed", "workspace_created", "workspace_updated", "workspace_archived", "workspace_deployment_set", "workspace_deployment_removed", "deployment_host_registered", "deployment_host_revoked", "service_key_created", "service_key_rotated", "service_key_revoked", "service_key_used", "service_key_auth_failed", "session_created", "session_validated", "session_revoked", "session_cascade_revoked", "session_expired", "sandbox_created", "sandbox_secret_injected", "sandbox_execution_started", "sandbox_execution_completed", "sandbox_limit_violated", "policy_created", "policy_updated", "policy_enforced", "policy_archived", "permit_sync_enqueued", "permit_sync_succeeded", "permit_sync_failed", "permit_sync_skipped", "agent_registered", "agent_updated", "tool_registered", "tool_updated", "pack_entitled", "pack_installed", "pack_enabled", "pack_disabled", "pack_entitlement_revoked", "pack_upgraded", "pack_upgrade_committed", "pack_upgrade_rolled_back", "pack_group_assigned", "pack_group_unassigned", "methodology_pack_created", "methodology_pack_updated", "methodology_pack_assigned", "methodology_pack_removed", "pack_assigned_to_group", "pack_revoked_from_group", "pack_ontology_materialized", "pack_ontology_topic_bound", "cutover_flag_set", "cutover_flag_cleared"]),
1201
1198
  "actorClerkId": z.string(),
1202
1199
  "details": z.any().optional(),
1203
1200
  "createdAt": z.number()
@@ -6408,6 +6405,21 @@ var INFISICAL_RUNTIME_PATHS = [
6408
6405
  }
6409
6406
  ]
6410
6407
  },
6408
+ {
6409
+ id: "platform-operator-credentials",
6410
+ secretPath: "/platform/runtime",
6411
+ description: "Lucern-owned operator credential material for local CLI, MCP, and SDK sessions.",
6412
+ variables: [
6413
+ {
6414
+ name: "LUCERN_API_KEY",
6415
+ required: false,
6416
+ secret: true,
6417
+ public: false,
6418
+ aliases: ["LUCERN_KEY"],
6419
+ description: "Lucern-owned operator API key for gateway calls from trusted local tooling."
6420
+ }
6421
+ ]
6422
+ },
6411
6423
  {
6412
6424
  id: "tenant-shared-install",
6413
6425
  secretPath: TENANT_CLIENT_INSTALL_TOKEN_INFISICAL_PATH,
@@ -6443,7 +6455,7 @@ var INFISICAL_RUNTIME_SURFACES = [
6443
6455
  id: "lucern-sdk",
6444
6456
  packageName: "@lucern/sdk",
6445
6457
  delivery: "runtime_fetch",
6446
- sourcePathIds: ["platform-runtime"],
6458
+ sourcePathIds: ["platform-runtime", "platform-operator-credentials"],
6447
6459
  consumer: "server-side SDK operator contexts with a scoped Infisical identity",
6448
6460
  description: "SDK exposes the runtime Infisical resolver used by clients that have machine identity credentials."
6449
6461
  },
@@ -6452,7 +6464,7 @@ var INFISICAL_RUNTIME_SURFACES = [
6452
6464
  packageName: "@lucern/cli",
6453
6465
  delivery: "runtime_fetch",
6454
6466
  fallback: "device_auth",
6455
- sourcePathIds: ["platform-runtime"],
6467
+ sourcePathIds: ["platform-runtime", "platform-operator-credentials"],
6456
6468
  consumer: "developer/operator CLI processes",
6457
6469
  description: "CLI hydrates runtime defaults from Infisical when configured, then authenticates users through Lucern device login."
6458
6470
  },
@@ -6461,7 +6473,7 @@ var INFISICAL_RUNTIME_SURFACES = [
6461
6473
  packageName: "@lucern/mcp",
6462
6474
  delivery: "runtime_fetch",
6463
6475
  fallback: "device_auth",
6464
- sourcePathIds: ["platform-runtime"],
6476
+ sourcePathIds: ["platform-runtime", "platform-operator-credentials"],
6465
6477
  consumer: "MCP server/client processes",
6466
6478
  description: "MCP hydrates runtime defaults through the SDK resolver and remains a Lucern client, not a platform secret owner."
6467
6479
  },
@@ -8942,9 +8954,33 @@ var GENERATED_INFISICAL_RUNTIME_ENV = {
8942
8954
  "consumer": "server-side SDK operator contexts with a scoped Infisical identity",
8943
8955
  "description": "SDK exposes the runtime Infisical resolver used by clients that have machine identity credentials.",
8944
8956
  "sourcePathIds": [
8945
- "platform-runtime"
8957
+ "platform-runtime",
8958
+ "platform-operator-credentials"
8946
8959
  ],
8947
8960
  "variables": [
8961
+ {
8962
+ "canonicalName": "LUCERN_API_KEY",
8963
+ "envNames": [
8964
+ "LUCERN_API_KEY",
8965
+ "LUCERN_KEY"
8966
+ ],
8967
+ "aliases": [
8968
+ "LUCERN_KEY"
8969
+ ],
8970
+ "writeNames": [
8971
+ "LUCERN_API_KEY"
8972
+ ],
8973
+ "required": false,
8974
+ "secret": true,
8975
+ "public": false,
8976
+ "sourcePath": "/platform/runtime",
8977
+ "environmentPolicy": "environment_specific",
8978
+ "consumers": [
8979
+ "lucern-sdk"
8980
+ ],
8981
+ "destinations": [],
8982
+ "description": "Lucern-owned operator API key for gateway calls from trusted local tooling."
8983
+ },
8948
8984
  {
8949
8985
  "canonicalName": "LUCERN_API_URL",
8950
8986
  "envNames": [
@@ -9045,9 +9081,57 @@ var GENERATED_INFISICAL_RUNTIME_ENV = {
9045
9081
  "consumer": "developer/operator CLI processes",
9046
9082
  "description": "CLI hydrates runtime defaults from Infisical when configured, then authenticates users through Lucern device login.",
9047
9083
  "sourcePathIds": [
9048
- "platform-runtime"
9084
+ "platform-runtime",
9085
+ "platform-operator-credentials"
9049
9086
  ],
9050
9087
  "variables": [
9088
+ {
9089
+ "canonicalName": "LUCERN_API_KEY",
9090
+ "envNames": [
9091
+ "LUCERN_API_KEY",
9092
+ "LUCERN_KEY"
9093
+ ],
9094
+ "aliases": [
9095
+ "LUCERN_KEY"
9096
+ ],
9097
+ "writeNames": [
9098
+ "LUCERN_API_KEY"
9099
+ ],
9100
+ "required": false,
9101
+ "secret": true,
9102
+ "public": false,
9103
+ "sourcePath": "/platform/runtime",
9104
+ "environmentPolicy": "environment_specific",
9105
+ "consumers": [
9106
+ "lucern-cli",
9107
+ "lucern-mcp",
9108
+ "lucern-repo-ci"
9109
+ ],
9110
+ "destinations": [
9111
+ {
9112
+ "kind": "runtime_fetch",
9113
+ "target": "lucern-cli-mcp-sdk",
9114
+ "writeNames": [
9115
+ "LUCERN_API_KEY"
9116
+ ]
9117
+ },
9118
+ {
9119
+ "kind": "operator_local",
9120
+ "target": "lucern-repo",
9121
+ "writeNames": [
9122
+ "LUCERN_API_KEY"
9123
+ ]
9124
+ },
9125
+ {
9126
+ "kind": "github_actions",
9127
+ "target": "LucernAI/lucern",
9128
+ "writeNames": [
9129
+ "LUCERN_API_KEY"
9130
+ ]
9131
+ }
9132
+ ],
9133
+ "description": "Lucern-owned operator API key for gateway calls from trusted local tooling. Lucern-owned operator API key for trusted CLI/MCP/CI calls. Source it from /platform/runtime; do not persist it into local user credential files."
9134
+ },
9051
9135
  {
9052
9136
  "canonicalName": "LUCERN_API_URL",
9053
9137
  "envNames": [
@@ -9386,7 +9470,8 @@ var GENERATED_INFISICAL_RUNTIME_ENV = {
9386
9470
  "consumer": "MCP server/client processes",
9387
9471
  "description": "MCP hydrates runtime defaults through the SDK resolver and remains a Lucern client, not a platform secret owner.",
9388
9472
  "sourcePathIds": [
9389
- "platform-runtime"
9473
+ "platform-runtime",
9474
+ "platform-operator-credentials"
9390
9475
  ],
9391
9476
  "variables": [
9392
9477
  {
@@ -9474,6 +9559,53 @@ var GENERATED_INFISICAL_RUNTIME_ENV = {
9474
9559
  ],
9475
9560
  "description": "Lucern-owned Clerk backend secret. Never route to tenant-owned apps unless that tenant is Lucern itself."
9476
9561
  },
9562
+ {
9563
+ "canonicalName": "LUCERN_API_KEY",
9564
+ "envNames": [
9565
+ "LUCERN_API_KEY",
9566
+ "LUCERN_KEY"
9567
+ ],
9568
+ "aliases": [
9569
+ "LUCERN_KEY"
9570
+ ],
9571
+ "writeNames": [
9572
+ "LUCERN_API_KEY"
9573
+ ],
9574
+ "required": false,
9575
+ "secret": true,
9576
+ "public": false,
9577
+ "sourcePath": "/platform/runtime",
9578
+ "environmentPolicy": "environment_specific",
9579
+ "consumers": [
9580
+ "lucern-cli",
9581
+ "lucern-mcp",
9582
+ "lucern-repo-ci"
9583
+ ],
9584
+ "destinations": [
9585
+ {
9586
+ "kind": "runtime_fetch",
9587
+ "target": "lucern-cli-mcp-sdk",
9588
+ "writeNames": [
9589
+ "LUCERN_API_KEY"
9590
+ ]
9591
+ },
9592
+ {
9593
+ "kind": "operator_local",
9594
+ "target": "lucern-repo",
9595
+ "writeNames": [
9596
+ "LUCERN_API_KEY"
9597
+ ]
9598
+ },
9599
+ {
9600
+ "kind": "github_actions",
9601
+ "target": "LucernAI/lucern",
9602
+ "writeNames": [
9603
+ "LUCERN_API_KEY"
9604
+ ]
9605
+ }
9606
+ ],
9607
+ "description": "Lucern-owned operator API key for gateway calls from trusted local tooling. Lucern-owned operator API key for trusted CLI/MCP/CI calls. Source it from /platform/runtime; do not persist it into local user credential files."
9608
+ },
9477
9609
  {
9478
9610
  "canonicalName": "LUCERN_API_URL",
9479
9611
  "envNames": [
@@ -10214,7 +10346,7 @@ function compactRecord2(input) {
10214
10346
  Object.entries(input).filter(([, value]) => value !== void 0)
10215
10347
  );
10216
10348
  }
10217
- var listBeliefsProjection = defineProjection({
10349
+ defineProjection({
10218
10350
  contractName: "list_beliefs",
10219
10351
  inputSchema: listBeliefsInputSchema,
10220
10352
  project: (input) => compactRecord2({
@@ -12723,7 +12855,7 @@ var IDENTITY_WHOAMI = {
12723
12855
  response: {
12724
12856
  description: "Canonical identity summary for the current session",
12725
12857
  fields: {
12726
- principalId: "string \u2014 canonical federated principal identifier",
12858
+ principalId: "string \u2014 canonical principal identifier; for humans this is the Clerk user_... ID",
12727
12859
  principalType: "string \u2014 human, service, agent, group, or external_viewer",
12728
12860
  tenantId: "string | undefined \u2014 resolved tenant scope",
12729
12861
  workspaceId: "string | undefined \u2014 resolved workspace scope",
@@ -12737,7 +12869,7 @@ var IDENTITY_WHOAMI = {
12737
12869
  };
12738
12870
  var RESOLVE_INTERACTIVE_PRINCIPAL = {
12739
12871
  name: "resolve_interactive_principal",
12740
- description: "Read the Permit-backed Lucern principal context for an authenticated Clerk user. Like `git config --get user.email` plus the repository ACL \u2014 resolves the identity alias into the canonical authorization subject.",
12872
+ description: "Read the Permit-backed Lucern principal context for an authenticated Clerk user. Like `git config --get user.email` plus the repository ACL \u2014 resolves the Clerk subject into tenant/workspace authorization context.",
12741
12873
  parameters: {
12742
12874
  clerkId: {
12743
12875
  type: "string",
@@ -12760,7 +12892,7 @@ var RESOLVE_INTERACTIVE_PRINCIPAL = {
12760
12892
  response: {
12761
12893
  description: "Permit-backed Lucern principal context for tenant SDK bootstrap",
12762
12894
  fields: {
12763
- principalId: "string \u2014 canonical Lucern principal identifier",
12895
+ principalId: "string \u2014 canonical Clerk user_... ID for human sessions",
12764
12896
  principalType: "string \u2014 human, service, agent, group, or external_viewer",
12765
12897
  clerkId: "string \u2014 authenticated Clerk subject alias",
12766
12898
  tenantId: "string \u2014 resolved tenant scope",
@@ -13588,7 +13720,7 @@ var MANAGE_WRITE_POLICY = {
13588
13720
  },
13589
13721
  role: {
13590
13722
  type: "string",
13591
- description: "Role to set policy for (required for 'set'). E.g. 'agent:internal', 'user:analyst'."
13723
+ description: "Role to set policy for (required for 'set'). E.g. 'agent:internal' or a Permit role key such as 'workspace_admin'."
13592
13724
  },
13593
13725
  permission: {
13594
13726
  type: "string",
@@ -15530,11 +15662,8 @@ var identityContracts = [
15530
15662
  sdkNamespace: "identity",
15531
15663
  sdkMethod: "whoami",
15532
15664
  summary: "Describe the current gateway principal.",
15533
- convex: {
15534
- module: "identity",
15535
- functionName: "whoami",
15536
- kind: "query",
15537
- inputProjection: withPrincipal
15665
+ gateway: {
15666
+ handler: "identity.whoami"
15538
15667
  }
15539
15668
  }),
15540
15669
  surfaceContract({
@@ -15554,7 +15683,7 @@ var identityContracts = [
15554
15683
  providerProjectId: z.string().min(1).optional()
15555
15684
  }),
15556
15685
  convex: {
15557
- module: "identity",
15686
+ module: "platform",
15558
15687
  functionName: "resolveInteractivePrincipal",
15559
15688
  kind: "query"
15560
15689
  }
@@ -15638,15 +15767,6 @@ var beliefLookupInput = (input) => compactRecord4({
15638
15767
  var beliefNodeInput = (input) => compactRecord4({
15639
15768
  nodeId: input.nodeId ?? input.id ?? input.beliefId
15640
15769
  });
15641
- var beliefTopicInput = (input) => {
15642
- const parsed = listBeliefsProjection.inputSchema.safeParse(input);
15643
- if (!parsed.success) {
15644
- throw new Error(
15645
- `list_beliefs projection input rejected: ${parsed.error.message}`
15646
- );
15647
- }
15648
- return compactRecord4(listBeliefsProjection.project(parsed.data));
15649
- };
15650
15770
  var createBeliefInput = (input, context) => {
15651
15771
  return withUserId(
15652
15772
  compactRecord4({
@@ -15735,11 +15855,8 @@ var beliefsContracts = [
15735
15855
  sdkNamespace: "beliefs",
15736
15856
  sdkMethod: "listBeliefs",
15737
15857
  summary: "List beliefs for a topic.",
15738
- convex: {
15739
- module: "beliefs",
15740
- functionName: "getByTopic",
15741
- kind: "query",
15742
- inputProjection: beliefTopicInput
15858
+ gateway: {
15859
+ handler: "beliefs.list"
15743
15860
  },
15744
15861
  args: listBeliefsInputSchema
15745
15862
  }),
@@ -15924,12 +16041,6 @@ var evidenceIdInput = (input) => compactRecord4({
15924
16041
  insightId: input.insightId,
15925
16042
  nodeId: input.nodeId ?? input.id ?? input.evidenceId
15926
16043
  });
15927
- var evidenceTopicInput = (input) => compactRecord4({
15928
- topicId: input.topicId,
15929
- status: input.status,
15930
- userId: input.userId,
15931
- limit: input.limit
15932
- });
15933
16044
  var createEvidenceInput = (input, context) => {
15934
16045
  const parsed = createEvidenceProjection.inputSchema.safeParse(input);
15935
16046
  if (!parsed.success) {
@@ -16060,11 +16171,8 @@ var evidenceContracts = [
16060
16171
  sdkNamespace: "evidence",
16061
16172
  sdkMethod: "listEvidence",
16062
16173
  summary: "List evidence for a topic.",
16063
- convex: {
16064
- module: "evidence",
16065
- functionName: "getByTopic",
16066
- kind: "query",
16067
- inputProjection: evidenceTopicInput
16174
+ gateway: {
16175
+ handler: "evidence.list"
16068
16176
  }
16069
16177
  }),
16070
16178
  surfaceContract({
@@ -16299,11 +16407,8 @@ var questionsContracts = [
16299
16407
  sdkNamespace: "questions",
16300
16408
  sdkMethod: "listQuestions",
16301
16409
  summary: "List questions for a topic.",
16302
- convex: {
16303
- module: "questions",
16304
- functionName: "getByTopic",
16305
- kind: "query",
16306
- inputProjection: questionTopicInput
16410
+ gateway: {
16411
+ handler: "questions.list"
16307
16412
  }
16308
16413
  }),
16309
16414
  surfaceContract({
@@ -17408,6 +17513,19 @@ var worktreeEvidenceSignalInputSchema = z.object({
17408
17513
  progress: z.string().optional().describe("Collection progress note for the signal."),
17409
17514
  notes: z.string().optional().describe("Additional evidence collection notes.")
17410
17515
  }).passthrough().describe("Evidence signal embedded in the worktree plan.");
17516
+ var worktreeDocCompanionTargetSchema = z.object({
17517
+ docPath: z.string().describe(
17518
+ "Repo-relative path to a documentation file the worktree promises to update."
17519
+ ),
17520
+ sectionAnchor: z.string().optional().describe(
17521
+ "Markdown heading anchor (e.g. '## Function-surface manifest') that scopes the promised update."
17522
+ ),
17523
+ reason: z.string().describe(
17524
+ "Why this doc section must be updated for the worktree to be complete."
17525
+ )
17526
+ }).passthrough().describe(
17527
+ "Intent-driven docs companion target. pr-gate-reviewer verifies that the PR actually touches each declared (docPath, sectionAnchor). Distinct from the touch-driven docs-loop. See docs/development/docs-sync-discipline.md Lock 3."
17528
+ );
17411
17529
  var worktreeDecisionGateInputSchema = z.object({
17412
17530
  goCriteria: z.array(z.string()).describe("Criteria that must hold for the worktree to proceed."),
17413
17531
  noGoSignals: z.array(z.string()).describe("Signals that stop or redirect the worktree."),
@@ -17440,6 +17558,9 @@ var addWorktreeArgs = z.object({
17440
17558
  keyQuestions: z.array(worktreeKeyQuestionInputSchema).optional().describe("Inline key questions captured as part of the worktree plan."),
17441
17559
  evidenceSignals: z.array(worktreeEvidenceSignalInputSchema).optional().describe("Evidence signals the worktree needs to collect or validate."),
17442
17560
  decisionGate: worktreeDecisionGateInputSchema.optional(),
17561
+ docCompanionTargets: z.array(worktreeDocCompanionTargetSchema).optional().describe(
17562
+ "Doc sections the worktree promises to update at PR time. Enforced by pr-gate-reviewer (Lock 3)."
17563
+ ),
17443
17564
  goCriteria: z.array(z.string()).optional().describe("Shorthand go criteria used to build decisionGate."),
17444
17565
  noGoSignals: z.array(z.string()).optional().describe("Shorthand no-go signals used to build decisionGate."),
17445
17566
  proofArtifacts: z.array(z.unknown()).optional().describe("Expected proof artifacts required to close the worktree."),
@@ -21140,13 +21261,31 @@ function mergeHeaderRecord(base, addition) {
21140
21261
  }
21141
21262
  return Object.fromEntries(headers.entries());
21142
21263
  }
21264
+ function cleanHeaderValue(value) {
21265
+ const normalized = value?.trim();
21266
+ return normalized ? normalized : void 0;
21267
+ }
21143
21268
  function createGatewayRequestClient(config = {}) {
21144
21269
  const fetchImpl = config.fetchImpl ?? fetch;
21145
21270
  const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
21146
21271
  const maxRetries = config.maxRetries ?? 2;
21147
21272
  const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
21148
21273
  async function resolveAuthHeaders2() {
21149
- const base = config.getAuthHeaders ? await config.getAuthHeaders() : {};
21274
+ const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
21275
+ const headers = new Headers(provided);
21276
+ const setIfAbsent = (name, value) => {
21277
+ const normalized = cleanHeaderValue(value);
21278
+ if (normalized && !headers.has(name)) {
21279
+ headers.set(name, normalized);
21280
+ }
21281
+ };
21282
+ setIfAbsent("x-lucern-key", config.apiKey);
21283
+ setIfAbsent("x-lucern-session-token", config.userToken);
21284
+ setIfAbsent("x-lucern-environment", config.environment);
21285
+ setIfAbsent("x-lucern-clerk-id", config.clerkId);
21286
+ setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
21287
+ setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
21288
+ const base = Object.fromEntries(headers.entries());
21150
21289
  const authContextInput = await resolveConfiguredAuthContext(
21151
21290
  config.authContext
21152
21291
  );
@@ -22440,7 +22579,7 @@ function normalizeCanonicalPrincipalIdentity(input, options = {}) {
22440
22579
  })) {
22441
22580
  throw new LucernAccessControlError(
22442
22581
  "clerk_alias_unrecognized",
22443
- "Observed Clerk user id is not attached to the canonical Lucern principal."
22582
+ "Observed Clerk user id does not match the canonical human principal id."
22444
22583
  );
22445
22584
  }
22446
22585
  return {
@@ -28042,7 +28181,7 @@ function createToolRegistryClient(config = {}) {
28042
28181
  }
28043
28182
 
28044
28183
  // ../sdk/src/version.ts
28045
- var LUCERN_SDK_VERSION = "0.3.0-alpha.15";
28184
+ var LUCERN_SDK_VERSION = "0.3.0-alpha.17";
28046
28185
 
28047
28186
  // ../sdk/src/workflowClient.ts
28048
28187
  function normalizeLensQuery(value) {
@@ -28450,6 +28589,12 @@ function toGatewayConfig(config) {
28450
28589
  return {
28451
28590
  baseUrl: config.baseUrl,
28452
28591
  fetchImpl: config.fetchImpl,
28592
+ apiKey: config.apiKey,
28593
+ userToken: config.userToken,
28594
+ environment: config.environment,
28595
+ clerkId: config.clerkId,
28596
+ userId: config.userId,
28597
+ deploymentHost: config.deploymentHost,
28453
28598
  maxRetries: config.maxRetries,
28454
28599
  timeoutMs: config.timeoutMs,
28455
28600
  timeoutMsByMethod: config.timeoutMsByMethod,
@@ -28458,19 +28603,7 @@ function toGatewayConfig(config) {
28458
28603
  onResponse: config.onResponse,
28459
28604
  authContext: config.authContext,
28460
28605
  requireCanonicalAuthContext: config.requireCanonicalAuthContext,
28461
- getAuthHeaders: async () => {
28462
- const base = config.getAuthHeaders ? await config.getAuthHeaders() : {};
28463
- if (config.apiKey && !base["x-lucern-key"] && !base.Authorization) {
28464
- base["x-lucern-key"] = config.apiKey;
28465
- }
28466
- if (config.userToken && !base["x-lucern-session-token"]) {
28467
- base["x-lucern-session-token"] = config.userToken;
28468
- }
28469
- if (config.environment && !base["x-lucern-environment"]) {
28470
- base["x-lucern-environment"] = config.environment;
28471
- }
28472
- return base;
28473
- }
28606
+ getAuthHeaders: config.getAuthHeaders
28474
28607
  };
28475
28608
  }
28476
28609
  function exposeGatewayData(response) {
@@ -31742,7 +31875,7 @@ var SESSION_LIFECYCLE_STATUSES = [
31742
31875
  "revoked"
31743
31876
  ];
31744
31877
  function inferSessionPrincipalType(principalId) {
31745
- if (principalId.startsWith("user:")) {
31878
+ if (/^user_[A-Za-z0-9]+$/.test(principalId)) {
31746
31879
  return "human";
31747
31880
  }
31748
31881
  if (principalId.startsWith("agent:")) {
@@ -34969,7 +35102,7 @@ function createLucernStandaloneMcpServer(options) {
34969
35102
  });
34970
35103
  const server = new McpServer({
34971
35104
  name: "lucern-mcp",
34972
- version: "0.3.0-alpha.15"
35105
+ version: "0.3.0-alpha.17"
34973
35106
  });
34974
35107
  registerTools(server, runtime);
34975
35108
  const resources = registerResources(server, runtime, observationStore);