@opengeni/db 3.6.0 → 3.7.3-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/canonical-human-identities.js +3 -3
  2. package/dist/{chunk-744DFC65.js → chunk-4NAR7FBA.js} +92 -6
  3. package/dist/chunk-4NAR7FBA.js.map +1 -0
  4. package/dist/{chunk-IW6O6G7R.js → chunk-5NNCGFQY.js} +2 -2
  5. package/dist/{chunk-G3732M3T.js → chunk-DZCYW2WT.js} +2 -2
  6. package/dist/{chunk-WW7AJ5IC.js → chunk-F6PBS6WE.js} +5 -7
  7. package/dist/chunk-F6PBS6WE.js.map +1 -0
  8. package/dist/{chunk-UJ2EW3QI.js → chunk-O56DM5GZ.js} +340 -85
  9. package/dist/chunk-O56DM5GZ.js.map +1 -0
  10. package/dist/{chunk-CDMMSUWJ.js → chunk-S3TDDCS2.js} +3 -3
  11. package/dist/{chunk-Q5YUGQVK.js → chunk-SZAWDXQC.js} +3 -3
  12. package/dist/{chunk-UGDVSQ6U.js → chunk-U4WPPEBH.js} +2 -2
  13. package/dist/{chunk-2NT476HD.js → chunk-US4IS6IV.js} +2 -2
  14. package/dist/codex-token-resolver.d.ts +12 -1
  15. package/dist/company-profile-agent-admin.d.ts +4 -2
  16. package/dist/company-profile-agent-policy.d.ts +20 -0
  17. package/dist/company-profile-schema.d.ts +573 -0
  18. package/dist/editable-artifact-durable-export.js +2 -2
  19. package/dist/editable-artifacts.js +3 -3
  20. package/dist/index.d.ts +382 -18
  21. package/dist/index.js +4513 -2065
  22. package/dist/index.js.map +1 -1
  23. package/dist/managed-auth-session-sets.js +3 -3
  24. package/dist/managed-human-provisioning.d.ts +3 -3
  25. package/dist/memory-domain.d.ts +5 -3
  26. package/dist/provision-roles.js +1 -1
  27. package/dist/runtime-posture.d.ts +5 -5
  28. package/dist/schema.d.ts +725 -4
  29. package/dist/schema.js +13 -1
  30. package/dist/session-background-commands.js +3 -3
  31. package/dist/session-control.d.ts +40 -5
  32. package/dist/session-queue-commands.d.ts +2 -0
  33. package/dist/session-tenancy.js +3 -3
  34. package/dist/user-resource-authority.d.ts +8 -0
  35. package/dist/video-generation.js +3 -3
  36. package/drizzle/0369_local_human_personal_authority.sql +350 -0
  37. package/drizzle/0370_workspace_member_management_scope.sql +98 -0
  38. package/drizzle/0371_workspace_member_candidate_inventory.sql +128 -0
  39. package/drizzle/0372_ordered_variable_set_runtime_authority.sql +287 -0
  40. package/drizzle/0373_sandbox_shared_preparation.sql +59 -0
  41. package/drizzle/0374_session_event_cursors.sql +315 -0
  42. package/drizzle/0375_session_recovery_observability.sql +73 -0
  43. package/drizzle/0376_organization_workspace_inventory.sql +88 -0
  44. package/drizzle/0377_scoped_rig_health_projection.sql +80 -0
  45. package/drizzle/0378_scoped_rig_health_audit_timestamp.sql +77 -0
  46. package/drizzle/0379_session_event_raw_lane_activation.sql +518 -0
  47. package/drizzle/0380_autonomous_company_profile_agent_policy.sql +829 -0
  48. package/drizzle/0381_organization_codex_subscription_inheritance.sql +720 -0
  49. package/drizzle/0382_organization_api_key_provenance.sql +91 -0
  50. package/drizzle/0383_codex_cooldown_reconciliation.sql +51 -0
  51. package/drizzle/0384_codex_cooldown_revision_guard_privileges.sql +6 -0
  52. package/drizzle/0385_connected_machine_legacy_tilde_workdirs.sql +25 -0
  53. package/drizzle/0386_local_organization_administration.sql +157 -0
  54. package/package.json +6 -6
  55. package/src/codex-token-resolver.ts +26 -1
  56. package/src/company-brain-governed-writes.ts +30 -1
  57. package/src/company-profile-agent-admin.ts +68 -1
  58. package/src/company-profile-agent-policy.ts +126 -0
  59. package/src/company-profile-schema.ts +115 -1
  60. package/src/database.ts +3 -5
  61. package/src/index.ts +3626 -456
  62. package/src/managed-human-provisioning.ts +3 -3
  63. package/src/memory-domain.ts +9 -4
  64. package/src/organization-membership-lifecycle.ts +0 -1
  65. package/src/provision-roles.ts +83 -4
  66. package/src/runtime-posture.ts +22 -0
  67. package/src/schema.ts +161 -8
  68. package/src/session-control.ts +177 -59
  69. package/src/session-queue-commands.ts +146 -40
  70. package/src/session-tool-call-settlement.ts +34 -7
  71. package/src/user-resource-authority.ts +56 -0
  72. package/dist/chunk-744DFC65.js.map +0 -1
  73. package/dist/chunk-UJ2EW3QI.js.map +0 -1
  74. package/dist/chunk-WW7AJ5IC.js.map +0 -1
  75. /package/dist/{chunk-IW6O6G7R.js.map → chunk-5NNCGFQY.js.map} +0 -0
  76. /package/dist/{chunk-G3732M3T.js.map → chunk-DZCYW2WT.js.map} +0 -0
  77. /package/dist/{chunk-CDMMSUWJ.js.map → chunk-S3TDDCS2.js.map} +0 -0
  78. /package/dist/{chunk-Q5YUGQVK.js.map → chunk-SZAWDXQC.js.map} +0 -0
  79. /package/dist/{chunk-UGDVSQ6U.js.map → chunk-U4WPPEBH.js.map} +0 -0
  80. /package/dist/{chunk-2NT476HD.js.map → chunk-US4IS6IV.js.map} +0 -0
