@noodleseed/one 0.174.0 → 0.175.1

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.
Files changed (164) hide show
  1. package/dist/commands/solutions-activity.js +1 -1
  2. package/dist/commands/solutions-activity.js.map +1 -1
  3. package/dist/commands/solutions-drafts.d.ts.map +1 -1
  4. package/dist/commands/solutions-drafts.js +36 -9
  5. package/dist/commands/solutions-drafts.js.map +1 -1
  6. package/dist/commands/solutions-native-lifecycle.d.ts +5 -0
  7. package/dist/commands/solutions-native-lifecycle.d.ts.map +1 -0
  8. package/dist/commands/solutions-native-lifecycle.js +77 -0
  9. package/dist/commands/solutions-native-lifecycle.js.map +1 -0
  10. package/dist/commands/solutions-ops.d.ts.map +1 -1
  11. package/dist/commands/solutions-ops.js +3 -0
  12. package/dist/commands/solutions-ops.js.map +1 -1
  13. package/dist/commands/solutions-workspace.d.ts.map +1 -1
  14. package/dist/commands/solutions-workspace.js +36 -11
  15. package/dist/commands/solutions-workspace.js.map +1 -1
  16. package/dist/commands/whatsapp-output.d.ts.map +1 -1
  17. package/dist/commands/whatsapp-output.js +20 -4
  18. package/dist/commands/whatsapp-output.js.map +1 -1
  19. package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.d.ts +16 -9
  20. package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.js +5 -2
  21. package/node_modules/@noodle-borg/agent-kit/dist/curated/error-fixes.js +9 -0
  22. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +5 -5
  23. package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +9 -0
  24. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
  25. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +13 -1
  26. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  27. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.d.ts +5 -3
  28. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.js +5 -4
  29. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-inbox.js +6 -2
  30. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-store.d.ts +1 -1
  31. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.d.ts +12 -0
  32. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.d.ts +7 -2
  33. package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.js +14 -4
  34. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-capture.js +104 -0
  35. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-judgment.js +93 -0
  36. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-ledger.d.ts +105 -0
  37. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-ledger.js +183 -0
  38. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-model-call.js +38 -0
  39. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-parsers.d.ts +22 -0
  40. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-parsers.js +109 -0
  41. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-review.d.ts +21 -0
  42. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-review.js +44 -0
  43. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-spec.d.ts +18 -0
  44. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-spec.js +86 -0
  45. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-store.d.ts +11 -0
  46. package/node_modules/@noodle-borg/assistant-gateway/dist/collection-store.js +18 -0
  47. package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.d.ts +20 -1
  48. package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.js +38 -2
  49. package/node_modules/@noodle-borg/assistant-gateway/dist/model-runtime.js +3 -0
  50. package/node_modules/@noodle-borg/assistant-gateway/dist/portable.d.ts +5 -0
  51. package/node_modules/@noodle-borg/assistant-gateway/dist/portable.js +5 -0
  52. package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
  53. package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -0
  54. package/node_modules/@noodle-borg/authoring/dist/interaction.d.ts +49 -0
  55. package/node_modules/@noodle-borg/authoring/dist/interaction.js +25 -0
  56. package/node_modules/@noodle-borg/authoring/dist/server.d.ts +3 -0
  57. package/node_modules/@noodle-borg/authoring/dist/server.js +4 -0
  58. package/node_modules/@noodle-borg/authoring/package.json +6 -1
  59. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-channels.js +1 -1
  60. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-drafts.js +7 -0
  61. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-native-lifecycle.js +43 -0
  62. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-records.js +154 -0
  63. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-workspace.js +8 -1
  64. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solutions.js +2 -149
  65. package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +2 -1
  66. package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +33 -0
  67. package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +2 -1
  68. package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +2 -1
  69. package/node_modules/@noodle-borg/compiler/dist/compile.js +5 -0
  70. package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +1 -1
  71. package/node_modules/@noodle-borg/compiler/dist/index.d.ts +2 -2
  72. package/node_modules/@noodle-borg/compiler/dist/index.js +1 -1
  73. package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-schema.d.ts +41 -0
  74. package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-schema.js +62 -0
  75. package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-validation.js +220 -0
  76. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +60 -4
  77. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +7 -1
  78. package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.d.ts +9 -1
  79. package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.js +58 -10
  80. package/node_modules/@noodle-borg/control-plane/dist/in-memory-atomic-state.d.ts +8 -0
  81. package/node_modules/@noodle-borg/control-plane/dist/in-memory-atomic-state.js +136 -0
  82. package/node_modules/@noodle-borg/control-plane/dist/in-memory-control-plane-store.d.ts +7 -0
  83. package/node_modules/@noodle-borg/control-plane/dist/in-memory-control-plane-store.js +16 -24
  84. package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.d.ts +4 -2
  85. package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.js +8 -6
  86. package/node_modules/@noodle-borg/control-plane/dist/mcp-subdomain-claims.d.ts +2 -1
  87. package/node_modules/@noodle-borg/control-plane/dist/mcp-subdomain-claims.js +13 -8
  88. package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.d.ts +13 -4
  89. package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.js +23 -7
  90. package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +2 -1
  91. package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
  92. package/node_modules/@noodle-borg/module/dist/platform-human-identity.d.ts +5 -2
  93. package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +16 -4
  94. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +3 -6
  95. package/node_modules/@noodle-borg/runtime/dist/index.d.ts +1 -1
  96. package/node_modules/@noodle-borg/service/dist/application-activity.js +85 -63
  97. package/node_modules/@noodle-borg/service/dist/application-drafts/contracts.js +9 -0
  98. package/node_modules/@noodle-borg/service/dist/application-drafts/paths.js +2 -2
  99. package/node_modules/@noodle-borg/service/dist/application-runtime-target.js +1 -1
  100. package/node_modules/@noodle-borg/service/dist/business-information/contracts.d.ts +18 -4
  101. package/node_modules/@noodle-borg/service/dist/business-information/in-memory-business-pages.js +3 -5
  102. package/node_modules/@noodle-borg/service/dist/business-information/in-memory-installation-lifecycle.js +8 -6
  103. package/node_modules/@noodle-borg/service/dist/business-information/in-memory-native-lifecycle.js +80 -0
  104. package/node_modules/@noodle-borg/service/dist/business-information/in-memory-store.js +27 -31
  105. package/node_modules/@noodle-borg/service/dist/business-information/memory-native-retention.js +29 -0
  106. package/node_modules/@noodle-borg/service/dist/business-information/model.js +9 -2
  107. package/node_modules/@noodle-borg/service/dist/business-information/native-query.js +3 -1
  108. package/node_modules/@noodle-borg/service/dist/business-information/native-record-lifecycle.d.ts +27 -0
  109. package/node_modules/@noodle-borg/service/dist/business-information/native-record-lifecycle.js +63 -0
  110. package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.d.ts +3 -1
  111. package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.js +9 -4
  112. package/node_modules/@noodle-borg/service/dist/business-information/staff-authority.d.ts +16 -0
  113. package/node_modules/@noodle-borg/service/dist/business-information/staff-authority.js +60 -0
  114. package/node_modules/@noodle-borg/service/dist/business-information/workspace-permissions.js +18 -0
  115. package/node_modules/@noodle-borg/service/dist/business-information-runtime.js +1 -0
  116. package/node_modules/@noodle-borg/service/dist/business-onboarding.js +16 -3
  117. package/node_modules/@noodle-borg/service/dist/business-workspaces/contracts.d.ts +110 -0
  118. package/node_modules/@noodle-borg/service/dist/business-workspaces/permissions.d.ts +7 -0
  119. package/node_modules/@noodle-borg/service/dist/business-workspaces/store.d.ts +102 -0
  120. package/node_modules/@noodle-borg/service/dist/channels/360dialog.js +70 -8
  121. package/node_modules/@noodle-borg/service/dist/channels/capability-report.js +73 -0
  122. package/node_modules/@noodle-borg/service/dist/channels/collection-turn.js +232 -0
  123. package/node_modules/@noodle-borg/service/dist/channels/composition.js +1 -0
  124. package/node_modules/@noodle-borg/service/dist/channels/messaging-eligibility.js +45 -0
  125. package/node_modules/@noodle-borg/service/dist/channels/reply-buttons.js +23 -0
  126. package/node_modules/@noodle-borg/service/dist/channels/runtime.js +127 -33
  127. package/node_modules/@noodle-borg/service/dist/native-record-connector.js +19 -4
  128. package/node_modules/@noodle-borg/service/dist/routes/application-drafts.js +44 -2
  129. package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +4 -0
  130. package/node_modules/@noodle-borg/service/dist/routes/business-authoring-dispatch.js +1 -1
  131. package/node_modules/@noodle-borg/service/dist/routes/business-information-access.js +39 -0
  132. package/node_modules/@noodle-borg/service/dist/routes/business-information-activity.js +1 -1
  133. package/node_modules/@noodle-borg/service/dist/routes/business-information-channels.js +2 -2
  134. package/node_modules/@noodle-borg/service/dist/routes/business-information-connections.js +10 -4
  135. package/node_modules/@noodle-borg/service/dist/routes/business-information-dispatch.js +11 -0
  136. package/node_modules/@noodle-borg/service/dist/routes/business-information-installation.js +3 -1
  137. package/node_modules/@noodle-borg/service/dist/routes/business-information-notice.js +6 -2
  138. package/node_modules/@noodle-borg/service/dist/routes/business-information-pages.js +1 -1
  139. package/node_modules/@noodle-borg/service/dist/routes/business-information-paths.js +1 -1
  140. package/node_modules/@noodle-borg/service/dist/routes/business-information-record-create.js +7 -2
  141. package/node_modules/@noodle-borg/service/dist/routes/business-information-record-reads.js +2 -2
  142. package/node_modules/@noodle-borg/service/dist/routes/business-information-records.js +332 -0
  143. package/node_modules/@noodle-borg/service/dist/routes/business-information-settings.js +6 -3
  144. package/node_modules/@noodle-borg/service/dist/routes/business-information-staff.js +9 -5
  145. package/node_modules/@noodle-borg/service/dist/routes/business-information.js +12 -356
  146. package/node_modules/@noodle-borg/service/dist/routes/business-native-lifecycle.js +46 -0
  147. package/node_modules/@noodle-borg/service/dist/routes/business-workspaces.js +14 -1
  148. package/node_modules/@noodle-borg/service/dist/service.js +1 -0
  149. package/node_modules/@noodle-borg/service/dist/web-capabilities.js +3 -1
  150. package/node_modules/@noodle-borg/service/package.json +2 -1
  151. package/node_modules/@noodle-borg/wire-contracts/dist/application-draft-validation.d.ts +59 -0
  152. package/node_modules/@noodle-borg/wire-contracts/dist/application-draft-validation.js +38 -0
  153. package/node_modules/@noodle-borg/wire-contracts/dist/business-information.d.ts +144 -50
  154. package/node_modules/@noodle-borg/wire-contracts/dist/business-information.js +44 -4
  155. package/node_modules/@noodle-borg/wire-contracts/dist/business-workspaces.d.ts +70 -0
  156. package/node_modules/@noodle-borg/wire-contracts/dist/business-workspaces.js +31 -1
  157. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +2 -0
  158. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +2 -0
  159. package/node_modules/@noodle-borg/wire-contracts/dist/native-record-lifecycle.d.ts +81 -0
  160. package/node_modules/@noodle-borg/wire-contracts/dist/native-record-lifecycle.js +39 -0
  161. package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.d.ts +26 -0
  162. package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.js +24 -1
  163. package/node_modules/@noodleseed/assistant/package.json +1 -1
  164. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import { RECORD_CONNECTOR_ID } from '../native-record-operations.js';
