@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.
- package/dist/commands/solutions-activity.js +1 -1
- package/dist/commands/solutions-activity.js.map +1 -1
- package/dist/commands/solutions-drafts.d.ts.map +1 -1
- package/dist/commands/solutions-drafts.js +36 -9
- package/dist/commands/solutions-drafts.js.map +1 -1
- package/dist/commands/solutions-native-lifecycle.d.ts +5 -0
- package/dist/commands/solutions-native-lifecycle.d.ts.map +1 -0
- package/dist/commands/solutions-native-lifecycle.js +77 -0
- package/dist/commands/solutions-native-lifecycle.js.map +1 -0
- package/dist/commands/solutions-ops.d.ts.map +1 -1
- package/dist/commands/solutions-ops.js +3 -0
- package/dist/commands/solutions-ops.js.map +1 -1
- package/dist/commands/solutions-workspace.d.ts.map +1 -1
- package/dist/commands/solutions-workspace.js +36 -11
- package/dist/commands/solutions-workspace.js.map +1 -1
- package/dist/commands/whatsapp-output.d.ts.map +1 -1
- package/dist/commands/whatsapp-output.js +20 -4
- package/dist/commands/whatsapp-output.js.map +1 -1
- package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.d.ts +16 -9
- package/node_modules/@noodle-borg/admission-limits/dist/public-record-admission.js +5 -2
- package/node_modules/@noodle-borg/agent-kit/dist/curated/error-fixes.js +9 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +5 -5
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +9 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +13 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.d.ts +5 -3
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-coordinator.js +5 -4
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-inbox.js +6 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-store.d.ts +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-types.d.ts +12 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.d.ts +7 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/channel-work.js +14 -4
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-capture.js +104 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-judgment.js +93 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-ledger.d.ts +105 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-ledger.js +183 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-model-call.js +38 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-parsers.d.ts +22 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-parsers.js +109 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-review.d.ts +21 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-review.js +44 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-spec.d.ts +18 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-spec.js +86 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-store.d.ts +11 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/collection-store.js +18 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.d.ts +20 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/messaging-tool-dispatch.js +38 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/model-runtime.js +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/portable.d.ts +5 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/portable.js +5 -0
- package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/authoring/dist/interaction.d.ts +49 -0
- package/node_modules/@noodle-borg/authoring/dist/interaction.js +25 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +3 -0
- package/node_modules/@noodle-borg/authoring/dist/server.js +4 -0
- package/node_modules/@noodle-borg/authoring/package.json +6 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-channels.js +1 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-drafts.js +7 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-native-lifecycle.js +43 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-records.js +154 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-workspace.js +8 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solutions.js +2 -149
- package/node_modules/@noodle-borg/compiler/dist/artifact/assemble.js +2 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +33 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.d.ts +2 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/version.js +2 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.js +5 -0
- package/node_modules/@noodle-borg/compiler/dist/errors.d.ts +1 -1
- package/node_modules/@noodle-borg/compiler/dist/index.d.ts +2 -2
- package/node_modules/@noodle-borg/compiler/dist/index.js +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-schema.d.ts +41 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-schema.js +62 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/interaction-validation.js +220 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +60 -4
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +7 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.d.ts +9 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/website-projection.js +58 -10
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-atomic-state.d.ts +8 -0
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-atomic-state.js +136 -0
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-control-plane-store.d.ts +7 -0
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-control-plane-store.js +16 -24
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.d.ts +4 -2
- package/node_modules/@noodle-borg/control-plane/dist/in-memory-organization-store.js +8 -6
- package/node_modules/@noodle-borg/control-plane/dist/mcp-subdomain-claims.d.ts +2 -1
- package/node_modules/@noodle-borg/control-plane/dist/mcp-subdomain-claims.js +13 -8
- package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.d.ts +13 -4
- package/node_modules/@noodle-borg/control-plane/dist/organization-agreements.js +23 -7
- package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +2 -1
- package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
- package/node_modules/@noodle-borg/module/dist/platform-human-identity.d.ts +5 -2
- package/node_modules/@noodle-borg/runtime/dist/connector/types.d.ts +16 -4
- package/node_modules/@noodle-borg/runtime/dist/execute.d.ts +3 -6
- package/node_modules/@noodle-borg/runtime/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/service/dist/application-activity.js +85 -63
- package/node_modules/@noodle-borg/service/dist/application-drafts/contracts.js +9 -0
- package/node_modules/@noodle-borg/service/dist/application-drafts/paths.js +2 -2
- package/node_modules/@noodle-borg/service/dist/application-runtime-target.js +1 -1
- package/node_modules/@noodle-borg/service/dist/business-information/contracts.d.ts +18 -4
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-business-pages.js +3 -5
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-installation-lifecycle.js +8 -6
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-native-lifecycle.js +80 -0
- package/node_modules/@noodle-borg/service/dist/business-information/in-memory-store.js +27 -31
- package/node_modules/@noodle-borg/service/dist/business-information/memory-native-retention.js +29 -0
- package/node_modules/@noodle-borg/service/dist/business-information/model.js +9 -2
- package/node_modules/@noodle-borg/service/dist/business-information/native-query.js +3 -1
- package/node_modules/@noodle-borg/service/dist/business-information/native-record-lifecycle.d.ts +27 -0
- package/node_modules/@noodle-borg/service/dist/business-information/native-record-lifecycle.js +63 -0
- package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.d.ts +3 -1
- package/node_modules/@noodle-borg/service/dist/business-information/principal-authority.js +9 -4
- package/node_modules/@noodle-borg/service/dist/business-information/staff-authority.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/business-information/staff-authority.js +60 -0
- package/node_modules/@noodle-borg/service/dist/business-information/workspace-permissions.js +18 -0
- package/node_modules/@noodle-borg/service/dist/business-information-runtime.js +1 -0
- package/node_modules/@noodle-borg/service/dist/business-onboarding.js +16 -3
- package/node_modules/@noodle-borg/service/dist/business-workspaces/contracts.d.ts +110 -0
- package/node_modules/@noodle-borg/service/dist/business-workspaces/permissions.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/business-workspaces/store.d.ts +102 -0
- package/node_modules/@noodle-borg/service/dist/channels/360dialog.js +70 -8
- package/node_modules/@noodle-borg/service/dist/channels/capability-report.js +73 -0
- package/node_modules/@noodle-borg/service/dist/channels/collection-turn.js +232 -0
- package/node_modules/@noodle-borg/service/dist/channels/composition.js +1 -0
- package/node_modules/@noodle-borg/service/dist/channels/messaging-eligibility.js +45 -0
- package/node_modules/@noodle-borg/service/dist/channels/reply-buttons.js +23 -0
- package/node_modules/@noodle-borg/service/dist/channels/runtime.js +127 -33
- package/node_modules/@noodle-borg/service/dist/native-record-connector.js +19 -4
- package/node_modules/@noodle-borg/service/dist/routes/application-drafts.js +44 -2
- package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +4 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-authoring-dispatch.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-access.js +39 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-activity.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-channels.js +2 -2
- package/node_modules/@noodle-borg/service/dist/routes/business-information-connections.js +10 -4
- package/node_modules/@noodle-borg/service/dist/routes/business-information-dispatch.js +11 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-installation.js +3 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-notice.js +6 -2
- package/node_modules/@noodle-borg/service/dist/routes/business-information-pages.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-paths.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/business-information-record-create.js +7 -2
- package/node_modules/@noodle-borg/service/dist/routes/business-information-record-reads.js +2 -2
- package/node_modules/@noodle-borg/service/dist/routes/business-information-records.js +332 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-information-settings.js +6 -3
- package/node_modules/@noodle-borg/service/dist/routes/business-information-staff.js +9 -5
- package/node_modules/@noodle-borg/service/dist/routes/business-information.js +12 -356
- package/node_modules/@noodle-borg/service/dist/routes/business-native-lifecycle.js +46 -0
- package/node_modules/@noodle-borg/service/dist/routes/business-workspaces.js +14 -1
- package/node_modules/@noodle-borg/service/dist/service.js +1 -0
- package/node_modules/@noodle-borg/service/dist/web-capabilities.js +3 -1
- package/node_modules/@noodle-borg/service/package.json +2 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/application-draft-validation.d.ts +59 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/application-draft-validation.js +38 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.d.ts +144 -50
- package/node_modules/@noodle-borg/wire-contracts/dist/business-information.js +44 -4
- package/node_modules/@noodle-borg/wire-contracts/dist/business-workspaces.d.ts +70 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/business-workspaces.js +31 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +2 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +2 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/native-record-lifecycle.d.ts +81 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/native-record-lifecycle.js +39 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.d.ts +26 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.js +24 -1
- package/node_modules/@noodleseed/assistant/package.json +1 -1
- 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
|
-
(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
8
|
-
#personalWorkspaces
|
|
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
|
-
|
|
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.#
|
|
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.#
|
|
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 {
|
|
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
|
|
33
|
-
#activeBySubdomain
|
|
34
|
-
#claimedSubdomains
|
|
35
|
-
#lastChangedAtByOrg
|
|
36
|
-
#mutations
|
|
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.
|
|
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.
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
-
/**
|
|
39
|
+
/** Authority completion and receipt publication share the development-only transaction context. */
|
|
39
40
|
export class InMemoryOrganizationAgreements {
|
|
40
41
|
isOwner;
|
|
41
42
|
now;
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
|
89
|
-
|
|
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;
|
|
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';
|