@@ -0,0 +1,829 @@
1
+ -- deployment-mode: rolling
2
+ -- Add an organization-owner policy for agent-authored company-profile changes.
3
+ -- Existing organizations default to `suggest`, preserving the exact bound
4
+ -- human-confirmation path. `automatic` replaces only that per-change prompt:
5
+ -- the live turn must still be initiated by the active organization owner, and
6
+ -- activation still uses the company-profile CAS lifecycle. `off` creates no
7
+ -- new proposal. The policy is organization-scoped and cannot be changed by a
8
+ -- workspace administrator.
9
+ --
10
+ -- Rolling compatibility: the v1 proposal function remains review-only for old
11
+ -- API processes, but now records the frozen policy and refuses `off`. New API
12
+ -- processes call v2, which consumes an `automatic` snapshot and records a
13
+ -- distinct automatic-activation receipt. Thus old processes can be stricter
14
+ -- during rollout but can never gain autonomous authority.
15
+
16
+ SET LOCAL lock_timeout = '5s';
17
+ SET LOCAL statement_timeout = '10min';
18
+
19
+ CREATE TABLE organization_company_profile_agent_policies (
20
+ account_id uuid PRIMARY KEY REFERENCES managed_accounts(id) ON DELETE CASCADE,
21
+ mode text NOT NULL DEFAULT 'suggest',
22
+ version bigint NOT NULL DEFAULT 0,
23
+ updated_by_membership_id uuid,
24
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
25
+ CONSTRAINT organization_company_profile_agent_policies_membership_fk
26
+ FOREIGN KEY (updated_by_membership_id, account_id)
27
+ REFERENCES organization_memberships(id, account_id) ON DELETE RESTRICT,
28
+ CONSTRAINT organization_company_profile_agent_policies_mode_check
29
+ CHECK (mode IN ('off', 'suggest', 'automatic')),
30
+ CONSTRAINT organization_company_profile_agent_policies_version_check CHECK (version >= 0)
31
+ );
32
+
33
+ CREATE TABLE organization_company_profile_agent_policy_events (
34
+ id uuid PRIMARY KEY,
35
+ account_id uuid NOT NULL REFERENCES managed_accounts(id) ON DELETE CASCADE,
36
+ actor_membership_id uuid NOT NULL,
37
+ requested_mode text NOT NULL,
38
+ expected_version bigint NOT NULL,
39
+ result_mode text NOT NULL,
40
+ result_version bigint NOT NULL,
41
+ result_updated_at timestamptz NOT NULL,
42
+ changed boolean NOT NULL,
43
+ CONSTRAINT organization_company_profile_agent_policy_events_membership_fk
44
+ FOREIGN KEY (actor_membership_id, account_id)
45
+ REFERENCES organization_memberships(id, account_id) ON DELETE RESTRICT,
46
+ CONSTRAINT organization_company_profile_agent_policy_events_mode_check CHECK (
47
+ requested_mode IN ('off', 'suggest', 'automatic')
48
+ AND result_mode IN ('off', 'suggest', 'automatic')
49
+ ),
50
+ CONSTRAINT organization_company_profile_agent_policy_events_version_check CHECK (
51
+ expected_version >= 0 AND result_version > 0
52
+ )
53
+ );
54
+ CREATE INDEX organization_company_profile_agent_policy_events_account_idx
55
+ ON organization_company_profile_agent_policy_events (account_id, result_version);
56
+
57
+ ALTER TABLE organization_company_profile_agent_policies ENABLE ROW LEVEL SECURITY;
58
+ ALTER TABLE organization_company_profile_agent_policies FORCE ROW LEVEL SECURITY;
59
+ ALTER TABLE organization_company_profile_agent_policy_events ENABLE ROW LEVEL SECURITY;
60
+ ALTER TABLE organization_company_profile_agent_policy_events FORCE ROW LEVEL SECURITY;
61
+ REVOKE ALL ON TABLE organization_company_profile_agent_policies FROM PUBLIC;
62
+ REVOKE ALL ON TABLE organization_company_profile_agent_policy_events FROM PUBLIC;
63
+ CREATE POLICY organization_company_profile_agent_policy_lifecycle
64
+ ON organization_company_profile_agent_policies
65
+ USING (current_setting('opengeni.company_profile_agent_policy_lifecycle', true)
66
+ = 'company_profile_agent_policy')
67
+ WITH CHECK (current_setting('opengeni.company_profile_agent_policy_lifecycle', true)
68
+ = 'company_profile_agent_policy');
69
+ CREATE POLICY organization_company_profile_agent_policy_lifecycle
70
+ ON organization_company_profile_agent_policy_events
71
+ USING (current_setting('opengeni.company_profile_agent_policy_lifecycle', true)
72
+ = 'company_profile_agent_policy')
73
+ WITH CHECK (current_setting('opengeni.company_profile_agent_policy_lifecycle', true)
74
+ = 'company_profile_agent_policy');
75
+ CREATE FUNCTION initialize_company_profile_agent_policy()
76
+ RETURNS trigger
77
+ LANGUAGE plpgsql SECURITY DEFINER
78
+ SET search_path FROM CURRENT
79
+ AS $body$
80
+ BEGIN
81
+ PERFORM pg_catalog.set_config(
82
+ 'opengeni.company_profile_agent_policy_lifecycle',
83
+ 'company_profile_agent_policy', true
84
+ );
85
+ INSERT INTO organization_company_profile_agent_policies (
86
+ account_id, mode, version, updated_by_membership_id, updated_at
87
+ ) VALUES (NEW.id, 'suggest', 0, NULL, NEW.created_at)
88
+ ON CONFLICT (account_id) DO NOTHING;
89
+ RETURN NEW;
90
+ END
91
+ $body$;
92
+ REVOKE ALL ON FUNCTION initialize_company_profile_agent_policy() FROM PUBLIC;
93
+ CREATE TRIGGER managed_accounts_initialize_company_profile_agent_policy
94
+ AFTER INSERT ON managed_accounts
95
+ FOR EACH ROW EXECUTE FUNCTION initialize_company_profile_agent_policy();
96
+
97
+ CREATE FUNCTION company_profile_agent_policy_events_immutable()
98
+ RETURNS trigger
99
+ LANGUAGE plpgsql
100
+ AS $body$
101
+ BEGIN
102
+ IF TG_OP = 'DELETE'
103
+ AND pg_trigger_depth() > 1
104
+ AND NOT EXISTS (SELECT 1 FROM managed_accounts account WHERE account.id = OLD.account_id)
105
+ THEN
106
+ RETURN OLD;
107
+ END IF;
108
+ RAISE EXCEPTION 'company-profile agent policy events are immutable'
109
+ USING ERRCODE = '55000';
110
+ END
111
+ $body$;
112
+ CREATE TRIGGER organization_company_profile_agent_policy_events_immutable
113
+ BEFORE UPDATE OR DELETE ON organization_company_profile_agent_policy_events
114
+ FOR EACH ROW EXECUTE FUNCTION company_profile_agent_policy_events_immutable();
115
+
116
+ SELECT pg_catalog.set_config(
117
+ 'opengeni.company_profile_agent_policy_lifecycle',
118
+ 'company_profile_agent_policy', true
119
+ );
120
+ -- Migrations run as the non-bypass table owner without tenant GUCs. Relax
121
+ -- FORCE only for this owner-visible backfill; the runtime role remains
122
+ -- policy-bound, and the migration transaction restores FORCE before commit.
123
+ ALTER TABLE organization_company_profile_agent_policies NO FORCE ROW LEVEL SECURITY;
124
+ INSERT INTO organization_company_profile_agent_policies (
125
+ account_id, mode, version, updated_by_membership_id, updated_at
126
+ )
127
+ SELECT account.id, 'suggest', 0, NULL, account.created_at
128
+ FROM managed_accounts account
129
+ ON CONFLICT (account_id) DO NOTHING;
130
+ ALTER TABLE organization_company_profile_agent_policies FORCE ROW LEVEL SECURITY;
131
+
132
+ CREATE FUNCTION get_company_profile_agent_policy(
133
+ p_account_id uuid,
134
+ p_workspace_id uuid,
135
+ p_actor_subject_id text
136
+ ) RETURNS jsonb
137
+ LANGUAGE plpgsql SECURITY DEFINER
138
+ SET search_path FROM CURRENT
139
+ AS $body$
140
+ DECLARE
141
+ context_account_id uuid := nullif(current_setting('opengeni.account_id', true), '')::uuid;
142
+ context_workspace_id uuid := nullif(current_setting('opengeni.workspace_id', true), '')::uuid;
143
+ context_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
144
+ context_principal_kind text := nullif(current_setting('opengeni.principal_kind', true), '');
145
+ actor organization_memberships%ROWTYPE;
146
+ policy organization_company_profile_agent_policies%ROWTYPE;
147
+ BEGIN
148
+ IF context_account_id IS DISTINCT FROM p_account_id
149
+ OR context_workspace_id IS DISTINCT FROM p_workspace_id
150
+ OR context_subject_id IS DISTINCT FROM p_actor_subject_id
151
+ OR context_principal_kind IS DISTINCT FROM 'human_session'
152
+ THEN
153
+ RAISE EXCEPTION 'organization owner authority required' USING ERRCODE = '42501';
154
+ END IF;
155
+ PERFORM pg_catalog.set_config(
156
+ 'opengeni.company_profile_agent_policy_lifecycle',
157
+ 'company_profile_agent_policy', true
158
+ );
159
+ PERFORM 1 FROM workspaces workspace
160
+ WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id;
161
+ IF NOT FOUND THEN
162
+ RAISE EXCEPTION 'organization workspace is unavailable' USING ERRCODE = '42501';
163
+ END IF;
164
+ SELECT membership.* INTO actor FROM organization_memberships membership
165
+ WHERE membership.account_id = p_account_id
166
+ AND membership.subject_id = p_actor_subject_id
167
+ AND membership.status = 'active'
168
+ AND membership.role = 'owner';
169
+ IF NOT FOUND THEN
170
+ RAISE EXCEPTION 'organization owner authority required' USING ERRCODE = '42501';
171
+ END IF;
172
+ SELECT * INTO policy FROM organization_company_profile_agent_policies candidate
173
+ WHERE candidate.account_id = p_account_id;
174
+ IF NOT FOUND THEN
175
+ RAISE EXCEPTION 'company-profile agent policy is unavailable' USING ERRCODE = '55000';
176
+ END IF;
177
+ RETURN pg_catalog.jsonb_build_object(
178
+ 'organizationId', p_account_id,
179
+ 'mode', policy.mode,
180
+ 'version', policy.version,
181
+ 'updatedAt', policy.updated_at
182
+ );
183
+ END
184
+ $body$;
185
+ REVOKE ALL ON FUNCTION get_company_profile_agent_policy(uuid,uuid,text) FROM PUBLIC;
186
+
187
+ CREATE FUNCTION update_company_profile_agent_policy(
188
+ p_account_id uuid,
189
+ p_workspace_id uuid,
190
+ p_actor_subject_id text,
191
+ p_mode text,
192
+ p_expected_version bigint,
193
+ p_operation_id uuid
194
+ ) RETURNS jsonb
195
+ LANGUAGE plpgsql SECURITY DEFINER
196
+ SET search_path FROM CURRENT
197
+ AS $body$
198
+ DECLARE
199
+ context_account_id uuid := nullif(current_setting('opengeni.account_id', true), '')::uuid;
200
+ context_workspace_id uuid := nullif(current_setting('opengeni.workspace_id', true), '')::uuid;
201
+ context_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
202
+ context_principal_kind text := nullif(current_setting('opengeni.principal_kind', true), '');
203
+ actor organization_memberships%ROWTYPE;
204
+ policy organization_company_profile_agent_policies%ROWTYPE;
205
+ prior organization_company_profile_agent_policy_events%ROWTYPE;
206
+ next_version bigint;
207
+ did_change boolean;
208
+ BEGIN
209
+ IF context_account_id IS DISTINCT FROM p_account_id
210
+ OR context_workspace_id IS DISTINCT FROM p_workspace_id
211
+ OR context_subject_id IS DISTINCT FROM p_actor_subject_id
212
+ OR context_principal_kind IS DISTINCT FROM 'human_session'
213
+ OR p_mode NOT IN ('off', 'suggest', 'automatic')
214
+ OR p_expected_version IS NULL OR p_expected_version < 0
215
+ OR p_operation_id IS NULL
216
+ THEN
217
+ RAISE EXCEPTION 'company-profile agent policy request is invalid' USING ERRCODE = '22023';
218
+ END IF;
219
+ PERFORM pg_catalog.pg_advisory_xact_lock(pg_catalog.hashtextextended(
220
+ 'organization-membership:' || p_account_id::text, 0
221
+ ));
222
+ PERFORM pg_catalog.set_config(
223
+ 'opengeni.company_profile_agent_policy_lifecycle',
224
+ 'company_profile_agent_policy', true
225
+ );
226
+ PERFORM 1 FROM managed_accounts account WHERE account.id = p_account_id FOR KEY SHARE;
227
+ IF NOT FOUND THEN RAISE EXCEPTION 'organization not found' USING ERRCODE = 'P0002'; END IF;
228
+ PERFORM 1 FROM workspaces workspace
229
+ WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id;
230
+ IF NOT FOUND THEN
231
+ RAISE EXCEPTION 'organization workspace is unavailable' USING ERRCODE = '42501';
232
+ END IF;
233
+ SELECT membership.* INTO actor FROM organization_memberships membership
234
+ WHERE membership.account_id = p_account_id
235
+ AND membership.subject_id = p_actor_subject_id
236
+ AND membership.status = 'active'
237
+ AND membership.role = 'owner'
238
+ FOR SHARE;
239
+ IF NOT FOUND THEN
240
+ RAISE EXCEPTION 'organization owner authority required' USING ERRCODE = '42501';
241
+ END IF;
242
+ SELECT * INTO prior FROM organization_company_profile_agent_policy_events event
243
+ WHERE event.id = p_operation_id;
244
+ IF FOUND THEN
245
+ IF prior.account_id IS DISTINCT FROM p_account_id
246
+ OR prior.actor_membership_id IS DISTINCT FROM actor.id
247
+ OR prior.requested_mode IS DISTINCT FROM p_mode
248
+ OR prior.expected_version IS DISTINCT FROM p_expected_version
249
+ THEN
250
+ RAISE EXCEPTION 'company-profile agent policy operation id was reused'
251
+ USING ERRCODE = 'P1851';
252
+ END IF;
253
+ RETURN pg_catalog.jsonb_build_object(
254
+ 'organizationId', p_account_id,
255
+ 'mode', prior.result_mode,
256
+ 'version', prior.result_version,
257
+ 'updatedAt', prior.result_updated_at,
258
+ 'changed', prior.changed
259
+ );
260
+ END IF;
261
+ SELECT * INTO policy FROM organization_company_profile_agent_policies candidate
262
+ WHERE candidate.account_id = p_account_id FOR UPDATE;
263
+ IF NOT FOUND THEN
264
+ RAISE EXCEPTION 'company-profile agent policy is unavailable' USING ERRCODE = '55000';
265
+ END IF;
266
+ IF policy.version IS DISTINCT FROM p_expected_version THEN
267
+ RAISE EXCEPTION 'company-profile agent policy changed before update'
268
+ USING ERRCODE = '40001';
269
+ END IF;
270
+ did_change := policy.mode IS DISTINCT FROM p_mode;
271
+ next_version := policy.version + 1;
272
+ UPDATE organization_company_profile_agent_policies SET
273
+ mode = p_mode,
274
+ version = next_version,
275
+ updated_by_membership_id = actor.id,
276
+ updated_at = clock_timestamp()
277
+ WHERE account_id = p_account_id
278
+ RETURNING * INTO policy;
279
+ INSERT INTO organization_company_profile_agent_policy_events (
280
+ id, account_id, actor_membership_id, requested_mode, expected_version,
281
+ result_mode, result_version, result_updated_at, changed
282
+ ) VALUES (
283
+ p_operation_id, p_account_id, actor.id, p_mode, p_expected_version,
284
+ policy.mode, policy.version, policy.updated_at, did_change
285
+ );
286
+ RETURN pg_catalog.jsonb_build_object(
287
+ 'organizationId', p_account_id,
288
+ 'mode', policy.mode,
289
+ 'version', policy.version,
290
+ 'updatedAt', policy.updated_at,
291
+ 'changed', did_change
292
+ );
293
+ END
294
+ $body$;
295
+ REVOKE ALL ON FUNCTION
296
+ update_company_profile_agent_policy(uuid,uuid,text,text,bigint,uuid) FROM PUBLIC;
297
+
298
+ ALTER TABLE company_profile_agent_proposal_receipts
299
+ ADD COLUMN policy_mode text NOT NULL DEFAULT 'suggest',
300
+ ADD COLUMN policy_version bigint NOT NULL DEFAULT 0;
301
+ ALTER TABLE company_profile_agent_proposal_receipts
302
+ ADD CONSTRAINT company_profile_agent_proposals_policy_mode_check
303
+ CHECK (policy_mode IN ('suggest', 'automatic')),
304
+ ADD CONSTRAINT company_profile_agent_proposals_policy_version_check
305
+ CHECK (policy_version >= 0);
306
+
307
+ CREATE TABLE company_profile_agent_automatic_activation_receipts (
308
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
309
+ operation_id uuid NOT NULL,
310
+ input_hash text NOT NULL,
311
+ account_id uuid NOT NULL REFERENCES managed_accounts(id) ON DELETE CASCADE,
312
+ workspace_id uuid NOT NULL,
313
+ session_id uuid NOT NULL,
314
+ turn_id uuid NOT NULL,
315
+ activation_attempt_id uuid NOT NULL,
316
+ execution_generation integer NOT NULL,
317
+ proposal_receipt_id uuid NOT NULL,
318
+ proposal_revision_id uuid NOT NULL,
319
+ initiating_human_subject_id text NOT NULL,
320
+ initiating_membership_id uuid NOT NULL,
321
+ policy_version bigint NOT NULL,
322
+ activation_event_id uuid NOT NULL,
323
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
324
+ CONSTRAINT company_profile_agent_automatic_activations_workspace_fk
325
+ FOREIGN KEY (workspace_id, account_id)
326
+ REFERENCES workspaces(id, account_id) ON DELETE CASCADE,
327
+ CONSTRAINT company_profile_agent_automatic_activations_session_fk
328
+ FOREIGN KEY (workspace_id, session_id)
329
+ REFERENCES sessions(workspace_id, id) ON DELETE CASCADE,
330
+ CONSTRAINT company_profile_agent_automatic_activations_turn_fk
331
+ FOREIGN KEY (workspace_id, turn_id)
332
+ REFERENCES session_turns(workspace_id, id) ON DELETE CASCADE,
333
+ CONSTRAINT company_profile_agent_automatic_activations_attempt_fk
334
+ FOREIGN KEY (account_id, workspace_id, session_id, turn_id, activation_attempt_id)
335
+ REFERENCES session_turn_attempts(account_id, workspace_id, session_id, turn_id, id)
336
+ ON DELETE CASCADE,
337
+ CONSTRAINT company_profile_agent_automatic_activations_proposal_fk
338
+ FOREIGN KEY (proposal_receipt_id, account_id)
339
+ REFERENCES company_profile_agent_proposal_receipts(id, account_id) ON DELETE RESTRICT,
340
+ CONSTRAINT company_profile_agent_automatic_activations_revision_fk
341
+ FOREIGN KEY (proposal_revision_id, account_id)
342
+ REFERENCES company_profile_revisions(id, account_id) ON DELETE RESTRICT,
343
+ CONSTRAINT company_profile_agent_automatic_activations_membership_fk
344
+ FOREIGN KEY (initiating_membership_id, account_id)
345
+ REFERENCES organization_memberships(id, account_id) ON DELETE RESTRICT,
346
+ CONSTRAINT company_profile_agent_automatic_activations_event_fk
347
+ FOREIGN KEY (activation_event_id, account_id)
348
+ REFERENCES company_profile_activation_events(id, account_id) ON DELETE RESTRICT,
349
+ CONSTRAINT company_profile_agent_automatic_activations_input_hash_check CHECK (
350
+ input_hash ~ '^[0-9a-f]{64}$'
351
+ ),
352
+ CONSTRAINT company_profile_agent_automatic_activations_generation_check CHECK (
353
+ execution_generation > 0 AND policy_version >= 0
354
+ ),
355
+ CONSTRAINT company_profile_agent_automatic_activations_subject_check CHECK (
356
+ octet_length(btrim(initiating_human_subject_id)) BETWEEN 1 AND 1024
357
+ )
358
+ );
359
+ CREATE UNIQUE INDEX company_profile_agent_automatic_activations_account_operation_uq
360
+ ON company_profile_agent_automatic_activation_receipts (account_id, operation_id);
361
+ CREATE UNIQUE INDEX company_profile_agent_automatic_activations_proposal_uq
362
+ ON company_profile_agent_automatic_activation_receipts (account_id, proposal_receipt_id);
363
+ CREATE UNIQUE INDEX company_profile_agent_automatic_activations_event_uq
364
+ ON company_profile_agent_automatic_activation_receipts (account_id, activation_event_id);
365
+ CREATE INDEX company_profile_agent_automatic_activations_turn_idx
366
+ ON company_profile_agent_automatic_activation_receipts (
367
+ workspace_id, session_id, turn_id, execution_generation
368
+ );
369
+
370
+ ALTER TABLE company_profile_agent_automatic_activation_receipts ENABLE ROW LEVEL SECURITY;
371
+ ALTER TABLE company_profile_agent_automatic_activation_receipts FORCE ROW LEVEL SECURITY;
372
+ REVOKE ALL ON TABLE company_profile_agent_automatic_activation_receipts FROM PUBLIC;
373
+ CREATE POLICY company_profile_agent_admin_lifecycle
374
+ ON company_profile_agent_automatic_activation_receipts
375
+ USING (current_setting('opengeni.company_profile_agent_admin_lifecycle', true)
376
+ = 'company_profile_agent_admin')
377
+ WITH CHECK (current_setting('opengeni.company_profile_agent_admin_lifecycle', true)
378
+ = 'company_profile_agent_admin');
379
+ CREATE POLICY session_visibility_isolation
380
+ ON company_profile_agent_automatic_activation_receipts AS RESTRICTIVE
381
+ USING (session_reference_visible(account_id, workspace_id, session_id))
382
+ WITH CHECK (session_reference_visible(account_id, workspace_id, session_id));
383
+ CREATE TRIGGER company_profile_agent_automatic_activations_immutable
384
+ BEFORE UPDATE OR DELETE ON company_profile_agent_automatic_activation_receipts
385
+ FOR EACH ROW EXECUTE FUNCTION company_profile_agent_receipts_immutable();
386
+
387
+ CREATE OR REPLACE FUNCTION propose_company_profile_for_attempt(
388
+ p_account_id uuid,
389
+ p_workspace_id uuid,
390
+ p_session_id uuid,
391
+ p_turn_id uuid,
392
+ p_attempt_id uuid,
393
+ p_execution_generation integer,
394
+ p_operation_id uuid,
395
+ p_content_json text,
396
+ p_content_hash text,
397
+ p_reason text
398
+ ) RETURNS TABLE (
399
+ receipt_id uuid,
400
+ revision_id uuid,
401
+ human_input jsonb,
402
+ replayed boolean
403
+ )
404
+ LANGUAGE plpgsql SECURITY DEFINER
405
+ SET search_path FROM CURRENT
406
+ AS $body$
407
+ DECLARE
408
+ context_account_id uuid := nullif(current_setting('opengeni.account_id', true), '')::uuid;
409
+ context_workspace_id uuid := nullif(current_setting('opengeni.workspace_id', true), '')::uuid;
410
+ context_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
411
+ context_principal_kind text := nullif(current_setting('opengeni.principal_kind', true), '');
412
+ initiating_subject text;
413
+ actor_membership organization_memberships%ROWTYPE;
414
+ active_head company_profile_heads%ROWTYPE;
415
+ policy organization_company_profile_agent_policies%ROWTYPE;
416
+ prior company_profile_agent_proposal_receipts%ROWTYPE;
417
+ inserted_revision company_profile_revisions%ROWTYPE;
418
+ input_hash_value text;
419
+ new_receipt_id uuid := gen_random_uuid();
420
+ new_revision_id uuid := gen_random_uuid();
421
+ normalized_reason text := btrim(p_reason);
422
+ prompt jsonb;
423
+ BEGIN
424
+ IF context_account_id IS DISTINCT FROM p_account_id
425
+ OR context_workspace_id IS DISTINCT FROM p_workspace_id
426
+ OR context_subject_id IS NULL
427
+ OR context_principal_kind IS DISTINCT FROM 'agent_attempt'
428
+ OR p_execution_generation < 1
429
+ OR p_operation_id IS NULL
430
+ OR p_content_json IS NULL
431
+ OR p_content_hash !~ '^[0-9a-f]{64}$'
432
+ OR p_content_hash IS DISTINCT FROM encode(sha256(convert_to(p_content_json, 'UTF8')), 'hex')
433
+ OR octet_length(convert_to(p_content_json, 'UTF8')) NOT BETWEEN 1 AND 28672
434
+ OR octet_length(convert_to(normalized_reason, 'UTF8')) NOT BETWEEN 1 AND 16384
435
+ THEN
436
+ RAISE EXCEPTION 'company-profile agent proposal is invalid' USING ERRCODE = '22023';
437
+ END IF;
438
+
439
+ SELECT coalesce(
440
+ turn.initiating_human_subject_id,
441
+ CASE WHEN turn.initiator_kind = 'subject' THEN turn.initiator_subject_id END
442
+ ) INTO initiating_subject
443
+ FROM session_turns turn
444
+ WHERE turn.account_id = p_account_id
445
+ AND turn.workspace_id = p_workspace_id
446
+ AND turn.session_id = p_session_id
447
+ AND turn.id = p_turn_id;
448
+ IF initiating_subject IS NULL THEN
449
+ RAISE EXCEPTION
450
+ 'company-profile agent proposals require the exact live turn of the active organization owner'
451
+ USING ERRCODE = '42501';
452
+ END IF;
453
+
454
+ PERFORM 1 FROM workspaces workspace
455
+ WHERE workspace.account_id = p_account_id AND workspace.id = p_workspace_id
456
+ FOR KEY SHARE;
457
+ IF NOT FOUND THEN
458
+ RAISE EXCEPTION 'organization workspace is unavailable' USING ERRCODE = '42501';
459
+ END IF;
460
+ SELECT membership.* INTO actor_membership
461
+ FROM organization_memberships membership
462
+ WHERE membership.account_id = p_account_id
463
+ AND membership.subject_id = initiating_subject
464
+ AND membership.status = 'active'
465
+ AND membership.role = 'owner'
466
+ FOR KEY SHARE;
467
+ IF NOT FOUND THEN
468
+ RAISE EXCEPTION
469
+ 'company-profile agent proposals require the exact live turn of the active organization owner'
470
+ USING ERRCODE = '42501';
471
+ END IF;
472
+ PERFORM 1
473
+ FROM sessions session
474
+ JOIN session_turns turn
475
+ ON turn.account_id = session.account_id
476
+ AND turn.workspace_id = session.workspace_id
477
+ AND turn.session_id = session.id
478
+ JOIN session_turn_attempts attempt
479
+ ON attempt.account_id = turn.account_id
480
+ AND attempt.workspace_id = turn.workspace_id
481
+ AND attempt.session_id = turn.session_id
482
+ AND attempt.turn_id = turn.id
483
+ WHERE session.account_id = p_account_id
484
+ AND session.workspace_id = p_workspace_id
485
+ AND session.id = p_session_id
486
+ AND session.active_turn_id = p_turn_id
487
+ AND turn.id = p_turn_id
488
+ AND turn.active_attempt_id = p_attempt_id
489
+ AND turn.execution_generation = p_execution_generation
490
+ AND turn.status IN ('running', 'requires_action', 'recovering', 'waiting_capacity')
491
+ AND coalesce(
492
+ turn.initiating_human_subject_id,
493
+ CASE WHEN turn.initiator_kind = 'subject' THEN turn.initiator_subject_id END
494
+ ) = actor_membership.subject_id
495
+ AND attempt.id = p_attempt_id
496
+ AND attempt.execution_generation = p_execution_generation
497
+ AND attempt.state IN ('claimed', 'running')
498
+ AND NOT EXISTS (
499
+ SELECT 1 FROM session_attempt_interruptions interruption
500
+ WHERE interruption.workspace_id = attempt.workspace_id
501
+ AND interruption.attempt_id = attempt.id
502
+ AND interruption.state IN ('pending', 'delivered', 'acknowledged')
503
+ )
504
+ FOR SHARE OF session, turn, attempt;
505
+ IF NOT FOUND THEN
506
+ RAISE EXCEPTION
507
+ 'company-profile agent proposals require the exact live turn of the active organization owner'
508
+ USING ERRCODE = '42501';
509
+ END IF;
510
+
511
+ PERFORM 1 FROM managed_accounts account
512
+ WHERE account.id = p_account_id FOR KEY SHARE;
513
+ IF NOT FOUND THEN
514
+ RAISE EXCEPTION 'organization account is unavailable' USING ERRCODE = '42501';
515
+ END IF;
516
+
517
+ input_hash_value := encode(sha256(convert_to(jsonb_build_array(
518
+ 'company-profile-agent-proposal', 1, p_account_id, p_workspace_id,
519
+ p_session_id, p_turn_id, p_operation_id, p_content_hash, normalized_reason,
520
+ actor_membership.id, actor_membership.subject_id
521
+ )::text, 'UTF8')), 'hex');
522
+ PERFORM set_config(
523
+ 'opengeni.company_profile_agent_admin_lifecycle',
524
+ 'company_profile_agent_admin', true
525
+ );
526
+ SELECT * INTO prior FROM company_profile_agent_proposal_receipts receipt
527
+ WHERE receipt.account_id = p_account_id AND receipt.operation_id = p_operation_id;
528
+ IF FOUND THEN
529
+ IF prior.input_hash IS DISTINCT FROM input_hash_value THEN
530
+ RAISE EXCEPTION 'company-profile agent proposal operation id was reused'
531
+ USING ERRCODE = 'P1851';
532
+ END IF;
533
+ receipt_id := prior.id;
534
+ revision_id := prior.revision_id;
535
+ human_input := prior.human_input;
536
+ replayed := true;
537
+ RETURN NEXT;
538
+ RETURN;
539
+ END IF;
540
+ IF EXISTS (
541
+ SELECT 1 FROM company_profile_revisions revision
542
+ WHERE revision.account_id = p_account_id AND revision.operation_id = p_operation_id
543
+ ) THEN
544
+ RAISE EXCEPTION 'company-profile agent proposal operation id was reused'
545
+ USING ERRCODE = 'P1851';
546
+ END IF;
547
+
548
+ PERFORM set_config(
549
+ 'opengeni.company_profile_agent_policy_lifecycle',
550
+ 'company_profile_agent_policy', true
551
+ );
552
+ SELECT * INTO policy FROM organization_company_profile_agent_policies candidate
553
+ WHERE candidate.account_id = p_account_id
554
+ FOR SHARE;
555
+ IF NOT FOUND THEN
556
+ RAISE EXCEPTION 'company-profile agent policy is unavailable' USING ERRCODE = '55000';
557
+ END IF;
558
+ IF policy.mode = 'off' THEN
559
+ RAISE EXCEPTION 'company-profile agent changes are disabled by organization policy'
560
+ USING ERRCODE = 'P1852';
561
+ END IF;
562
+
563
+ SELECT * INTO active_head FROM company_profile_heads head
564
+ WHERE head.account_id = p_account_id;
565
+ INSERT INTO company_profile_revisions (
566
+ id, operation_id, request_fingerprint, account_id, intent,
567
+ content_json, content_hash, provenance_source, provenance_source_id,
568
+ supersedes_revision_id, created_by_subject_id
569
+ ) VALUES (
570
+ new_revision_id, p_operation_id, input_hash_value, p_account_id, 'proposal',
571
+ p_content_json, p_content_hash, 'agent_admin',
572
+ 'agent-admin-proposal:' || new_receipt_id::text,
573
+ active_head.revision_id, context_subject_id
574
+ ) RETURNING * INTO inserted_revision;
575
+ prompt := company_profile_agent_confirmation_prompt(
576
+ inserted_revision.id, inserted_revision.revision,
577
+ inserted_revision.content_hash, inserted_revision.content_json
578
+ );
579
+ INSERT INTO company_profile_agent_proposal_receipts (
580
+ id, operation_id, input_hash, account_id, workspace_id, session_id,
581
+ turn_id, creation_attempt_id, execution_generation,
582
+ initiating_human_subject_id, initiating_membership_id, revision_id,
583
+ expected_current_revision_id, expected_activation_version,
584
+ policy_mode, policy_version, reason, human_input
585
+ ) VALUES (
586
+ new_receipt_id, p_operation_id, input_hash_value, p_account_id, p_workspace_id,
587
+ p_session_id, p_turn_id, p_attempt_id, p_execution_generation,
588
+ actor_membership.subject_id, actor_membership.id, inserted_revision.id,
589
+ active_head.revision_id, coalesce(active_head.activation_version, 0),
590
+ policy.mode, policy.version, normalized_reason, prompt
591
+ );
592
+ receipt_id := new_receipt_id;
593
+ revision_id := inserted_revision.id;
594
+ human_input := prompt;
595
+ replayed := false;
596
+ RETURN NEXT;
597
+ END
598
+ $body$;
599
+
600
+ CREATE FUNCTION propose_company_profile_for_attempt_v2(
601
+ p_account_id uuid,
602
+ p_workspace_id uuid,
603
+ p_session_id uuid,
604
+ p_turn_id uuid,
605
+ p_attempt_id uuid,
606
+ p_execution_generation integer,
607
+ p_operation_id uuid,
608
+ p_automatic_activation_operation_id uuid,
609
+ p_content_json text,
610
+ p_content_hash text,
611
+ p_reason text
612
+ ) RETURNS TABLE (
613
+ receipt_id uuid,
614
+ revision_id uuid,
615
+ human_input jsonb,
616
+ policy_mode text,
617
+ automatic_activation_receipt_id uuid,
618
+ activation_event_id uuid,
619
+ replayed boolean
620
+ )
621
+ LANGUAGE plpgsql SECURITY DEFINER
622
+ SET search_path FROM CURRENT
623
+ AS $body$
624
+ DECLARE
625
+ context_subject_id text := nullif(current_setting('opengeni.subject_id', true), '');
626
+ context_principal_kind text := nullif(current_setting('opengeni.principal_kind', true), '');
627
+ base record;
628
+ proposal company_profile_agent_proposal_receipts%ROWTYPE;
629
+ proposal_revision company_profile_revisions%ROWTYPE;
630
+ prior company_profile_agent_automatic_activation_receipts%ROWTYPE;
631
+ input_hash_value text;
632
+ event_id_value uuid;
633
+ new_receipt_id uuid := gen_random_uuid();
634
+ service_actor text := 'service:company-profile-autonomy';
635
+ BEGIN
636
+ IF context_subject_id IS NULL
637
+ OR context_principal_kind IS DISTINCT FROM 'agent_attempt'
638
+ OR p_automatic_activation_operation_id IS NULL
639
+ OR p_automatic_activation_operation_id IS NOT DISTINCT FROM p_operation_id
640
+ THEN
641
+ RAISE EXCEPTION 'company-profile automatic activation operation is invalid'
642
+ USING ERRCODE = '22023';
643
+ END IF;
644
+ SELECT * INTO base FROM propose_company_profile_for_attempt(
645
+ p_account_id, p_workspace_id, p_session_id, p_turn_id, p_attempt_id,
646
+ p_execution_generation, p_operation_id, p_content_json, p_content_hash, p_reason
647
+ );
648
+ IF base.receipt_id IS NULL THEN
649
+ RAISE EXCEPTION 'company-profile proposal returned no receipt' USING ERRCODE = '55000';
650
+ END IF;
651
+ PERFORM set_config(
652
+ 'opengeni.company_profile_agent_admin_lifecycle',
653
+ 'company_profile_agent_admin', true
654
+ );
655
+ SELECT * INTO proposal FROM company_profile_agent_proposal_receipts receipt
656
+ WHERE receipt.account_id = p_account_id AND receipt.id = base.receipt_id
657
+ FOR SHARE;
658
+ IF NOT FOUND THEN
659
+ RAISE EXCEPTION 'company-profile proposal receipt is unavailable' USING ERRCODE = '55000';
660
+ END IF;
661
+
662
+ receipt_id := proposal.id;
663
+ revision_id := proposal.revision_id;
664
+ human_input := proposal.human_input;
665
+ policy_mode := proposal.policy_mode;
666
+ IF proposal.policy_mode = 'suggest' THEN
667
+ automatic_activation_receipt_id := NULL;
668
+ activation_event_id := NULL;
669
+ replayed := base.replayed;
670
+ RETURN NEXT;
671
+ RETURN;
672
+ END IF;
673
+ IF proposal.policy_mode IS DISTINCT FROM 'automatic' THEN
674
+ RAISE EXCEPTION 'company-profile proposal policy is invalid' USING ERRCODE = '55000';
675
+ END IF;
676
+
677
+ SELECT * INTO prior FROM company_profile_agent_automatic_activation_receipts receipt
678
+ WHERE receipt.account_id = p_account_id AND receipt.proposal_receipt_id = proposal.id;
679
+ IF FOUND THEN
680
+ IF prior.operation_id IS DISTINCT FROM p_automatic_activation_operation_id THEN
681
+ RAISE EXCEPTION 'company-profile automatic activation operation id was reused'
682
+ USING ERRCODE = 'P1851';
683
+ END IF;
684
+ automatic_activation_receipt_id := prior.id;
685
+ activation_event_id := prior.activation_event_id;
686
+ replayed := true;
687
+ RETURN NEXT;
688
+ RETURN;
689
+ END IF;
690
+ SELECT * INTO prior FROM company_profile_agent_automatic_activation_receipts receipt
691
+ WHERE receipt.account_id = p_account_id
692
+ AND receipt.operation_id = p_automatic_activation_operation_id;
693
+ IF FOUND THEN
694
+ RAISE EXCEPTION 'company-profile automatic activation operation id was reused'
695
+ USING ERRCODE = 'P1851';
696
+ END IF;
697
+
698
+ SELECT * INTO proposal_revision FROM company_profile_revisions revision
699
+ WHERE revision.account_id = p_account_id
700
+ AND revision.id = proposal.revision_id
701
+ AND revision.intent = 'proposal'
702
+ AND revision.provenance_source = 'agent_admin'
703
+ AND revision.provenance_source_id = 'agent-admin-proposal:' || proposal.id::text
704
+ FOR SHARE;
705
+ IF NOT FOUND THEN
706
+ RAISE EXCEPTION 'company-profile proposal revision is unavailable'
707
+ USING ERRCODE = '42501';
708
+ END IF;
709
+
710
+ input_hash_value := encode(sha256(convert_to(jsonb_build_array(
711
+ 'company-profile-agent-automatic-activation', 1,
712
+ p_account_id, p_workspace_id, p_session_id, p_turn_id,
713
+ p_automatic_activation_operation_id, proposal.id, proposal.revision_id,
714
+ proposal.policy_version, proposal.initiating_membership_id,
715
+ proposal.initiating_human_subject_id
716
+ )::text, 'UTF8')), 'hex');
717
+
718
+ PERFORM set_config('opengeni.subject_id', service_actor, true);
719
+ PERFORM set_config('opengeni.principal_kind', 'service', true);
720
+ SELECT activation.event_id INTO event_id_value
721
+ FROM company_profile_apply_activation(
722
+ p_automatic_activation_operation_id, input_hash_value,
723
+ p_account_id, p_workspace_id, proposal_revision.id,
724
+ proposal.expected_current_revision_id, proposal.expected_activation_version,
725
+ 'activate', service_actor, 'service',
726
+ 'Automatically activated under the organization company-profile agent policy'
727
+ ) activation;
728
+ IF event_id_value IS NULL THEN
729
+ RAISE EXCEPTION 'company-profile automatic activation returned no event'
730
+ USING ERRCODE = '55000';
731
+ END IF;
732
+ PERFORM set_config('opengeni.subject_id', context_subject_id, true);
733
+ PERFORM set_config('opengeni.principal_kind', context_principal_kind, true);
734
+
735
+ INSERT INTO company_profile_agent_automatic_activation_receipts (
736
+ id, operation_id, input_hash, account_id, workspace_id, session_id, turn_id,
737
+ activation_attempt_id, execution_generation, proposal_receipt_id,
738
+ proposal_revision_id, initiating_human_subject_id, initiating_membership_id,
739
+ policy_version, activation_event_id
740
+ ) VALUES (
741
+ new_receipt_id, p_automatic_activation_operation_id, input_hash_value,
742
+ p_account_id, p_workspace_id, p_session_id, p_turn_id, p_attempt_id,
743
+ p_execution_generation, proposal.id, proposal.revision_id,
744
+ proposal.initiating_human_subject_id, proposal.initiating_membership_id,
745
+ proposal.policy_version, event_id_value
746
+ );
747
+ automatic_activation_receipt_id := new_receipt_id;
748
+ activation_event_id := event_id_value;
749
+ replayed := false;
750
+ RETURN NEXT;
751
+ END
752
+ $body$;
753
+
754
+ REVOKE ALL ON FUNCTION propose_company_profile_for_attempt_v2(
755
+ uuid,uuid,uuid,uuid,uuid,integer,uuid,uuid,text,text,text
756
+ ) FROM PUBLIC;
757
+
758
+ DO $autonomous_company_profile_hardening$
759
+ DECLARE
760
+ target_schema text := current_schema();
761
+ runtime_role text := nullif(current_setting('opengeni.runtime_role', true), '');
762
+ BEGIN
763
+ EXECUTE format(
764
+ 'ALTER FUNCTION %I.initialize_company_profile_agent_policy() '
765
+ || 'SET search_path = pg_catalog, %I, pg_temp',
766
+ target_schema, target_schema
767
+ );
768
+ EXECUTE format(
769
+ 'ALTER FUNCTION %I.company_profile_agent_policy_events_immutable() '
770
+ || 'SET search_path = pg_catalog, %I, pg_temp',
771
+ target_schema, target_schema
772
+ );
773
+ EXECUTE format(
774
+ 'ALTER FUNCTION %I.get_company_profile_agent_policy(uuid,uuid,text) '
775
+ || 'SET search_path = pg_catalog, %I, pg_temp',
776
+ target_schema, target_schema
777
+ );
778
+ EXECUTE format(
779
+ 'ALTER FUNCTION %I.update_company_profile_agent_policy(uuid,uuid,text,text,bigint,uuid) '
780
+ || 'SET search_path = pg_catalog, %I, pg_temp',
781
+ target_schema, target_schema
782
+ );
783
+ EXECUTE format(
784
+ 'ALTER FUNCTION %I.propose_company_profile_for_attempt('
785
+ || 'uuid,uuid,uuid,uuid,uuid,integer,uuid,text,text,text) '
786
+ || 'SET search_path = pg_catalog, %I, pg_temp',
787
+ target_schema, target_schema
788
+ );
789
+ EXECUTE format(
790
+ 'ALTER FUNCTION %I.propose_company_profile_for_attempt_v2('
791
+ || 'uuid,uuid,uuid,uuid,uuid,integer,uuid,uuid,text,text,text) '
792
+ || 'SET search_path = pg_catalog, %I, pg_temp',
793
+ target_schema, target_schema
794
+ );
795
+ IF runtime_role IS NOT NULL THEN
796
+ EXECUTE format(
797
+ 'REVOKE ALL ON TABLE %I.organization_company_profile_agent_policies FROM %I',
798
+ target_schema, runtime_role
799
+ );
800
+ EXECUTE format(
801
+ 'REVOKE ALL ON TABLE %I.organization_company_profile_agent_policy_events FROM %I',
802
+ target_schema, runtime_role
803
+ );
804
+ EXECUTE format(
805
+ 'REVOKE ALL ON TABLE %I.company_profile_agent_automatic_activation_receipts FROM %I',
806
+ target_schema, runtime_role
807
+ );
808
+ EXECUTE format(
809
+ 'GRANT EXECUTE ON FUNCTION %I.get_company_profile_agent_policy(uuid,uuid,text) TO %I',
810
+ target_schema, runtime_role
811
+ );
812
+ EXECUTE format(
813
+ 'GRANT EXECUTE ON FUNCTION %I.update_company_profile_agent_policy('
814
+ || 'uuid,uuid,text,text,bigint,uuid) TO %I',
815
+ target_schema, runtime_role
816
+ );
817
+ EXECUTE format(
818
+ 'GRANT EXECUTE ON FUNCTION %I.propose_company_profile_for_attempt_v2('
819
+ || 'uuid,uuid,uuid,uuid,uuid,integer,uuid,uuid,text,text,text) TO %I',
820
+ target_schema, runtime_role
821
+ );
822
+ END IF;
823
+ END
824
+ $autonomous_company_profile_hardening$;
825
+
826
+ COMMENT ON TABLE organization_company_profile_agent_policies IS
827
+ 'Organization-owner policy for agent-authored company-profile changes; default suggest preserves per-change confirmation, automatic permits exact owner-initiated turns to activate through the company-profile lifecycle.';
828
+ COMMENT ON TABLE company_profile_agent_automatic_activation_receipts IS
829
+ 'Immutable exact-attempt receipts for company-profile proposals activated without per-change confirmation under a frozen organization-owner automatic policy.';