1
2
  import { collectPaths } from './expression.js';
2
3
  /** A tool touches identity when it reads `${user}` or requires verified claims (ADR 0185). */
3
4
  export function anonymousBehavior(tool) {
@@ -40,16 +41,11 @@ export function validateWebsiteProjection(assistant, surfaces) {
40
41
  if (tool === undefined)
41
42
  return;
42
43
  const path = `tools.${tool.name}`;
43
- if (surface.kind === 'messaging' &&
44
- (tool.annotations?.readOnlyHint !== true ||
45
- tool._meta?.ui !== undefined ||
46
- tool.fulfilment.kind === 'operation' ||
47
- tool.fulfilment.steps.some((step) => step.kind === 'operation'))) {
48
- errors.push({
49
- code: 'assistant_messaging_unsupported',
50
- path,
51
- message: `"${tool.name}" requires a write, connector, or UI renderer not enabled for this messaging slice`,
52
- });
44
+ if (surface.kind === 'messaging') {
45
+ const selected = new Set(surface.capabilities?.flatMap((entry) => (entry.kind === 'tool' ? [entry.name] : [])));
46
+ const requirement = messagingRequirement(tool, selected, surfaces);
47
+ if (requirement !== undefined)
48
+ errors.push({ ...requirement, path });
53
49
  }
54
50
  if (surface.mode === 'public' && anonymousBehavior(tool) === 'requires-identity') {
55
51
  errors.push({
@@ -73,6 +69,58 @@ export function validateWebsiteProjection(assistant, surfaces) {
73
69
  });
74
70
  return errors;
75
71
  }
72
+ /**
73
+ * What a messaging profile can present (ADR 0240): pure reads and knowledge as before, plus a
74
+ * `collect` opener whose confirmed action is selected beside it and saves one native record. The
75
+ * opener may carry a browser widget (the website keeps its React view) because the profile renders
76
+ * the same block as natural collection. Anything else names the requirement it lacks.
77
+ */
78
+ function messagingRequirement(tool, selected, surfaces) {
79
+ const operations = operationRefs(tool.fulfilment);
80
+ const interaction = surfaces.interactions?.[tool.name];
81
+ if (interaction !== undefined && !selected.has(interaction.action)) {
82
+ return {
83
+ code: 'channel_dependency_missing',
84
+ message: `"${tool.name}" requires its confirmed action "${interaction.action}", which is not selected on this messaging surface`,
85
+ };
86
+ }
87
+ const opensCollection = interaction !== undefined;
88
+ const isCollectAction = [...selected].some((name) => surfaces.interactions?.[name]?.action === tool.name);
89
+ if (isCollectAction) {
90
+ const [operation] = operations;
91
+ if (operations.length === 1 &&
92
+ operation !== undefined &&
93
+ isNativeRecordsOperation(operation, surfaces.connectors)) {
94
+ return undefined;
95
+ }
96
+ return {
97
+ code: 'channel_requirement_unsupported',
98
+ message: `"${tool.name}" requires a connector call the messaging profile does not provide; a collect action saves exactly one native record`,
99
+ };
100
+ }
101
+ const requirements = [
102
+ ...(tool.annotations?.readOnlyHint !== true ? ['a write'] : []),
103
+ ...(operations.length > 0 ? ['a connector call'] : []),
104
+ ...(tool._meta?.ui?.resourceUri !== undefined && !opensCollection ? ['a UI renderer'] : []),
105
+ ];
106
+ if (requirements.length === 0)
107
+ return undefined;
108
+ return {
109
+ code: 'channel_requirement_unsupported',
110
+ message: `"${tool.name}" requires ${requirements.join(' and ')} that the messaging profile does not provide without a collect interaction`,
111
+ };
112
+ }
113
+ function operationRefs(fulfilment) {
114
+ return fulfilment.kind === 'operation'
115
+ ? [fulfilment.operationRef]
116
+ : fulfilment.steps.flatMap((step) => (step.kind === 'operation' ? [step.operationRef] : []));
117
+ }
118
+ /** Resolved refs carry the connector id; a shape-only ref is looked up through its declared alias. */
119
+ export function isNativeRecordsOperation(operation, connectors) {
120
+ return operation.resolved
121
+ ? operation.connectorId === RECORD_CONNECTOR_ID
122
+ : connectors?.[operation.connector]?.id === RECORD_CONNECTOR_ID;
123
+ }
76
124
  /**
77
125
  * Reads every expression a fulfilment evaluates — one operation's args, or a flow's output plus each
78
126
  * step's args and its `if` guard, since a condition can read `${user}` just as an argument can.
@@ -0,0 +1,8 @@
1
+ /** Development-only composition. PostgreSQL remains the production transaction authority. */
2
+ export declare class InMemoryAtomicState {
3
+ #private;
4
+ /** Values retain normal Map reference semantics; owners validate and copy their records. */
5
+ map<K, V>(): Map<K, V>;
6
+ run<T>(operation: () => Promise<T>): Promise<T>;
7
+ }
8
+ //# sourceMappingURL=in-memory-atomic-state.d.ts.map
@@ -0,0 +1,136 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ /** Development-only composition. PostgreSQL remains the production transaction authority. */
3
+ export class InMemoryAtomicState {
4
+ #current = new AsyncLocalStorage();
5
+ #tail = Promise.resolve();
6
+ /** Values retain normal Map reference semantics; owners validate and copy their records. */
7
+ map() {
8
+ return new AtomicMap(() => {
9
+ const transaction = this.#current.getStore();
10
+ if (transaction?.closed)
11
+ throw new Error('memory transaction is closed');
12
+ return transaction;
13
+ });
14
+ }
15
+ async run(operation) {
16
+ const inherited = this.#current.getStore();
17
+ if (inherited) {
18
+ if (inherited.closed)
19
+ throw new Error('memory transaction is closed');
20
+ inherited.pending++;
21
+ try {
22
+ return await operation();
23
+ }
24
+ catch (error) {
25
+ inherited.failure ??= { error };
26
+ throw error;
27
+ }
28
+ finally {
29
+ inherited.pending--;
30
+ }
31
+ }
32
+ const prior = this.#tail;
33
+ let release = () => { };
34
+ this.#tail = new Promise((done) => {
35
+ release = done;
36
+ });
37
+ await prior;
38
+ const transaction = { participants: new Map(), closed: false, pending: 0 };
39
+ try {
40
+ const result = await this.#current.run(transaction, operation);
41
+ if (transaction.failure)
42
+ throw transaction.failure.error;
43
+ if (transaction.pending !== 0)
44
+ throw new Error('memory transaction has unfinished work');
45
+ // Validate every generation before any publication. Nonparticipating mutations survive a conflict.
46
+ for (const participant of transaction.participants.values())
47
+ participant.validate();
48
+ for (const participant of transaction.participants.values())
49
+ participant.commit();
50
+ return result;
51
+ }
52
+ finally {
53
+ transaction.closed = true;
54
+ release();
55
+ }
56
+ }
57
+ }
58
+ /** Private maps never restore a process-wide snapshot or expose staged entries to another request. */
59
+ class AtomicMap {
60
+ transaction;
61
+ [Symbol.toStringTag] = 'Map';
62
+ #entries = new Map();
63
+ #generation = 0;
64
+ constructor(transaction) {
65
+ this.transaction = transaction;
66
+ }
67
+ #view(mutate = false) {
68
+ const transaction = this.transaction();
69
+ if (!transaction) {
70
+ if (mutate)
71
+ this.#generation++;
72
+ return this.#entries;
73
+ }
74
+ let participant = transaction.participants.get(this);
75
+ if (!participant) {
76
+ const generation = this.#generation;
77
+ const draft = { entries: new Map(this.#entries), dirty: false };
78
+ participant = {
79
+ value: draft,
80
+ validate: () => {
81
+ if (generation !== this.#generation)
82
+ throw new Error('memory transaction conflict');
83
+ },
84
+ commit: () => {
85
+ if (!draft.dirty)
86
+ return;
87
+ this.#entries = draft.entries;
88
+ this.#generation++;
89
+ },
90
+ };
91
+ transaction.participants.set(this, participant);
92
+ }
93
+ // The unexposed map instance is the type-stable key for this participant.
94
+ const draft = participant.value;
95
+ if (mutate)
96
+ draft.dirty = true;
97
+ return draft.entries;
98
+ }
99
+ get size() {
100
+ return this.#view().size;
101
+ }
102
+ get(key) {
103
+ return this.#view().get(key);
104
+ }
105
+ has(key) {
106
+ return this.#view().has(key);
107
+ }
108
+ set(key, value) {
109
+ this.#view(true).set(key, value);
110
+ return this;
111
+ }
112
+ delete(key) {
113
+ return this.#view(true).delete(key);
114
+ }
115
+ clear() {
116
+ this.#view(true).clear();
117
+ }
118
+ entries() {
119
+ return this.#view().entries();
120
+ }
121
+ keys() {
122
+ return this.#view().keys();
123
+ }
124
+ values() {
125
+ return this.#view().values();
126
+ }
127
+ [Symbol.iterator]() {
128
+ return this.entries();
129
+ }
130
+ forEach(callback, thisArg) {
131
+ this.#view().forEach((value, key) => {
132
+ callback.call(thisArg, value, key, this);
133
+ });
134
+ }
135
+ }
136
+ //# sourceMappingURL=in-memory-atomic-state.js.map
@@ -1,10 +1,17 @@
1
1
  import type { CreateOrgWithOwnerInput, OrgMemberRecord, OrgRecord, OrgRole, PersonalWorkspaceProvisionInput, PersonalWorkspaceProvisionResult, WelcomeEmailRecord } from './contracts.js';
2
+ import { InMemoryAtomicState } from './in-memory-atomic-state.js';
2
3
  import { InMemoryOrganizationStore } from './in-memory-organization-store.js';
3
4
  /** Portable organization state. Commercial account provisioning is an optional module side effect. */
4
5
  export declare class InMemoryControlPlaneStore extends InMemoryOrganizationStore {
5
6
  #private;
6
7
  constructor(options?: {
7
8
  readonly now?: () => Date;
9
+ readonly transactions?: InMemoryAtomicState;
10
+ /** Fresh-only local participant; all stores must share the supplied transaction context. */
11
+ readonly personalWorkspaceCreated?: (input: {
12
+ readonly org: string;
13
+ readonly ownerSubject: string;
14
+ }) => Promise<void>;
8
15
  });
9
16
  provisionPersonalWorkspace(input: PersonalWorkspaceProvisionInput): Promise<PersonalWorkspaceProvisionResult>;
10
17
  createOrgWithOwner(input: CreateOrgWithOwnerInput): Promise<OrgRecord>;
@@ -1,20 +1,29 @@
1
1
  import { PersonalWorkspaceOwnerMutationError } from './contracts.js';
2
+ import { InMemoryAtomicState } from './in-memory-atomic-state.js';
2
3
  import { InMemoryOrganizationStore } from './in-memory-organization-store.js';
3
4
  import { personalOrgSlugSuffix } from './organization-helpers.js';
4
5
  import { validateUserOwnedOrgSlug } from './validation.js';
5
6
  /** Portable organization state. Commercial account provisioning is an optional module side effect. */
6
7
  export class InMemoryControlPlaneStore extends InMemoryOrganizationStore {
7
- #welcomeEmails = new Map();
8
- #personalWorkspaces = new Map();
9
- #queues = new Map();
8
+ #welcomeEmails;
9
+ #personalWorkspaces;
10
10
  #now;
11
+ #transactions;
12
+ #personalWorkspaceCreated;
11
13
  constructor(options = {}) {
14
+ if (options.personalWorkspaceCreated && !options.transactions)
15
+ throw new Error('fresh workspace composition requires a shared memory transaction context');
12
16
  const now = options.now ?? (() => new Date());
13
- super({ now });
17
+ const transactions = options.transactions ?? new InMemoryAtomicState();
18
+ super({ now, transactions });
14
19
  this.#now = now;
20
+ this.#transactions = transactions;
21
+ this.#personalWorkspaceCreated = options.personalWorkspaceCreated;
22
+ this.#welcomeEmails = transactions.map();
23
+ this.#personalWorkspaces = transactions.map();
15
24
  }
16
25
  provisionPersonalWorkspace(input) {
17
- return this.#serialized(`personal:${input.subject}`, async () => {
26
+ return this.#transactions.run(async () => {
18
27
  const requestedSlug = validateUserOwnedOrgSlug(input.slug);
19
28
  const bound = this.#personalWorkspaces.get(input.subject);
20
29
  if (bound !== undefined) {
@@ -46,6 +55,7 @@ export class InMemoryControlPlaneStore extends InMemoryOrganizationStore {
46
55
  }
47
56
  const org = await this.createOrg({ slug: requestedSlug, displayName: input.displayName });
48
57
  await this.#ensureOwner(requestedSlug, input);
58
+ await this.#personalWorkspaceCreated?.({ org: requestedSlug, ownerSubject: input.subject });
49
59
  const createdAt = this.#now().toISOString();
50
60
  this.#welcomeEmails.set(input.subject, {
51
61
  subject: input.subject,
@@ -60,7 +70,7 @@ export class InMemoryControlPlaneStore extends InMemoryOrganizationStore {
60
70
  });
61
71
  }
62
72
  createOrgWithOwner(input) {
63
- return this.#serialized(`org:${input.slug}`, async () => {
73
+ return this.#transactions.run(async () => {
64
74
  const slug = validateUserOwnedOrgSlug(input.slug);
65
75
  const existing = await this.getOrg(slug);
66
76
  if (existing !== undefined) {
@@ -149,23 +159,5 @@ export class InMemoryControlPlaneStore extends InMemoryOrganizationStore {
149
159
  throw new PersonalWorkspaceOwnerMutationError();
150
160
  }
151
161
  }
152
- async #serialized(key, operation) {
153
- const prior = this.#queues.get(key) ?? Promise.resolve();
154
- let release;
155
- const next = new Promise((resolve) => {
156
- release = resolve;
157
- });
158
- const chain = prior.then(() => next);
159
- this.#queues.set(key, chain);
160
- await prior;
161
- try {
162
- return await operation();
163
- }
164
- finally {
165
- release();
166
- if (this.#queues.get(key) === chain)
167
- this.#queues.delete(key);
168
- }
169
- }
170
162
  }
171
163
  //# sourceMappingURL=in-memory-control-plane-store.js.map
@@ -1,6 +1,8 @@
1
1
  import type { ActiveMcpSubdomainClaim, ChangeMcpSubdomainInput, McpSubdomainMutationResult, McpSubdomainSetting, OrganizationStore, OrgDomainRecord, OrgInvitationRecord, OrgMemberRecord, OrgOpenAIAppsChallengeRecord, OrgRecord, OrgRole, SignupAllowlistKind, SignupAllowlistRecord } from './contracts.js';
2
- import { type AcceptOrganizationAgreementInput } from './organization-agreements.js';
2
+ import type { InMemoryAtomicState } from './in-memory-atomic-state.js';
3
+ import { type AcceptOrganizationAgreementInput, type OrganizationAgreementOwnerAuthority } from './organization-agreements.js';
3
4
  interface InMemoryOrganizationStoreOptions {
5
+ readonly transactions?: InMemoryAtomicState;
4
6
  readonly now?: () => Date;
5
7
  readonly orgs?: Map<string, OrgRecord>;
6
8
  readonly members?: Map<string, OrgMemberRecord>;
@@ -10,7 +12,7 @@ export declare class InMemoryOrganizationStore {
10
12
  #private;
11
13
  constructor(options?: InMemoryOrganizationStoreOptions);
12
14
  getOrganizationAgreement(org: string, version: string): Promise<import("./organization-agreements.js").OrganizationAgreementAcceptance | undefined>;
13
- acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput): Promise<import("./organization-agreements.js").OrganizationAgreementAcceptance>;
15
+ acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput, authority?: OrganizationAgreementOwnerAuthority): Promise<import("./organization-agreements.js").OrganizationAgreementAcceptance>;
14
16
  hasOrg(org: string): boolean;
15
17
  isExactOwner(org: string, subject: string): boolean;
16
18
  ensureDefaultMcpSubdomain(org: string): ActiveMcpSubdomainClaim | undefined;
@@ -15,17 +15,19 @@ export class InMemoryOrganizationStore {
15
15
  #now;
16
16
  #agreements;
17
17
  constructor(options = {}) {
18
+ if (options.transactions && (options.orgs || options.members))
19
+ throw new Error('atomic organization state cannot use externally mutable maps');
18
20
  this.#now = options.now ?? (() => new Date());
19
- this.#orgs = options.orgs ?? new Map();
20
- this.#members = options.members ?? new Map();
21
- this.#mcpSubdomainClaims = new InMemoryMcpSubdomainClaimStore(this.#now);
22
- this.#agreements = new InMemoryOrganizationAgreements((org, subject) => this.isExactOwner(org, subject), this.#now);
21
+ this.#orgs = options.orgs ?? options.transactions?.map() ?? new Map();
22
+ this.#members = options.members ?? options.transactions?.map() ?? new Map();
23
+ this.#mcpSubdomainClaims = new InMemoryMcpSubdomainClaimStore(this.#now, options.transactions);
24
+ this.#agreements = new InMemoryOrganizationAgreements((org, subject) => this.isExactOwner(org, subject), this.#now, options.transactions);
23
25
  }
24
26
  getOrganizationAgreement(org, version) {
25
27
  return this.#agreements.getOrganizationAgreement(org, version);
26
28
  }
27
- acceptOrganizationAgreement(input) {
28
- return this.#agreements.acceptOrganizationAgreement(input);
29
+ acceptOrganizationAgreement(input, authority) {
30
+ return this.#agreements.acceptOrganizationAgreement(input, authority);
29
31
  }
30
32
  hasOrg(org) {
31
33
  return this.#orgs.has(org);
@@ -1,4 +1,5 @@
1
1
  import type { ActiveMcpSubdomainClaim, ChangeMcpSubdomainInput, McpSubdomainMutationResult, McpSubdomainSetting, OrganizationStore } from './contracts.js';
2
+ import type { InMemoryAtomicState } from './in-memory-atomic-state.js';
2
3
  export declare class McpSubdomainOwnerRequiredError extends Error {
3
4
  constructor();
4
5
  }
@@ -15,7 +16,7 @@ export declare class McpSubdomainCooldownError extends Error {
15
16
  /** In-memory parity for active claim reads and organization-creation defaults. */
16
17
  export declare class InMemoryMcpSubdomainClaimStore {
17
18
  #private;
18
- constructor(now?: () => Date);
19
+ constructor(now?: () => Date, transactions?: InMemoryAtomicState);
19
20
  ensureDefaultMcpSubdomain(org: string): ActiveMcpSubdomainClaim | undefined;
20
21
  getActiveMcpSubdomain(org: string): Promise<ActiveMcpSubdomainClaim | undefined>;
21
22
  resolveActiveMcpSubdomain(mcpSubdomain: string): Promise<ActiveMcpSubdomainClaim | undefined>;
@@ -29,15 +29,20 @@ export class McpSubdomainCooldownError extends Error {
29
29
  }
30
30
  /** In-memory parity for active claim reads and organization-creation defaults. */
31
31
  export class InMemoryMcpSubdomainClaimStore {
32
- #activeByOrg = new Map();
33
- #activeBySubdomain = new Map();
34
- #claimedSubdomains = new Set();
35
- #lastChangedAtByOrg = new Map();
36
- #mutations = new Map();
32
+ #activeByOrg;
33
+ #activeBySubdomain;
34
+ #claimedSubdomains;
35
+ #lastChangedAtByOrg;
36
+ #mutations;
37
37
  #now;
38
38
  #mutationTail = Promise.resolve();
39
- constructor(now = () => new Date()) {
39
+ constructor(now = () => new Date(), transactions) {
40
40
  this.#now = now;
41
+ this.#activeByOrg = transactions?.map() ?? new Map();
42
+ this.#activeBySubdomain = transactions?.map() ?? new Map();
43
+ this.#claimedSubdomains = transactions?.map() ?? new Map();
44
+ this.#lastChangedAtByOrg = transactions?.map() ?? new Map();
45
+ this.#mutations = transactions?.map() ?? new Map();
41
46
  }
42
47
  ensureDefaultMcpSubdomain(org) {
43
48
  const orgSlug = validateSlug('org', org);
@@ -57,7 +62,7 @@ export class InMemoryMcpSubdomainClaimStore {
57
62
  };
58
63
  this.#activeByOrg.set(orgSlug, record);
59
64
  this.#activeBySubdomain.set(mcpSubdomain, record);
60
- this.#claimedSubdomains.add(mcpSubdomain);
65
+ this.#claimedSubdomains.set(mcpSubdomain, true);
61
66
  return record;
62
67
  }
63
68
  getActiveMcpSubdomain(org) {
@@ -127,7 +132,7 @@ export class InMemoryMcpSubdomainClaimStore {
127
132
  this.#activeBySubdomain.delete(current.mcpSubdomain);
128
133
  this.#activeByOrg.set(org, next);
129
134
  this.#activeBySubdomain.set(mcpSubdomain, next);
130
- this.#claimedSubdomains.add(mcpSubdomain);
135
+ this.#claimedSubdomains.set(mcpSubdomain, true);
131
136
  this.#lastChangedAtByOrg.set(org, changedAt);
132
137
  const result = {
133
138
  orgSlug: org,
@@ -1,3 +1,4 @@
1
+ import { InMemoryAtomicState } from './in-memory-atomic-state.js';
1
2
  export interface AgreementDocument {
2
3
  readonly url: string;
3
4
  readonly sha256: string;
@@ -25,7 +26,13 @@ export interface AcceptOrganizationAgreementInput {
25
26
  export interface OrganizationAgreementStore {
26
27
  getOrganizationAgreement(org: string, version: string): Promise<OrganizationAgreementAcceptance | undefined>;
27
28
  /** Repeats live exact-owner authorization atomically; equal acceptance preserves the first receipt. */
28
- acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput): Promise<OrganizationAgreementAcceptance>;
29
+ acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput, authority?: OrganizationAgreementOwnerAuthority): Promise<OrganizationAgreementAcceptance>;
30
+ }
31
+ /** Trusted host policy, never request data. The selected owner authority must fence the local commit.
32
+ * Legacy may be selected only when no versioned authority exists, never after denial or an outage.
33
+ */
34
+ export interface OrganizationAgreementOwnerAuthority {
35
+ run<T>(org: string, actor: string, commit: () => Promise<T>, legacy: () => Promise<T>): Promise<T>;
29
36
  }
30
37
  export declare class OrganizationAgreementError extends Error {
31
38
  readonly code: 'agreement_owner_required' | 'agreement_version_conflict';
@@ -33,13 +40,15 @@ export declare class OrganizationAgreementError extends Error {
33
40
  }
34
41
  export declare function validateAgreementDocuments(input: AgreementDocuments): AgreementDocuments;
35
42
  export declare function agreementDocumentDigest(documents: AgreementDocuments): string;
36
- /** Synchronous commit boundary keeps membership recheck, catalog registration and receipt indivisible. */
43
+ /** Authority completion and receipt publication share the development-only transaction context. */
37
44
  export declare class InMemoryOrganizationAgreements implements OrganizationAgreementStore {
38
45
  #private;
39
46
  private readonly isOwner;
40
47
  private readonly now;
41
- constructor(isOwner: (org: string, subject: string) => boolean, now: () => Date);
48
+ private readonly transactions;
49
+ constructor(isOwner: (org: string, subject: string) => boolean, now: () => Date, transactions?: InMemoryAtomicState);
42
50
  getOrganizationAgreement(org: string, version: string): Promise<OrganizationAgreementAcceptance | undefined>;
43
- acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput): Promise<OrganizationAgreementAcceptance>;
51
+ acceptOrganizationAgreement(input: AcceptOrganizationAgreementInput, authority?: OrganizationAgreementOwnerAuthority): Promise<OrganizationAgreementAcceptance>;
52
+ private commit;
44
53
  }
45
54
  //# sourceMappingURL=organization-agreements.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import { InMemoryAtomicState } from './in-memory-atomic-state.js';
2
3
  import { validateSlug } from './validation.js';
3
4
  export class OrganizationAgreementError extends Error {
4
5
  code;
@@ -35,24 +36,39 @@ export function agreementDocumentDigest(documents) {
35
36
  .update(JSON.stringify(validateAgreementDocuments(documents)))
36
37
  .digest('hex');
37
38
  }
38
- /** Synchronous commit boundary keeps membership recheck, catalog registration and receipt indivisible. */
39
+ /** Authority completion and receipt publication share the development-only transaction context. */
39
40
  export class InMemoryOrganizationAgreements {
40
41
  isOwner;
41
42
  now;
42
- #catalog = new Map();
43
- #receipts = new Map();
44
- constructor(isOwner, now) {
43
+ transactions;
44
+ #catalog;
45
+ #receipts;
46
+ constructor(isOwner, now, transactions = new InMemoryAtomicState()) {
45
47
  this.isOwner = isOwner;
46
48
  this.now = now;
49
+ this.transactions = transactions;
50
+ this.#catalog = transactions.map();
51
+ this.#receipts = transactions.map();
47
52
  }
48
53
  getOrganizationAgreement(org, version) {
49
54
  const receipt = this.#receipts.get(JSON.stringify([validateSlug('org', org), version]));
50
55
  return Promise.resolve(receipt ? structuredClone(receipt) : undefined);
51
56
  }
52
- async acceptOrganizationAgreement(input) {
57
+ async acceptOrganizationAgreement(input, authority) {
53
58
  const org = validateSlug('org', input.org);
54
- if (!this.isOwner(org, input.actorSubject))
55
- throw new OrganizationAgreementError('agreement_owner_required');
59
+ const commit = () => Promise.resolve(this.commit({ ...input, org }));
60
+ const legacy = () => {
61
+ if (!this.isOwner(org, input.actorSubject))
62
+ throw new OrganizationAgreementError('agreement_owner_required');
63
+ return commit();
64
+ };
65
+ // Legacy check + publication is one synchronous operation; an enclosing context still stages maps.
66
+ return authority
67
+ ? this.transactions.run(() => authority.run(org, input.actorSubject, commit, legacy))
68
+ : legacy();
69
+ }
70
+ commit(input) {
71
+ const org = input.org;
56
72
  const documents = validateAgreementDocuments(input.documents);
57
73
  const documentDigest = agreementDocumentDigest(documents);
58
74
  const registered = this.#catalog.get(documents.version);
@@ -5,10 +5,11 @@ export { type DeploymentDeleteOperationResult, type DeploymentDeleteScope, type
5
5
  export { allowAllGate, bearerToken, type ControlPlaneAuthResult, type DeployAuthGate, } from './deploy-auth.js';
6
6
  export { CompositeControlPlaneGate, type ControlPlaneSignupMode, GoogleControlPlaneGate, type GoogleControlPlaneGateOptions, type GoogleIdTokenVerifier, GoogleWorkloadControlPlaneGate, type GoogleWorkloadControlPlaneGateOptions, NoodleOAuthControlPlaneGate, type NoodleOAuthControlPlaneGateOptions, type SignupAuthorizer, } from './deploy-gates.js';
7
7
  export type { DeploymentDeleteResult, DeploymentDeleteSelection, } from './deployment-deletion-contracts.js';
8
+ export { InMemoryAtomicState } from './in-memory-atomic-state.js';
8
9
  export { InMemoryControlPlaneStore } from './in-memory-control-plane-store.js';
9
10
  export { bindInMemoryOrganizationStore, type InMemoryOrganizationOperations, InMemoryOrganizationStore, } from './in-memory-organization-store.js';
10
11
  export { InMemoryMcpSubdomainClaimStore, McpSubdomainCooldownError, McpSubdomainIdempotencyConflictError, McpSubdomainOwnerRequiredError, type McpSubdomainRouteRef, McpSubdomainUnavailableError, mcpSubdomainEndpointOptions, type ResolvedMcpTenantRef, resolveMcpSubdomainTenant, } from './mcp-subdomain-claims.js';
11
- export { type AcceptOrganizationAgreementInput, type AgreementDocument, type AgreementDocuments, agreementDocumentDigest, type OrganizationAgreementAcceptance, OrganizationAgreementError, type OrganizationAgreementStore, validateAgreementDocuments, } from './organization-agreements.js';
12
+ export { type AcceptOrganizationAgreementInput, type AgreementDocument, type AgreementDocuments, agreementDocumentDigest, type OrganizationAgreementAcceptance, OrganizationAgreementError, type OrganizationAgreementOwnerAuthority, type OrganizationAgreementStore, validateAgreementDocuments, } from './organization-agreements.js';
12
13
  export { domainFromEmail, domainKey, memberKey, normalizeSignupAllowlistValue, personalOrgSlug, personalOrgSlugSuffix, signupKey, } from './organization-helpers.js';
13
14
  export { ensurePersonalWorkspace } from './personal-workspace.js';
14
15
  export { type RollbackControlPlane, type RollbackOperationDependencies, type RollbackOperationInput, type RollbackOperationResult, type RollbackRegistry, rollbackDeploymentOperation, } from './rollback-deployment.js';
@@ -3,6 +3,7 @@ export { PersonalWorkspaceOwnerMutationError } from './contracts.js';
3
3
  export { deleteDeploymentOperation, } from './delete-deployment.js';
4
4
  export { allowAllGate, bearerToken, } from './deploy-auth.js';
5
5
  export { CompositeControlPlaneGate, GoogleControlPlaneGate, GoogleWorkloadControlPlaneGate, NoodleOAuthControlPlaneGate, } from './deploy-gates.js';
6
+ export { InMemoryAtomicState } from './in-memory-atomic-state.js';
6
7
  export { InMemoryControlPlaneStore } from './in-memory-control-plane-store.js';
7
8
  export { bindInMemoryOrganizationStore, InMemoryOrganizationStore, } from './in-memory-organization-store.js';
8
9
  export { InMemoryMcpSubdomainClaimStore, McpSubdomainCooldownError, McpSubdomainIdempotencyConflictError, McpSubdomainOwnerRequiredError, McpSubdomainUnavailableError, mcpSubdomainEndpointOptions, resolveMcpSubdomainTenant, } from './mcp-subdomain-claims.js';
@@ -85,8 +85,11 @@ export interface PlatformHumanIdentityContribution {
85
85
  readonly oldTokenHash: string;
86
86
  readonly clientId: string;
87
87
  }) => Promise<'continue' | 'unknown' | 'suspended'>;
88
- /** Check a business assignee under the caller's borrowed transaction and suspension lock. */
89
- readonly assertActivePrincipal?: (transaction: ModuleSqlTransaction, subject: string) => Promise<void>;
88
+ /** Check under the caller's transaction and suspension lock. Versioned workspaces require
89
+ * explicit known-principal evidence; retained legacy consumers may ignore the optional receipt. */
90
+ readonly assertActivePrincipal?: (transaction: ModuleSqlTransaction, subject: string) => Promise<void> | Promise<{
91
+ readonly known: boolean;
92
+ }>;
90
93
  readonly continuityProbe?: () => void | Promise<void>;
91
94
  }
92
95
  //# sourceMappingURL=platform-human-identity.d.ts.map
@@ -80,6 +80,21 @@ export interface ConnectorCallHost {
80
80
  /** Internal inherited execution deadline; never a sandbox-controlled value. */
81
81
  parentSignal?: AbortSignal): Promise<unknown>;
82
82
  }
83
+ /**
84
+ * Trusted admission facts for native public writes (ADR 0240). Every field is transport- or
85
+ * adapter-derived: `network` from verified ingress, `messaging` as a binding-scoped participant digest
86
+ * computed only after webhook authentication, and `provenance` naming the channel a saved record came
87
+ * from. A write needs `network` or `messaging`; nothing here is ever read from tool input or expressions.
88
+ */
89
+ export interface PublicAdmissionContext {
90
+ readonly network?: string;
91
+ readonly visitor?: string;
92
+ readonly messaging?: string;
93
+ readonly provenance?: {
94
+ readonly kind: 'messaging';
95
+ readonly channel: 'whatsapp';
96
+ };
97
+ }
83
98
  /** A single connector-operation invocation, fully resolved and credentialed by the runtime. */
84
99
  export interface ConnectorCall {
85
100
  readonly capabilityBudget?: CapabilityBudget;
@@ -93,10 +108,7 @@ export interface ConnectorCall {
93
108
  readonly coordination?: OperationCoordinationSnapshot;
94
109
  readonly resolveCoordination?: () => Promise<void>;
95
110
  /** Trusted request attribution for native public writes; never an argument or expression value. */
96
- readonly publicAdmission?: {
97
- readonly network: string;
98
- readonly visitor?: string;
99
- };
111
+ readonly publicAdmission?: PublicAdmissionContext;
100
112
  /** Evaluated, validated arguments. */
101
113
  readonly args: Readonly<Record<string, unknown>>;
102
114
  /** Managed variables resolved for the deployment scope. */
@@ -1,7 +1,7 @@
1
1
  import type { ArtifactFulfilment, RuntimeArtifact } from '@noodle-borg/compiler';
2
2
  import { CapabilityBudget } from '@noodle-borg/managed-capabilities';
3
3
  import type { CredentialBroker } from './broker/types.js';
4
- import type { CallerIdentity, ConnectorRegistry, ExecutionTraceSink } from './connector/types.js';
4
+ import type { CallerIdentity, ConnectorRegistry, ExecutionTraceSink, PublicAdmissionContext } from './connector/types.js';
5
5
  import type { FrozenCustomerRoutes } from './customer-routing.js';
6
6
  import { type EvalScope } from './eval/evaluate.js';
7
7
  import type { InvocationContext } from './invocation-context.js';
@@ -26,11 +26,8 @@ export interface ExecuteDeps {
26
26
  readonly policy?: PolicyGate;
27
27
  readonly env?: Record<string, unknown> | (() => Promise<Record<string, unknown>>);
28
28
  readonly caller?: CallerIdentity;
29
- /** Transport-owned admission attribution; absent network means public native writes must refuse. */
30
- readonly publicAdmission?: {
31
- readonly network: string;
32
- readonly visitor?: string;
33
- };
29
+ /** Transport-owned admission attribution; without a network or messaging bucket public native writes refuse. */
30
+ readonly publicAdmission?: PublicAdmissionContext;
34
31
  /** Verified customer IdP issuer, kept outside caller/expression scope for credential isolation. */
35
32
  readonly customerIssuer?: string;
36
33
  /** Request-local validated customer connector routes, kept separate from caller/expression scope. */
@@ -7,7 +7,7 @@ export { resolveVariableEnvironment, type VariableEnvironmentResult, validateVar
7
7
  export { executePreparedTool, prepareToolForConfirmation, resumeToolPreparation, } from './confirmation.js';
8
8
  export { sanitizeConnectorFailureDetails } from './connector/failure-details.js';
9
9
  export { InMemoryConnector, InMemoryConnectorRegistry, type InMemoryOperation, type OperationHandler, } from './connector/in-memory.js';
10
- export type { CallerIdentity, Connector, ConnectorCall, ConnectorCallHost, ConnectorFailureCategory, ConnectorRegistry, ConnectorTraceEvent, ExecutionTraceSink, } from './connector/types.js';
10
+ export type { CallerIdentity, Connector, ConnectorCall, ConnectorCallHost, ConnectorFailureCategory, ConnectorRegistry, ConnectorTraceEvent, ExecutionTraceSink, PublicAdmissionContext, } from './connector/types.js';
11
11
  export { ConnectorInvocationError, connectorInvocationErrorMessage, isConnectorInvocationError, } from './connector/types.js';
12
12
  export { type CustomerConnectorRoute, type CustomerRouteBinding, type CustomerRouteRequirement, type FrozenCustomerRoute, type FrozenCustomerRoutes, freezeCustomerRoutes, resolveCustomerConnectorRoute, resolveCustomerRouteBinding, } from './customer-routing.js';
13
13
  export { type EvalScope, ExpressionEvalError, type ExpressionEvalErrorCode, evaluateCondition, evaluateValue, } from './eval/evaluate.js';