@consiliency/agent-board-schema 1.57.0 → 1.59.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.
- package/fixtures/already-applied.json +8 -0
- package/migrations/20261008000100_agent_board_hosted_delegates.sql +3152 -0
- package/migrations/20261009000100_agent_board_hosted_followups.sql +665 -0
- package/package.json +1 -1
- package/schema-manifest.json +21 -3
- package/src/tooling.test.mjs +9 -2
- package/tests/agent_board_atomic_fleet_onboarding.test.sql +13 -0
- package/tests/agent_board_consent_emission.test.sql +4 -2
- package/tests/agent_board_delegate_role_class.test.sql +736 -0
- package/tests/agent_board_federated_identity_injective_slug.test.sql +5 -2
- package/tests/agent_board_fedsession_stored_identity_gate.test.sql +71 -14
- package/tests/agent_board_fk_lock_edges.test.sql +9 -0
- package/tests/agent_board_hosted_delegates.test.sql +1278 -0
- package/tests/agent_board_ledger_authority.test.sql +34 -5
- package/tests/agent_board_signer_lifecycle.test.sql +3 -0
- package/tests/agent_board_write_enforcement_class.test.sql +8 -3
- package/tests/catalog/function_execute_privileges.json +269 -2
- package/tests/catalog/p_metadata_parameters.json +44 -0
- package/tests/isolation/expected/hosted_delegate_add_tombstone_race.out +105 -0
- package/tests/isolation/expected/hosted_delegate_exchange_agent_revoke_race.out +66 -0
- package/tests/isolation/expected/hosted_delegate_exchange_race.out +93 -0
- package/tests/isolation/expected/hosted_delegate_first_exchange_race.out +129 -0
- package/tests/isolation/expected/hosted_delegate_owner_provisioning_race.out +91 -0
- package/tests/isolation/expected/hosted_delegate_owner_revoke_race.out +137 -0
- package/tests/isolation/expected/hosted_delegate_revoke_race.out +87 -0
- package/tests/isolation/expected/hosted_delegate_tombstone_revoke_race.out +170 -0
- package/tests/isolation/expected/hosted_delegate_withdraw_evict_race.out +235 -0
- package/tests/isolation/specs/hosted_delegate_add_tombstone_race.spec +102 -0
- package/tests/isolation/specs/hosted_delegate_exchange_agent_revoke_race.spec +92 -0
- package/tests/isolation/specs/hosted_delegate_exchange_race.spec +64 -0
- package/tests/isolation/specs/hosted_delegate_first_exchange_race.spec +72 -0
- package/tests/isolation/specs/hosted_delegate_owner_provisioning_race.spec +73 -0
- package/tests/isolation/specs/hosted_delegate_owner_revoke_race.spec +93 -0
- package/tests/isolation/specs/hosted_delegate_revoke_race.spec +59 -0
- package/tests/isolation/specs/hosted_delegate_tombstone_revoke_race.spec +158 -0
- package/tests/isolation/specs/hosted_delegate_withdraw_evict_race.spec +145 -0
|
@@ -49,7 +49,8 @@ begin;
|
|
|
49
49
|
|
|
50
50
|
-- 88 at #276; #280 deletes 7 (EXEMPTION B1/B2/B3, the three RESIDUAL assertions, and a fourth
|
|
51
51
|
-- residual companion in section 10 that named only the slug) and adds 10 in section 11.
|
|
52
|
-
|
|
52
|
+
-- 92 with HOSTED (20261008000100): EXEMPTION E below licenses add_delegate_to_board.
|
|
53
|
+
select plan(92);
|
|
53
54
|
|
|
54
55
|
create function pg_temp.claims(p_sub text) returns void language plpgsql as $$
|
|
55
56
|
begin
|
|
@@ -566,10 +567,10 @@ select is(
|
|
|
566
567
|
and agent_board_test.stripped_body(p.oid)
|
|
567
568
|
~ agent_board_test.re(agent_board_test.call_frag('_assert_actor_not_fleet_revoked')
|
|
568
569
|
|| '|' || agent_board_test.call_frag('_actor_fleet_revoked'))),
|
|
569
|
-
'_redeem_unbounded_invite_for_agent,create_board,create_invite_link,grant_board_role,'
|
|
570
|
+
'_redeem_unbounded_invite_for_agent,add_delegate_to_board,create_board,create_invite_link,grant_board_role,'
|
|
570
571
|
|| 'set_board_authority_ceiling,set_board_claim_policy,set_board_role_gate',
|
|
571
|
-
'the functions that consult the fleet revocation ledger are exactly these
|
|
572
|
-
'create_board)');
|
|
572
|
+
'the functions that consult the fleet revocation ledger are exactly these eight (#280 added '
|
|
573
|
+
'create_board; HOSTED added add_delegate_to_board)');
|
|
573
574
|
|
|
574
575
|
-- The gate proper: the two sets must differ by EXACTLY the three asserted exemptions, and any
|
|
575
576
|
-- other member of the difference is NAMED in the failure. Each excluded name is licensed by a
|
|
@@ -593,6 +594,9 @@ select is(
|
|
|
593
594
|
-- the three asserted exemptions (create_board was the fourth until #280)...
|
|
594
595
|
'_upsert_board_membership_state',
|
|
595
596
|
'_fedsession_autojoin_default_board', 'bootstrap_board_owner_memberships',
|
|
597
|
+
-- ...HOSTED's add_delegate_to_board, which consults the ledger for the OWNER and
|
|
598
|
+
-- writes no authority relation itself (EXEMPTION E, positively, below)...
|
|
599
|
+
'add_delegate_to_board',
|
|
596
600
|
-- ...and the two helpers, which ARE the gate rather than users of it
|
|
597
601
|
'_assert_actor_not_fleet_revoked', '_actor_fleet_revoked')
|
|
598
602
|
and ((agent_board_test.stripped_body(p.oid) ~ agent_board_test.stmt_re('insert into', 'board_memberships')
|
|
@@ -688,7 +692,8 @@ select is(
|
|
|
688
692
|
where n.nspname = 'agent_board'
|
|
689
693
|
and p.proname <> '_upsert_board_membership_state'
|
|
690
694
|
and agent_board_test.stripped_body(p.oid) ~ agent_board_test.call_re('_upsert_board_membership_state')),
|
|
691
|
-
'
|
|
695
|
+
'add_delegate_to_board(p_agent_id uuid, p_board_id uuid)'
|
|
696
|
+
|| ' | invite_board_member(p_board_id uuid, p_agent_id uuid, p_created_by_agent_id uuid, p_metadata jsonb)'
|
|
692
697
|
|| ' | join_board(p_board_id uuid, p_agent_id uuid, p_membership_state text, p_created_by_agent_id uuid, p_metadata jsonb)'
|
|
693
698
|
|| ' | request_join_board(p_board_id uuid, p_agent_id uuid, p_metadata jsonb)'
|
|
694
699
|
|| ' | resolve_board_request(p_board_id uuid, p_agent_id uuid, p_membership_state text, p_created_by_agent_id uuid, p_metadata jsonb)'
|
|
@@ -726,6 +731,30 @@ select is(
|
|
|
726
731
|
'EXEMPTION D: bootstrap_board_owner_memberships takes NO arguments — it backfills the board '
|
|
727
732
|
'own recorded owner_agent_id and can name no other principal');
|
|
728
733
|
|
|
734
|
+
-- EXEMPTION E — add_delegate_to_board (HOSTED, 20261008000100). It is in the ledger-consult set
|
|
735
|
+
-- (the owner must not be fleet-revoked, IF-0-HOSTED-12) and NOT in the authority-writer set, so
|
|
736
|
+
-- the pairing assertion above excludes it by name. Licensed positively here: it consults the
|
|
737
|
+
-- ledger, it reaches board_memberships ONLY through the sink, it names no role, and it writes
|
|
738
|
+
-- no other authority relation in its own body. Each conjunct is reported, so a change names
|
|
739
|
+
-- which one moved.
|
|
740
|
+
select is(
|
|
741
|
+
(select string_agg(
|
|
742
|
+
'ledger=' || (b ~ agent_board_test.call_re('_assert_actor_not_fleet_revoked', false))::text
|
|
743
|
+
|| ' sink=' || (b ~ agent_board_test.call_re('_upsert_board_membership_state', false))::text
|
|
744
|
+
|| ' direct_membership_write=' || (b ~ agent_board_test.write_re('board_memberships'))::text
|
|
745
|
+
|| ' role_write=' || (b ~ agent_board_test.col_write_re('board_memberships', 'role'))::text
|
|
746
|
+
|| ' other_authority_write=' || (b ~ agent_board_test.stmt_re('insert into|update', 'board_authority_ceilings')
|
|
747
|
+
or b ~ agent_board_test.col_write_re('boards', 'role_gate_enforced')
|
|
748
|
+
or b ~ agent_board_test.col_write_re('boards', 'claim_policy')
|
|
749
|
+
or b ~ agent_board_test.stmt_re('insert into', 'board_invite_tokens'))::text,
|
|
750
|
+
' | ')
|
|
751
|
+
from (select agent_board_test.stripped_body(p.oid) as b
|
|
752
|
+
from pg_proc p join pg_namespace n on n.oid = p.pronamespace
|
|
753
|
+
where n.nspname = 'agent_board' and p.proname = 'add_delegate_to_board') x),
|
|
754
|
+
'ledger=true sink=true direct_membership_write=false role_write=false other_authority_write=false',
|
|
755
|
+
'EXEMPTION E: add_delegate_to_board consults the ledger and writes membership only through the '
|
|
756
|
+
'sink — no role, no other authority relation');
|
|
757
|
+
|
|
729
758
|
|
|
730
759
|
-- ===========================================================================
|
|
731
760
|
-- 10. G3 — THE INVITE ROUTE. An admin-preset link is a deferred grant of admin, so a
|
|
@@ -727,6 +727,9 @@ select is(
|
|
|
727
727
|
from agg
|
|
728
728
|
where locks_agents and locks_memberships),
|
|
729
729
|
array[
|
|
730
|
+
-- HOSTED (20261008000100): the fleet-ledger gate on the owner row-locks agents, and the sink
|
|
731
|
+
-- writes the delegate's membership. Serialised by the advisory lock, as grant_board_role is.
|
|
732
|
+
'add_delegate_to_board => serialised by the board advisory lock',
|
|
730
733
|
-- Joined this class in #276 (20260909000100). The fleet-ledger gate row-locks the actor's
|
|
731
734
|
-- agents row, so the live grant chokepoint -- and therefore every caller of it -- now locks
|
|
732
735
|
-- both relations. It takes the advisory lock rather than arguing from its ordering: this
|
|
@@ -427,10 +427,13 @@ select distinct p.oid,
|
|
|
427
427
|
-- 59 -> 60 with #521's agent_board.enroll_token_uses. Its only writer, _enroll_token_bind, is
|
|
428
428
|
-- EXECUTE-able by no API role and is reached only from the service_role-only
|
|
429
429
|
-- enroll_federated_identity, so it adds no member to the `authenticated` writer population.
|
|
430
|
+
-- 60 -> 62 with HOSTED's delegate_instances and delegate_allowed_operations (20261008000100).
|
|
431
|
+
-- Both are written only by service_role-only definers or the migration itself, so neither joins
|
|
432
|
+
-- the `authenticated` writer population below.
|
|
430
433
|
select is(
|
|
431
434
|
(select count(*)::text from _wec_target where relkind = 'r'),
|
|
432
|
-
'
|
|
433
|
-
'#325 canary: agent_board has
|
|
435
|
+
'62',
|
|
436
|
+
'#325 canary: agent_board has 62 base tables — the universe the write scan runs over, pinned so an empty violating set below cannot mean an empty universe');
|
|
434
437
|
|
|
435
438
|
-- WEC-2. The relations the class writes, as an EXACT SET. A new one names itself.
|
|
436
439
|
select is(
|
|
@@ -489,6 +492,8 @@ select is( -- pgtap-allow-raise-checked
|
|
|
489
492
|
array[
|
|
490
493
|
'agent_board.acquire_claim(uuid,text,text,timestamp with time zone,uuid,uuid,jsonb)',
|
|
491
494
|
'agent_board.add_artifact(uuid,text,text,text,uuid,uuid,uuid,uuid,jsonb)',
|
|
495
|
+
-- HOSTED (20261008000100): the owner places its hosted delegate through the sink.
|
|
496
|
+
'agent_board.add_delegate_to_board(uuid,uuid)',
|
|
492
497
|
'agent_board.append_task_event(uuid,uuid,text,jsonb,text,uuid,timestamp with time zone)',
|
|
493
498
|
'agent_board.block_board_inviter(uuid,uuid,uuid,jsonb)',
|
|
494
499
|
'agent_board.create_board(uuid,text,text,text,jsonb,text)',
|
|
@@ -548,7 +553,7 @@ select is( -- pgtap-allow-raise-checked
|
|
|
548
553
|
'agent_board.upsert_delegation_policy(uuid,text,jsonb,integer,interval,boolean)',
|
|
549
554
|
'agent_board.verify_callback_endpoint(uuid,uuid,jsonb)'
|
|
550
555
|
]::text[],
|
|
551
|
-
'#325: the effect-derived class is exactly these
|
|
556
|
+
'#325: the effect-derived class is exactly these 61 authenticated-executable writer OVERLOADS — per-OID, and TRANSITIVE, so a delegating wrapper whose own body holds no DML is a member rather than a blind spot');
|
|
552
557
|
|
|
553
558
|
-- WEC-4. THE DELEGATION-CHAIN LIVENESS PIN, and the mitigation for the fail-open inversion the
|
|
554
559
|
-- header describes. Everything above depends on `fn_call_closure()` actually resolving edges; a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "GENERATED by scripts/build-function-privileges-snapshot.mjs from pg_catalog — do not hand-edit. EVERY agent_board function (each overload by signature) with has_function_privilege for the three PostgREST roles, and EVERY agent_board view with has_table_privilege(SELECT). Derived with NO name filter. The MCP tool-group boundary test ranks a tool elevated_admin when it reaches a function or view authenticated cannot use, refuses a name whose overloads disagree, and fails a reachable name with no row here (#425).",
|
|
2
|
+
"$comment": "GENERATED by scripts/build-function-privileges-snapshot.mjs from pg_catalog — do not hand-edit. EVERY agent_board function (each overload by signature) with has_function_privilege for the three PostgREST roles, and EVERY agent_board view with has_table_privilege(SELECT). Derived with NO name filter. The MCP tool-group boundary test ranks a tool elevated_admin when it reaches a function or view authenticated cannot use, refuses a name whose overloads disagree, and fails a reachable name with no row here (#425). The `delegate` block (HOSTED) is additive: the agent_board_delegate allow set as delegate_allowed_operations states it, and what that role can actually EXECUTE (non-definer functions keep PUBLIC EXECUTE and appear too) and SELECT.",
|
|
3
3
|
"functions": [
|
|
4
4
|
{
|
|
5
5
|
"name": "_active_board_membership_id",
|
|
@@ -64,6 +64,15 @@
|
|
|
64
64
|
"authenticated": false
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
+
{
|
|
68
|
+
"name": "_agents_is_delegate_immutable",
|
|
69
|
+
"signature": "_agents_is_delegate_immutable()",
|
|
70
|
+
"executable_by": {
|
|
71
|
+
"anon": false,
|
|
72
|
+
"service_role": false,
|
|
73
|
+
"authenticated": false
|
|
74
|
+
}
|
|
75
|
+
},
|
|
67
76
|
{
|
|
68
77
|
"name": "_append_task_event",
|
|
69
78
|
"signature": "_append_task_event(p_origin_posture text, p_task_id uuid, p_actor_agent_id uuid, p_event_type text, p_payload jsonb, p_status text, p_assigned_agent_id uuid, p_completed_at timestamp with time zone)",
|
|
@@ -325,6 +334,51 @@
|
|
|
325
334
|
"authenticated": false
|
|
326
335
|
}
|
|
327
336
|
},
|
|
337
|
+
{
|
|
338
|
+
"name": "_delegate_instance_slug",
|
|
339
|
+
"signature": "_delegate_instance_slug(p_issuer text, p_instance_id text)",
|
|
340
|
+
"executable_by": {
|
|
341
|
+
"anon": false,
|
|
342
|
+
"service_role": false,
|
|
343
|
+
"authenticated": false
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"name": "_delegate_instances_owner_identity_immutable",
|
|
348
|
+
"signature": "_delegate_instances_owner_identity_immutable()",
|
|
349
|
+
"executable_by": {
|
|
350
|
+
"anon": false,
|
|
351
|
+
"service_role": false,
|
|
352
|
+
"authenticated": false
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"name": "_delegate_principal_agent_id",
|
|
357
|
+
"signature": "_delegate_principal_agent_id(p_agent_id uuid)",
|
|
358
|
+
"executable_by": {
|
|
359
|
+
"anon": false,
|
|
360
|
+
"service_role": false,
|
|
361
|
+
"authenticated": false
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"name": "_delegate_visible_agent",
|
|
366
|
+
"signature": "_delegate_visible_agent(p_agent_id uuid)",
|
|
367
|
+
"executable_by": {
|
|
368
|
+
"anon": false,
|
|
369
|
+
"service_role": false,
|
|
370
|
+
"authenticated": false
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"name": "_delegate_visible_board_ids",
|
|
375
|
+
"signature": "_delegate_visible_board_ids()",
|
|
376
|
+
"executable_by": {
|
|
377
|
+
"anon": false,
|
|
378
|
+
"service_role": false,
|
|
379
|
+
"authenticated": false
|
|
380
|
+
}
|
|
381
|
+
},
|
|
328
382
|
{
|
|
329
383
|
"name": "_emit_membership_event",
|
|
330
384
|
"signature": "_emit_membership_event(p_board_id uuid, p_agent_id uuid, p_membership_state text, p_event_kind text)",
|
|
@@ -658,6 +712,24 @@
|
|
|
658
712
|
"authenticated": false
|
|
659
713
|
}
|
|
660
714
|
},
|
|
715
|
+
{
|
|
716
|
+
"name": "_refuse_delegate_addressee",
|
|
717
|
+
"signature": "_refuse_delegate_addressee(p_agent_id uuid, p_board_id uuid, p_what text)",
|
|
718
|
+
"executable_by": {
|
|
719
|
+
"anon": false,
|
|
720
|
+
"service_role": false,
|
|
721
|
+
"authenticated": false
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"name": "_refuse_delegate_membership_target",
|
|
726
|
+
"signature": "_refuse_delegate_membership_target(p_agent_id uuid, p_operation text)",
|
|
727
|
+
"executable_by": {
|
|
728
|
+
"anon": false,
|
|
729
|
+
"service_role": false,
|
|
730
|
+
"authenticated": false
|
|
731
|
+
}
|
|
732
|
+
},
|
|
661
733
|
{
|
|
662
734
|
"name": "_require_platform_admin_user_id",
|
|
663
735
|
"signature": "_require_platform_admin_user_id()",
|
|
@@ -784,6 +856,15 @@
|
|
|
784
856
|
"authenticated": true
|
|
785
857
|
}
|
|
786
858
|
},
|
|
859
|
+
{
|
|
860
|
+
"name": "add_delegate_to_board",
|
|
861
|
+
"signature": "add_delegate_to_board(p_agent_id uuid, p_board_id uuid)",
|
|
862
|
+
"executable_by": {
|
|
863
|
+
"anon": false,
|
|
864
|
+
"service_role": false,
|
|
865
|
+
"authenticated": true
|
|
866
|
+
}
|
|
867
|
+
},
|
|
787
868
|
{
|
|
788
869
|
"name": "agent_liveness_summary",
|
|
789
870
|
"signature": "agent_liveness_summary()",
|
|
@@ -991,6 +1072,15 @@
|
|
|
991
1072
|
"authenticated": false
|
|
992
1073
|
}
|
|
993
1074
|
},
|
|
1075
|
+
{
|
|
1076
|
+
"name": "exchange_delegate_credential",
|
|
1077
|
+
"signature": "exchange_delegate_credential(p_claims jsonb)",
|
|
1078
|
+
"executable_by": {
|
|
1079
|
+
"anon": false,
|
|
1080
|
+
"service_role": true,
|
|
1081
|
+
"authenticated": false
|
|
1082
|
+
}
|
|
1083
|
+
},
|
|
994
1084
|
{
|
|
995
1085
|
"name": "expand_recipients_dry_run",
|
|
996
1086
|
"signature": "expand_recipients_dry_run(p_actor_agent_id uuid, p_recipient_descriptors jsonb, p_thread_idempotency_key text)",
|
|
@@ -1675,6 +1765,15 @@
|
|
|
1675
1765
|
"authenticated": true
|
|
1676
1766
|
}
|
|
1677
1767
|
},
|
|
1768
|
+
{
|
|
1769
|
+
"name": "tombstone_delegate_instance",
|
|
1770
|
+
"signature": "tombstone_delegate_instance(p_instance_id text, p_issuer text, p_owner_sub text, p_reason text)",
|
|
1771
|
+
"executable_by": {
|
|
1772
|
+
"anon": false,
|
|
1773
|
+
"service_role": true,
|
|
1774
|
+
"authenticated": false
|
|
1775
|
+
}
|
|
1776
|
+
},
|
|
1678
1777
|
{
|
|
1679
1778
|
"name": "unblock_board_inviter",
|
|
1680
1779
|
"signature": "unblock_board_inviter(p_board_id uuid, p_inviter_agent_id uuid, p_target_agent_id uuid)",
|
|
@@ -1955,5 +2054,173 @@
|
|
|
1955
2054
|
"authenticated": true
|
|
1956
2055
|
}
|
|
1957
2056
|
}
|
|
1958
|
-
]
|
|
2057
|
+
],
|
|
2058
|
+
"delegate": {
|
|
2059
|
+
"role": "agent_board_delegate",
|
|
2060
|
+
"allowed_operations": [
|
|
2061
|
+
{
|
|
2062
|
+
"kind": "ambient_rpc",
|
|
2063
|
+
"name": "get_schema_version",
|
|
2064
|
+
"signature": "get_schema_version()"
|
|
2065
|
+
},
|
|
2066
|
+
{
|
|
2067
|
+
"kind": "predicate",
|
|
2068
|
+
"name": "_delegate_visible_agent",
|
|
2069
|
+
"signature": "_delegate_visible_agent(uuid)"
|
|
2070
|
+
},
|
|
2071
|
+
{
|
|
2072
|
+
"kind": "predicate",
|
|
2073
|
+
"name": "_delegate_visible_board_ids",
|
|
2074
|
+
"signature": "_delegate_visible_board_ids()"
|
|
2075
|
+
},
|
|
2076
|
+
{
|
|
2077
|
+
"kind": "predicate",
|
|
2078
|
+
"name": "current_agent_id",
|
|
2079
|
+
"signature": "current_agent_id()"
|
|
2080
|
+
},
|
|
2081
|
+
{
|
|
2082
|
+
"kind": "read_table",
|
|
2083
|
+
"name": "agent_signing_keys",
|
|
2084
|
+
"signature": "agent_signing_keys"
|
|
2085
|
+
},
|
|
2086
|
+
{
|
|
2087
|
+
"kind": "read_table",
|
|
2088
|
+
"name": "agents",
|
|
2089
|
+
"signature": "agents"
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
"kind": "read_table",
|
|
2093
|
+
"name": "board_memberships",
|
|
2094
|
+
"signature": "board_memberships"
|
|
2095
|
+
},
|
|
2096
|
+
{
|
|
2097
|
+
"kind": "read_table",
|
|
2098
|
+
"name": "boards",
|
|
2099
|
+
"signature": "boards"
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
"kind": "read_table",
|
|
2103
|
+
"name": "claims",
|
|
2104
|
+
"signature": "claims"
|
|
2105
|
+
},
|
|
2106
|
+
{
|
|
2107
|
+
"kind": "read_table",
|
|
2108
|
+
"name": "delivery_recipients",
|
|
2109
|
+
"signature": "delivery_recipients"
|
|
2110
|
+
},
|
|
2111
|
+
{
|
|
2112
|
+
"kind": "read_table",
|
|
2113
|
+
"name": "escalations",
|
|
2114
|
+
"signature": "escalations"
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
"kind": "read_table",
|
|
2118
|
+
"name": "inbox_items",
|
|
2119
|
+
"signature": "inbox_items"
|
|
2120
|
+
},
|
|
2121
|
+
{
|
|
2122
|
+
"kind": "read_table",
|
|
2123
|
+
"name": "messages",
|
|
2124
|
+
"signature": "messages"
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
"kind": "read_table",
|
|
2128
|
+
"name": "presence",
|
|
2129
|
+
"signature": "presence"
|
|
2130
|
+
},
|
|
2131
|
+
{
|
|
2132
|
+
"kind": "read_table",
|
|
2133
|
+
"name": "signature_evidence",
|
|
2134
|
+
"signature": "signature_evidence"
|
|
2135
|
+
},
|
|
2136
|
+
{
|
|
2137
|
+
"kind": "read_table",
|
|
2138
|
+
"name": "task_events",
|
|
2139
|
+
"signature": "task_events"
|
|
2140
|
+
},
|
|
2141
|
+
{
|
|
2142
|
+
"kind": "read_table",
|
|
2143
|
+
"name": "tasks",
|
|
2144
|
+
"signature": "tasks"
|
|
2145
|
+
},
|
|
2146
|
+
{
|
|
2147
|
+
"kind": "read_view",
|
|
2148
|
+
"name": "v_agent_dashboard",
|
|
2149
|
+
"signature": "v_agent_dashboard"
|
|
2150
|
+
},
|
|
2151
|
+
{
|
|
2152
|
+
"kind": "read_view",
|
|
2153
|
+
"name": "v_agent_inbox",
|
|
2154
|
+
"signature": "v_agent_inbox"
|
|
2155
|
+
},
|
|
2156
|
+
{
|
|
2157
|
+
"kind": "read_view",
|
|
2158
|
+
"name": "v_board_feed",
|
|
2159
|
+
"signature": "v_board_feed"
|
|
2160
|
+
},
|
|
2161
|
+
{
|
|
2162
|
+
"kind": "read_view",
|
|
2163
|
+
"name": "v_board_memberships",
|
|
2164
|
+
"signature": "v_board_memberships"
|
|
2165
|
+
},
|
|
2166
|
+
{
|
|
2167
|
+
"kind": "read_view",
|
|
2168
|
+
"name": "v_thread_feed",
|
|
2169
|
+
"signature": "v_thread_feed"
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
"kind": "rpc",
|
|
2173
|
+
"name": "create_or_find_thread",
|
|
2174
|
+
"signature": "create_or_find_thread(uuid, text, text, text, jsonb)"
|
|
2175
|
+
},
|
|
2176
|
+
{
|
|
2177
|
+
"kind": "rpc",
|
|
2178
|
+
"name": "post_board_message",
|
|
2179
|
+
"signature": "post_board_message(uuid, uuid, text, text, text, text, text, text, text, jsonb)"
|
|
2180
|
+
},
|
|
2181
|
+
{
|
|
2182
|
+
"kind": "rpc",
|
|
2183
|
+
"name": "post_board_message",
|
|
2184
|
+
"signature": "post_board_message(uuid, uuid, uuid, text, text, text, text, text, jsonb)"
|
|
2185
|
+
},
|
|
2186
|
+
{
|
|
2187
|
+
"kind": "rpc",
|
|
2188
|
+
"name": "post_message",
|
|
2189
|
+
"signature": "post_message(uuid, uuid, text, text, uuid, jsonb)"
|
|
2190
|
+
}
|
|
2191
|
+
],
|
|
2192
|
+
"executable_functions": [
|
|
2193
|
+
"_addressing_descriptors_array(p_descriptors jsonb)",
|
|
2194
|
+
"_board_membership_events_provenance_guard()",
|
|
2195
|
+
"_delegate_visible_agent(p_agent_id uuid)",
|
|
2196
|
+
"_delegate_visible_board_ids()",
|
|
2197
|
+
"create_or_find_thread(p_created_by_agent_id uuid, p_subject text, p_idempotency_key text, p_thread_type text, p_metadata jsonb)",
|
|
2198
|
+
"current_agent_id()",
|
|
2199
|
+
"get_schema_version()",
|
|
2200
|
+
"post_board_message(p_thread_id uuid, p_author_agent_id uuid, p_board_id uuid, p_subject text, p_body text, p_message_type text, p_priority text, p_idempotency_key text, p_metadata jsonb)",
|
|
2201
|
+
"post_board_message(p_thread_id uuid, p_author_agent_id uuid, p_board_slug text, p_addressing_mode text, p_subject text, p_body text, p_message_type text, p_priority text, p_idempotency_key text, p_metadata jsonb)",
|
|
2202
|
+
"post_message(p_thread_id uuid, p_author_agent_id uuid, p_body text, p_message_type text, p_task_id uuid, p_metadata jsonb)",
|
|
2203
|
+
"sync_agent_principal_columns()"
|
|
2204
|
+
],
|
|
2205
|
+
"selectable_relations": [
|
|
2206
|
+
"agent_signing_keys",
|
|
2207
|
+
"agents",
|
|
2208
|
+
"board_memberships",
|
|
2209
|
+
"boards",
|
|
2210
|
+
"claims",
|
|
2211
|
+
"delivery_recipients",
|
|
2212
|
+
"escalations",
|
|
2213
|
+
"inbox_items",
|
|
2214
|
+
"messages",
|
|
2215
|
+
"presence",
|
|
2216
|
+
"signature_evidence",
|
|
2217
|
+
"task_events",
|
|
2218
|
+
"tasks",
|
|
2219
|
+
"v_agent_dashboard",
|
|
2220
|
+
"v_agent_inbox",
|
|
2221
|
+
"v_board_feed",
|
|
2222
|
+
"v_board_memberships",
|
|
2223
|
+
"v_thread_feed"
|
|
2224
|
+
]
|
|
2225
|
+
}
|
|
1959
2226
|
}
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"signature": "_agent_principal_active(p_agent_id uuid)",
|
|
30
30
|
"declares_p_metadata": false
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
"signature": "_agents_is_delegate_immutable()",
|
|
34
|
+
"declares_p_metadata": false
|
|
35
|
+
},
|
|
32
36
|
{
|
|
33
37
|
"signature": "_append_task_event(p_origin_posture text, p_task_id uuid, p_actor_agent_id uuid, p_event_type text, p_payload jsonb, p_status text, p_assigned_agent_id uuid, p_completed_at timestamp with time zone)",
|
|
34
38
|
"declares_p_metadata": false
|
|
@@ -145,6 +149,26 @@
|
|
|
145
149
|
"signature": "_default_provision_display_name(p_slug text)",
|
|
146
150
|
"declares_p_metadata": false
|
|
147
151
|
},
|
|
152
|
+
{
|
|
153
|
+
"signature": "_delegate_instance_slug(p_issuer text, p_instance_id text)",
|
|
154
|
+
"declares_p_metadata": false
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"signature": "_delegate_instances_owner_identity_immutable()",
|
|
158
|
+
"declares_p_metadata": false
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"signature": "_delegate_principal_agent_id(p_agent_id uuid)",
|
|
162
|
+
"declares_p_metadata": false
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"signature": "_delegate_visible_agent(p_agent_id uuid)",
|
|
166
|
+
"declares_p_metadata": false
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"signature": "_delegate_visible_board_ids()",
|
|
170
|
+
"declares_p_metadata": false
|
|
171
|
+
},
|
|
148
172
|
{
|
|
149
173
|
"signature": "_emit_membership_event(p_board_id uuid, p_agent_id uuid, p_membership_state text, p_event_kind text)",
|
|
150
174
|
"declares_p_metadata": false
|
|
@@ -293,6 +317,14 @@
|
|
|
293
317
|
"signature": "_redeem_unbounded_invite_for_agent(p_code text, p_agent_id uuid)",
|
|
294
318
|
"declares_p_metadata": false
|
|
295
319
|
},
|
|
320
|
+
{
|
|
321
|
+
"signature": "_refuse_delegate_addressee(p_agent_id uuid, p_board_id uuid, p_what text)",
|
|
322
|
+
"declares_p_metadata": false
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"signature": "_refuse_delegate_membership_target(p_agent_id uuid, p_operation text)",
|
|
326
|
+
"declares_p_metadata": false
|
|
327
|
+
},
|
|
296
328
|
{
|
|
297
329
|
"signature": "_require_platform_admin_user_id()",
|
|
298
330
|
"declares_p_metadata": false
|
|
@@ -349,6 +381,10 @@
|
|
|
349
381
|
"signature": "add_artifact(p_created_by_agent_id uuid, p_uri text, p_artifact_type text, p_storage_kind text, p_thread_id uuid, p_task_id uuid, p_message_id uuid, p_task_event_id uuid, p_metadata jsonb)",
|
|
350
382
|
"declares_p_metadata": true
|
|
351
383
|
},
|
|
384
|
+
{
|
|
385
|
+
"signature": "add_delegate_to_board(p_agent_id uuid, p_board_id uuid)",
|
|
386
|
+
"declares_p_metadata": false
|
|
387
|
+
},
|
|
352
388
|
{
|
|
353
389
|
"signature": "agent_liveness_summary()",
|
|
354
390
|
"declares_p_metadata": false
|
|
@@ -441,6 +477,10 @@
|
|
|
441
477
|
"signature": "evaluate_signed_write_fleet_policy(p_operation text, p_payload jsonb, p_gateway_decision jsonb)",
|
|
442
478
|
"declares_p_metadata": false
|
|
443
479
|
},
|
|
480
|
+
{
|
|
481
|
+
"signature": "exchange_delegate_credential(p_claims jsonb)",
|
|
482
|
+
"declares_p_metadata": false
|
|
483
|
+
},
|
|
444
484
|
{
|
|
445
485
|
"signature": "expand_recipients_dry_run(p_actor_agent_id uuid, p_recipient_descriptors jsonb, p_thread_idempotency_key text)",
|
|
446
486
|
"declares_p_metadata": false
|
|
@@ -745,6 +785,10 @@
|
|
|
745
785
|
"signature": "sync_agent_principal_columns()",
|
|
746
786
|
"declares_p_metadata": false
|
|
747
787
|
},
|
|
788
|
+
{
|
|
789
|
+
"signature": "tombstone_delegate_instance(p_instance_id text, p_issuer text, p_owner_sub text, p_reason text)",
|
|
790
|
+
"declares_p_metadata": false
|
|
791
|
+
},
|
|
748
792
|
{
|
|
749
793
|
"signature": "unblock_board_inviter(p_board_id uuid, p_inviter_agent_id uuid, p_target_agent_id uuid)",
|
|
750
794
|
"declares_p_metadata": false
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Parsed test spec with 3 sessions
|
|
2
|
+
|
|
3
|
+
starting permutation: o_begin o_add t_begin t_tomb o_commit t_commit check
|
|
4
|
+
step o_begin:
|
|
5
|
+
BEGIN;
|
|
6
|
+
select set_config('request.jwt.claims', json_build_object('role', 'authenticated', 'sub',
|
|
7
|
+
(select auth_user_id from agent_board.agents
|
|
8
|
+
where handle = agent_board._federated_identity_slug('https://iso-at.test', 'iso-at-owner')))::text, true) is not null as owner_session;
|
|
9
|
+
|
|
10
|
+
owner_session
|
|
11
|
+
-------------
|
|
12
|
+
t
|
|
13
|
+
(1 row)
|
|
14
|
+
|
|
15
|
+
step o_add:
|
|
16
|
+
select membership_state from agent_board.add_delegate_to_board(
|
|
17
|
+
(select agent_id from agent_board.delegate_instances where instance_id = 'iso_at_instance_00001'),
|
|
18
|
+
'16591300-0000-4000-8000-000000000001');
|
|
19
|
+
|
|
20
|
+
membership_state
|
|
21
|
+
----------------
|
|
22
|
+
joined
|
|
23
|
+
(1 row)
|
|
24
|
+
|
|
25
|
+
step t_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
26
|
+
step t_tomb:
|
|
27
|
+
select first from agent_board.tombstone_delegate_instance(
|
|
28
|
+
'iso_at_instance_00001', 'https://iso-at.test', 'iso-at-owner', 'owner_revoked');
|
|
29
|
+
<waiting ...>
|
|
30
|
+
step o_commit: COMMIT;
|
|
31
|
+
step t_tomb: <... completed>
|
|
32
|
+
first
|
|
33
|
+
-----
|
|
34
|
+
t
|
|
35
|
+
(1 row)
|
|
36
|
+
|
|
37
|
+
step t_commit: COMMIT;
|
|
38
|
+
step check:
|
|
39
|
+
select (select (di.tombstoned_at is not null)::text from agent_board.delegate_instances di
|
|
40
|
+
where di.instance_id = 'iso_at_instance_00001') as tombstoned,
|
|
41
|
+
(select a.status from agent_board.agents a
|
|
42
|
+
join agent_board.delegate_instances di on di.agent_id = a.id
|
|
43
|
+
where di.instance_id = 'iso_at_instance_00001') as delegate_status,
|
|
44
|
+
(select string_agg(bm.membership_state, ',' order by bm.created_at, bm.id) from agent_board.board_memberships bm
|
|
45
|
+
join agent_board.delegate_instances di on di.agent_id = bm.agent_id
|
|
46
|
+
where di.instance_id = 'iso_at_instance_00001') as delegate_memberships,
|
|
47
|
+
(select count(*) from agent_board.board_memberships bm
|
|
48
|
+
join agent_board.delegate_instances di on di.agent_id = bm.agent_id
|
|
49
|
+
where di.tombstoned_at is not null and bm.membership_state in ('joined', 'subscribed')) as tombstoned_and_active;
|
|
50
|
+
|
|
51
|
+
tombstoned|delegate_status|delegate_memberships|tombstoned_and_active
|
|
52
|
+
----------+---------------+--------------------+---------------------
|
|
53
|
+
true |revoked |left | 0
|
|
54
|
+
(1 row)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
starting permutation: t_begin t_tomb o_begin o_add t_commit o_commit check
|
|
58
|
+
step t_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
59
|
+
step t_tomb:
|
|
60
|
+
select first from agent_board.tombstone_delegate_instance(
|
|
61
|
+
'iso_at_instance_00001', 'https://iso-at.test', 'iso-at-owner', 'owner_revoked');
|
|
62
|
+
|
|
63
|
+
first
|
|
64
|
+
-----
|
|
65
|
+
t
|
|
66
|
+
(1 row)
|
|
67
|
+
|
|
68
|
+
step o_begin:
|
|
69
|
+
BEGIN;
|
|
70
|
+
select set_config('request.jwt.claims', json_build_object('role', 'authenticated', 'sub',
|
|
71
|
+
(select auth_user_id from agent_board.agents
|
|
72
|
+
where handle = agent_board._federated_identity_slug('https://iso-at.test', 'iso-at-owner')))::text, true) is not null as owner_session;
|
|
73
|
+
|
|
74
|
+
owner_session
|
|
75
|
+
-------------
|
|
76
|
+
t
|
|
77
|
+
(1 row)
|
|
78
|
+
|
|
79
|
+
step o_add:
|
|
80
|
+
select membership_state from agent_board.add_delegate_to_board(
|
|
81
|
+
(select agent_id from agent_board.delegate_instances where instance_id = 'iso_at_instance_00001'),
|
|
82
|
+
'16591300-0000-4000-8000-000000000001');
|
|
83
|
+
<waiting ...>
|
|
84
|
+
step t_commit: COMMIT;
|
|
85
|
+
step o_add: <... completed>
|
|
86
|
+
ERROR: the hosted delegate instance is not live
|
|
87
|
+
step o_commit: COMMIT;
|
|
88
|
+
step check:
|
|
89
|
+
select (select (di.tombstoned_at is not null)::text from agent_board.delegate_instances di
|
|
90
|
+
where di.instance_id = 'iso_at_instance_00001') as tombstoned,
|
|
91
|
+
(select a.status from agent_board.agents a
|
|
92
|
+
join agent_board.delegate_instances di on di.agent_id = a.id
|
|
93
|
+
where di.instance_id = 'iso_at_instance_00001') as delegate_status,
|
|
94
|
+
(select string_agg(bm.membership_state, ',' order by bm.created_at, bm.id) from agent_board.board_memberships bm
|
|
95
|
+
join agent_board.delegate_instances di on di.agent_id = bm.agent_id
|
|
96
|
+
where di.instance_id = 'iso_at_instance_00001') as delegate_memberships,
|
|
97
|
+
(select count(*) from agent_board.board_memberships bm
|
|
98
|
+
join agent_board.delegate_instances di on di.agent_id = bm.agent_id
|
|
99
|
+
where di.tombstoned_at is not null and bm.membership_state in ('joined', 'subscribed')) as tombstoned_and_active;
|
|
100
|
+
|
|
101
|
+
tombstoned|delegate_status|delegate_memberships|tombstoned_and_active
|
|
102
|
+
----------+---------------+--------------------+---------------------
|
|
103
|
+
true |revoked | | 0
|
|
104
|
+
(1 row)
|
|
105
|
+
|