@consiliency/agent-board-schema 1.12.0 → 1.23.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 (156) hide show
  1. package/fixtures/already-applied.json +160 -0
  2. package/migrations/20260731000100_agent_board_agentsdir_column_scope.sql +88 -0
  3. package/migrations/20260801000100_agent_board_leaveidem_terminal_noop.sql +317 -0
  4. package/migrations/20260802000100_agent_board_rolereset_reentry_clamp.sql +237 -0
  5. package/migrations/20260803000100_agent_board_rowid_total_order.sql +1201 -0
  6. package/migrations/20260804000100_agent_board_hygiene_actor_binding_rls.sql +229 -0
  7. package/migrations/20260806000100_agent_board_consent_substrate.sql +339 -0
  8. package/migrations/20260807000100_agent_board_consent_emission.sql +619 -0
  9. package/migrations/20260808000100_agent_board_rejectsem.sql +145 -0
  10. package/migrations/20260809000100_agent_board_consent_gating.sql +492 -0
  11. package/migrations/20260810000100_agent_board_consent_locking.sql +485 -0
  12. package/migrations/20260811000100_agent_board_retention_metadata_revoke.sql +23 -0
  13. package/migrations/20260812000100_agent_board_pubexec_class_revoke.sql +54 -0
  14. package/migrations/20260813000100_agent_board_invitepolicy_block.sql +420 -0
  15. package/migrations/20260814000100_agent_board_obsgate_thread_post_policy.sql +239 -0
  16. package/migrations/20260815000100_agent_board_obsgate2_authoring_gates.sql +287 -0
  17. package/migrations/20260816000100_agent_board_obsgate3_task_lifecycle.sql +118 -0
  18. package/migrations/20260817000100_agent_board_obsgate4_claims_lifecycle.sql +250 -0
  19. package/migrations/20260818000100_agent_board_fleet_machines_rls_correlation.sql +43 -0
  20. package/migrations/20260819000100_agent_board_resolve_noop_retire.sql +166 -0
  21. package/migrations/20260820000100_agent_board_roomdeleg_lane_b.sql +206 -0
  22. package/migrations/20260821000100_agent_board_claimgate_claimkey.sql +372 -0
  23. package/migrations/20260822000100_agent_board_mint_harden.sql +710 -0
  24. package/migrations/20260822000200_agent_board_mint_harden_fingerprint_backfill.sql +207 -0
  25. package/migrations/20260823000100_agent_board_fleet_machine_hijack.sql +106 -0
  26. package/migrations/20260824000100_agent_board_claimgate_shadow.sql +443 -0
  27. package/migrations/20260825000100_agent_board_claimgate_enforce.sql +660 -0
  28. package/migrations/20260826000100_agent_board_fleet_machine_reactivation.sql +514 -0
  29. package/migrations/20260828000100_agent_board_delegation_cap_ceiling.sql +474 -0
  30. package/migrations/20260829000100_agent_board_fleet_machine_reclaim.sql +432 -0
  31. package/migrations/20260830000100_agent_board_delegation_sole_writer.sql +41 -0
  32. package/migrations/20260831000100_agent_board_fleet_domain_reclaim.sql +389 -0
  33. package/migrations/20260901000100_agent_board_atomic_fleet_onboarding.sql +1496 -0
  34. package/migrations/20260901000110_agent_board_fleet_onboarding_ceiling_lock.sql +604 -0
  35. package/migrations/20260901000120_agent_board_human_revocation_evidence_completeness.sql +78 -0
  36. package/migrations/20260901000130_agent_board_fedsession_human_revocation_gate.sql +74 -0
  37. package/migrations/20260901000140_agent_board_fedsession_board_owner_lock_order.sql +102 -0
  38. package/migrations/20260902000100_agent_board_outbox_wake_ordering.sql +184 -0
  39. package/migrations/20260903000100_agent_board_enroll_identity_board_owner_lock_order.sql +604 -0
  40. package/migrations/20260903000200_agent_board_fedsession_provider_absence_gate.sql +177 -0
  41. package/migrations/20260904000100_agent_board_wake_recovery_surface.sql +155 -0
  42. package/package.json +1 -1
  43. package/schema-manifest.json +363 -3
  44. package/src/tooling.test.mjs +113 -2
  45. package/tests/agent_board_actorspoof.test.sql +349 -0
  46. package/tests/agent_board_agentsdir.test.sql +154 -0
  47. package/tests/agent_board_atomic_fleet_onboarding.test.sql +623 -0
  48. package/tests/agent_board_atomic_fleet_onboarding_backfill.test.sql +142 -0
  49. package/tests/agent_board_atomic_fleet_onboarding_runtime.test.sql +1250 -0
  50. package/tests/agent_board_authbound_boundary.test.sql +9 -1
  51. package/tests/agent_board_claimgate_enforce.test.sql +464 -0
  52. package/tests/agent_board_claimgate_predicate.test.sql +360 -0
  53. package/tests/agent_board_claimkey.test.sql +229 -0
  54. package/tests/agent_board_consent_backfill.test.sql +48 -0
  55. package/tests/agent_board_consent_emission.test.sql +601 -0
  56. package/tests/agent_board_consent_gating.test.sql +489 -0
  57. package/tests/agent_board_consent_substrate.test.sql +720 -0
  58. package/tests/agent_board_delegation_cap_ceiling.test.sql +303 -0
  59. package/tests/agent_board_delegation_enforcement.test.sql +55 -6
  60. package/tests/agent_board_delegation_policies.test.sql +107 -1
  61. package/tests/agent_board_enroll_federated_identity.test.sql +3 -3
  62. package/tests/agent_board_enroll_pop_binding.test.sql +13 -3
  63. package/tests/agent_board_enrollment_audit_content.test.sql +11 -7
  64. package/tests/agent_board_federated_lock_order_class.test.sql +390 -0
  65. package/tests/agent_board_fedsession.test.sql +51 -5
  66. package/tests/agent_board_fedsession_provider_absence_gate.test.sql +170 -0
  67. package/tests/agent_board_fleet_domain_reclaim.test.sql +419 -0
  68. package/tests/agent_board_fleet_machine_hijack.test.sql +190 -0
  69. package/tests/agent_board_fleet_machine_reactivation.test.sql +426 -0
  70. package/tests/agent_board_fleet_machine_reclaim.test.sql +509 -0
  71. package/tests/agent_board_fleet_machines_rls.test.sql +79 -0
  72. package/tests/agent_board_fleet_policy.test.sql +2 -2
  73. package/tests/agent_board_grants_hygiene.test.sql +408 -0
  74. package/tests/agent_board_identity_providers.test.sql +9 -0
  75. package/tests/agent_board_inbox_reads.test.sql +45 -31
  76. package/tests/agent_board_inbox_rpcs.test.sql +44 -34
  77. package/tests/agent_board_invitepolicy.test.sql +205 -0
  78. package/tests/agent_board_leaveidem.test.sql +194 -0
  79. package/tests/agent_board_mint_fleet_agent_session.test.sql +10 -10
  80. package/tests/agent_board_mint_harden.test.sql +303 -0
  81. package/tests/agent_board_mint_harden_backfill.test.sql +95 -0
  82. package/tests/agent_board_obsgate.test.sql +178 -0
  83. package/tests/agent_board_obsgate2.test.sql +153 -0
  84. package/tests/agent_board_obsgate3.test.sql +170 -0
  85. package/tests/agent_board_obsgate4.test.sql +196 -0
  86. package/tests/agent_board_outbox_wake_ordering.test.sql +452 -0
  87. package/tests/agent_board_portal_offline_invariant.test.sql +14 -3
  88. package/tests/agent_board_pubexec_class.test.sql +53 -0
  89. package/tests/agent_board_rejectsem.test.sql +271 -0
  90. package/tests/agent_board_resigning_refresh.test.sql +1 -1
  91. package/tests/agent_board_resolve_noop_retire.test.sql +71 -0
  92. package/tests/agent_board_retention_metadata_acl.test.sql +53 -0
  93. package/tests/agent_board_revoke_agent_subtree.test.sql +3 -3
  94. package/tests/agent_board_rolereset.test.sql +351 -0
  95. package/tests/agent_board_roomdeleg.test.sql +5 -3
  96. package/tests/agent_board_roomdeleg_lane_b.test.sql +144 -0
  97. package/tests/agent_board_roomlink.test.sql +27 -11
  98. package/tests/agent_board_rowid.test.sql +1274 -0
  99. package/tests/agent_board_signature_rls_reads.test.sql +3 -3
  100. package/tests/agent_board_signed_write_gateway.test.sql +3 -3
  101. package/tests/agent_board_signing_challenge_pending_cap.test.sql +2 -2
  102. package/tests/agent_board_signing_challenge_reaper.test.sql +2 -2
  103. package/tests/agent_board_signing_proof_rpcs.test.sql +4 -4
  104. package/tests/agent_board_signing_store.test.sql +6 -6
  105. package/tests/agent_board_wake_recovery.test.sql +756 -0
  106. package/tests/fixtures/isolation-substrate.sql +93 -0
  107. package/tests/fixtures/test-prereqs.sql +33 -0
  108. package/tests/isolation/expected/atomic_fedsession_fleet_lock_order.out +79 -0
  109. package/tests/isolation/expected/atomic_fedsession_human_revoke.out +87 -0
  110. package/tests/isolation/expected/atomic_fleet_authority_races.out +469 -0
  111. package/tests/isolation/expected/atomic_fleet_binding_revoke.out +103 -0
  112. package/tests/isolation/expected/atomic_fleet_board_archive.out +117 -0
  113. package/tests/isolation/expected/atomic_fleet_human_fresh_revoke.out +136 -0
  114. package/tests/isolation/expected/atomic_fleet_identity_disposition.out +61 -0
  115. package/tests/isolation/expected/atomic_fleet_lifecycle_races.out +1479 -0
  116. package/tests/isolation/expected/atomic_fleet_onboarding.out +75 -0
  117. package/tests/isolation/expected/atomic_fleet_subtree_lock_order.out +60 -0
  118. package/tests/isolation/expected/ceiling_setter_lock_before_upsert.out +95 -0
  119. package/tests/isolation/expected/claimgate_ownerless_quota.out +36 -0
  120. package/tests/isolation/expected/claimkey_renew_race.out +38 -0
  121. package/tests/isolation/expected/consent_approval_lock.out +43 -0
  122. package/tests/isolation/expected/consent_emit_actual_state.out +37 -0
  123. package/tests/isolation/expected/domain_reclaim_revoke_race.out +40 -0
  124. package/tests/isolation/expected/enroll_identity_board_owner_lock_order.out +55 -0
  125. package/tests/isolation/expected/fedsession_provider_absent_owner_lock.out +37 -0
  126. package/tests/isolation/expected/onboarding_ceiling_lock_order.out +123 -0
  127. package/tests/isolation/expected/outbox_wake_ordering.out +86 -0
  128. package/tests/isolation/expected/reactivate_revoke_race.out +80 -0
  129. package/tests/isolation/expected/reclaim_revoke_race.out +40 -0
  130. package/tests/isolation/expected/wake_recovery_late_commit.out +89 -0
  131. package/tests/isolation/specs/atomic_fedsession_fleet_lock_order.spec +117 -0
  132. package/tests/isolation/specs/atomic_fedsession_human_revoke.spec +66 -0
  133. package/tests/isolation/specs/atomic_fleet_authority_races.spec +235 -0
  134. package/tests/isolation/specs/atomic_fleet_binding_revoke.spec +127 -0
  135. package/tests/isolation/specs/atomic_fleet_board_archive.spec +134 -0
  136. package/tests/isolation/specs/atomic_fleet_human_fresh_revoke.spec +142 -0
  137. package/tests/isolation/specs/atomic_fleet_identity_disposition.spec +118 -0
  138. package/tests/isolation/specs/atomic_fleet_lifecycle_races.spec +244 -0
  139. package/tests/isolation/specs/atomic_fleet_onboarding.spec +106 -0
  140. package/tests/isolation/specs/atomic_fleet_subtree_lock_order.spec +147 -0
  141. package/tests/isolation/specs/ceiling_setter_lock_before_upsert.spec +117 -0
  142. package/tests/isolation/specs/claimgate_ownerless_quota.spec +77 -0
  143. package/tests/isolation/specs/claimkey_renew_race.spec +67 -0
  144. package/tests/isolation/specs/consent_approval_lock.spec +98 -0
  145. package/tests/isolation/specs/consent_emit_actual_state.spec +79 -0
  146. package/tests/isolation/specs/domain_reclaim_revoke_race.spec +88 -0
  147. package/tests/isolation/specs/enroll_identity_board_owner_lock_order.spec +117 -0
  148. package/tests/isolation/specs/fedsession_provider_absent_owner_lock.spec +63 -0
  149. package/tests/isolation/specs/onboarding_ceiling_lock_order.spec +183 -0
  150. package/tests/isolation/specs/outbox_wake_ordering.spec +202 -0
  151. package/tests/isolation/specs/reactivate_revoke_race.spec +115 -0
  152. package/tests/isolation/specs/reclaim_revoke_race.spec +94 -0
  153. package/tests/isolation/specs/wake_recovery_late_commit.spec +207 -0
  154. package/tests/seeds/20260806000100_agent_board_consent_substrate.sql.pre.sql +19 -0
  155. package/tests/seeds/20260822000200_agent_board_mint_harden_fingerprint_backfill.sql.pre.sql +39 -0
  156. package/tests/seeds/20260901000100_agent_board_atomic_fleet_onboarding.sql.pre.sql +110 -0
@@ -0,0 +1,93 @@
1
+ -- Minimal Supabase substrate for the two-session ISOLATION harness only.
2
+ --
3
+ -- The pgTAP runner applies the agent_board bundle onto the DB that `supabase
4
+ -- start` provisions (54322/postgres), which already carries GoTrue's `auth`
5
+ -- schema, the `extensions` schema, pgcrypto, and the base roles. The isolation
6
+ -- harness instead builds a THROWAWAY template database (specs COMMIT across
7
+ -- sessions and cannot share the live DB), so it must self-provision the same
8
+ -- substrate the migrations assume.
9
+ --
10
+ -- Rather than replay GoTrue's full ~2000-line schema (webauthn/saml/oauth/mfa +
11
+ -- cross-schema net/role dependencies that drift with every GoTrue bump), this
12
+ -- reproduces ONLY the surface the agent_board migrations actually touch:
13
+ --
14
+ -- * auth.users FK target for agents.auth_user_id / owner_user_id, and
15
+ -- written by provision/ensure_github_user with 11 columns.
16
+ -- * auth.identities written by ensure_github_user; looked up by (provider,
17
+ -- provider_id).
18
+ -- * auth.uid()/role() read request.jwt.claim.* — the identity the RPCs gate on.
19
+ -- * extensions.pgcrypto extensions.digest / extensions.gen_random_bytes.
20
+ --
21
+ -- auth.sessions is intentionally omitted: it appears in the migrations only in a
22
+ -- comment, never in SQL. Base ROLES (service_role/authenticated/anon) are NOT
23
+ -- created here — they are cluster-global on the Supabase server this template is
24
+ -- built on (both local `supabase start` and CI), so migration GRANTs resolve.
25
+ --
26
+ -- If a future migration touches an auth column/table not modelled here, the apply
27
+ -- fails LOUDLY (a missing-column/relation error) — the signal to extend this file,
28
+ -- never a silent skip. Keep it minimal and driven by real usage.
29
+
30
+ create schema if not exists auth;
31
+ create schema if not exists extensions;
32
+
33
+ create extension if not exists pgcrypto with schema extensions;
34
+ create extension if not exists "uuid-ossp" with schema extensions;
35
+
36
+ -- GoTrue's auth.users, reduced to the columns the bundle inserts/reads. Everything
37
+ -- is nullable or defaulted so the canonical 11-column provision insert succeeds.
38
+ create table if not exists auth.users (
39
+ id uuid primary key,
40
+ instance_id uuid,
41
+ email text,
42
+ email_confirmed_at timestamptz,
43
+ encrypted_password text,
44
+ created_at timestamptz default now(),
45
+ updated_at timestamptz default now(),
46
+ raw_app_meta_data jsonb,
47
+ raw_user_meta_data jsonb,
48
+ aud text,
49
+ role text,
50
+ -- read-safety padding for common GoTrue columns a future path might SELECT
51
+ phone text,
52
+ confirmed_at timestamptz,
53
+ last_sign_in_at timestamptz,
54
+ is_sso_user boolean default false,
55
+ is_anonymous boolean default false
56
+ );
57
+
58
+ create table if not exists auth.identities (
59
+ id uuid primary key,
60
+ user_id uuid references auth.users(id) on delete cascade,
61
+ provider_id text,
62
+ provider text,
63
+ identity_data jsonb,
64
+ last_sign_in_at timestamptz,
65
+ created_at timestamptz default now(),
66
+ updated_at timestamptz default now(),
67
+ unique (provider, provider_id)
68
+ );
69
+
70
+ -- The identity helpers the bundle's RLS/RPCs gate on. Copied VERBATIM from the
71
+ -- live Supabase auth schema (supabase/postgres:17.6) so the harness exercises the
72
+ -- exact identity resolution production uses: coalesce the flattened
73
+ -- `request.jwt.claim.<key>` GUC with the `request.jwt.claims` JSON blob, so either
74
+ -- form the runtime sets resolves the caller.
75
+ create or replace function auth.uid() returns uuid
76
+ language sql stable
77
+ as $$
78
+ select
79
+ coalesce(
80
+ nullif(current_setting('request.jwt.claim.sub', true), ''),
81
+ (nullif(current_setting('request.jwt.claims', true), '')::jsonb ->> 'sub')
82
+ )::uuid
83
+ $$;
84
+
85
+ create or replace function auth.role() returns text
86
+ language sql stable
87
+ as $$
88
+ select
89
+ coalesce(
90
+ nullif(current_setting('request.jwt.claim.role', true), ''),
91
+ (nullif(current_setting('request.jwt.claims', true), '')::jsonb ->> 'role')
92
+ )::text
93
+ $$;
@@ -82,3 +82,36 @@ $$;
82
82
 
83
83
  REVOKE ALL ON FUNCTION public.ensure_github_user(text, text, text, text) FROM PUBLIC;
84
84
  GRANT EXECUTE ON FUNCTION public.ensure_github_user(text, text, text, text) TO service_role;
85
+
86
+ -- ---------------------------------------------------------------------------
87
+ -- Deterministic consistent (public_key, fingerprint) pair generators for pgTAP
88
+ -- fixtures. MINTHARDEN (#138) installs a BEFORE INSERT OR UPDATE trigger on
89
+ -- agent_board.agent_signing_keys asserting fingerprint = raw-byte derivation of
90
+ -- public_key for raw_ed25519_base64url keys. Fixtures that seed keys directly must
91
+ -- therefore use a CANONICAL key whose fingerprint MATCHES. These helpers derive a
92
+ -- distinct canonical 43-char base64url raw-Ed25519 key from a seed (public_key =
93
+ -- base64url(sha256(seed))) and the matching raw-byte fingerprint
94
+ -- (sha256:base64url(sha256(raw_bytes))) — byte-identical to agent_board._raw_key_fingerprint
95
+ -- WITHOUT depending on it (so this file still loads before the migrations). Seed on a
96
+ -- distinct value per row (its key/agent uuid or a unique label) to avoid UNIQUE collisions.
97
+ CREATE OR REPLACE FUNCTION public.test_pubkey(p_seed text)
98
+ RETURNS text
99
+ LANGUAGE sql
100
+ IMMUTABLE
101
+ AS $$
102
+ SELECT rtrim(translate(encode(extensions.digest(convert_to(p_seed, 'UTF8'), 'sha256'), 'base64'), '+/', '-_'), '=');
103
+ $$;
104
+
105
+ CREATE OR REPLACE FUNCTION public.test_key_fingerprint(p_seed text)
106
+ RETURNS text
107
+ LANGUAGE sql
108
+ IMMUTABLE
109
+ AS $$
110
+ SELECT 'sha256:' || rtrim(translate(encode(
111
+ extensions.digest(extensions.digest(convert_to(p_seed, 'UTF8'), 'sha256'), 'sha256'),
112
+ 'base64'), '+/', '-_'), '=');
113
+ $$;
114
+
115
+ REVOKE ALL ON FUNCTION public.test_pubkey(text) FROM PUBLIC;
116
+ REVOKE ALL ON FUNCTION public.test_key_fingerprint(text) FROM PUBLIC;
117
+ GRANT EXECUTE ON FUNCTION public.test_pubkey(text), public.test_key_fingerprint(text) TO service_role;
@@ -0,0 +1,79 @@
1
+ Parsed test spec with 4 sessions
2
+
3
+ starting permutation: guard_begin guard_board_key_share fleet_begin fleet_onboard portal_begin portal_enroll guard_commit fleet_commit portal_commit check
4
+ count
5
+ -----
6
+ 1
7
+ (1 row)
8
+
9
+ step guard_begin: BEGIN;
10
+ step guard_board_key_share:
11
+ select slug from agent_board.boards
12
+ where slug='atomic-cross-board' for key share;
13
+
14
+ slug
15
+ ------------------
16
+ atomic-cross-board
17
+ (1 row)
18
+
19
+ step fleet_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
20
+ step fleet_onboard:
21
+ select identity_disposition, membership_disposition, binding_disposition
22
+ from agent_board.onboard_federated_fleet_agent(
23
+ 'https://atomic-cross.test', 'message-board', 'cross-human',
24
+ jsonb_build_object('iss','https://atomic-cross.test','aud','message-board','sub','cross-human','iat',100),
25
+ 'atomic-cross-agent',
26
+ 'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0',
27
+ 'raw_ed25519_base64url',
28
+ 'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8',
29
+ true, null, 'agent', ARRAY['board:send'], ARRAY[]::text[],
30
+ (select code from agent_board.board_invite_tokens where created_by_agent_id='162a0000-0000-0000-0000-000000000001'),
31
+ (select id from agent_board.boards where slug='atomic-cross-board'),
32
+ '162a0000-0000-0000-0000-000000000003',
33
+ 'codex', 'phase-loop', 'message-board', 'sha256:atomic-cross-repo',
34
+ 'worker', 'phase_worker', 'atomic-cross-agent'
35
+ );
36
+ <waiting ...>
37
+ step portal_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
38
+ step portal_enroll:
39
+ select status from agent_board.enroll_federated_human(
40
+ 'https://atomic-cross.test', 'message-board', 'cross-human',
41
+ jsonb_build_object('sub','cross-human','iat',200), 'Cross Human'
42
+ );
43
+ <waiting ...>
44
+ step guard_commit: COMMIT;
45
+ step fleet_onboard: <... completed>
46
+ identity_disposition|membership_disposition|binding_disposition
47
+ --------------------+----------------------+-------------------
48
+ created |created |created
49
+ (1 row)
50
+
51
+ step fleet_commit: COMMIT;
52
+ step portal_enroll: <... completed>
53
+ status
54
+ ------
55
+ active
56
+ (1 row)
57
+
58
+ step portal_commit: COMMIT;
59
+ step check:
60
+ select
61
+ (select count(*) from agent_board.agents
62
+ where owner_user_id=(select auth_user_id from agent_board.agents
63
+ where metadata #>> ARRAY['federation','subject']='cross-human'
64
+ order by kind='human' desc limit 1)) as owned_agents,
65
+ (select count(*) from agent_board.board_memberships m
66
+ join agent_board.agents a on a.id=m.agent_id
67
+ where m.board_id=(select id from agent_board.boards where slug='atomic-cross-board')
68
+ and a.owner_user_id=(select auth_user_id from agent_board.agents
69
+ where metadata #>> ARRAY['federation','subject']='cross-human'
70
+ order by kind='human' desc limit 1)) as memberships,
71
+ (select count(*) from agent_board.fleet_machine_agents b
72
+ join agent_board.agents a on a.id=b.agent_id
73
+ where a.handle='atomic-cross-agent') as bindings;
74
+
75
+ owned_agents|memberships|bindings
76
+ ------------+-----------+--------
77
+ 2| 2| 1
78
+ (1 row)
79
+
@@ -0,0 +1,87 @@
1
+ Parsed test spec with 3 sessions
2
+
3
+ starting permutation: portal_begin portal_enroll revoke_begin revoke_human portal_commit revoke_commit check
4
+ count
5
+ -----
6
+ 1
7
+ (1 row)
8
+
9
+ step portal_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
10
+ step portal_enroll:
11
+ select status from agent_board.enroll_federated_human(
12
+ 'https://atomic-fedsession.test', 'message-board', 'portal-human-race',
13
+ jsonb_build_object('sub','portal-human-race','iat',200), 'Portal Human Race'
14
+ );
15
+
16
+ status
17
+ ------
18
+ active
19
+ (1 row)
20
+
21
+ step revoke_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
22
+ step revoke_human:
23
+ select revoked_agent_count from agent_board.revoke_human_subtree(
24
+ (select auth_user_id from agent_board.agents where metadata #>> ARRAY['federation','subject'] = 'portal-human-race'),
25
+ '16290000-0000-0000-0000-000000000001', 'portal race revoke'
26
+ );
27
+ <waiting ...>
28
+ step portal_commit: COMMIT;
29
+ step revoke_human: <... completed>
30
+ revoked_agent_count
31
+ -------------------
32
+ 1
33
+ (1 row)
34
+
35
+ step revoke_commit: COMMIT;
36
+ step check:
37
+ select
38
+ (select count(*) from agent_board.fleet_human_revocations where issuer='https://atomic-fedsession.test') as markers,
39
+ (select count(*) from agent_board.agents where metadata #>> ARRAY['federation','subject'] = 'portal-human-race' and status='active') as active_humans,
40
+ (select count(*) from agent_board.enrollment_federation_audit where issuer='https://atomic-fedsession.test') as audits;
41
+
42
+ markers|active_humans|audits
43
+ -------+-------------+------
44
+ 1| 0| 2
45
+ (1 row)
46
+
47
+
48
+ starting permutation: revoke_begin revoke_human portal_begin portal_enroll revoke_commit portal_commit check
49
+ count
50
+ -----
51
+ 1
52
+ (1 row)
53
+
54
+ step revoke_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
55
+ step revoke_human:
56
+ select revoked_agent_count from agent_board.revoke_human_subtree(
57
+ (select auth_user_id from agent_board.agents where metadata #>> ARRAY['federation','subject'] = 'portal-human-race'),
58
+ '16290000-0000-0000-0000-000000000001', 'portal race revoke'
59
+ );
60
+
61
+ revoked_agent_count
62
+ -------------------
63
+ 1
64
+ (1 row)
65
+
66
+ step portal_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
67
+ step portal_enroll:
68
+ select status from agent_board.enroll_federated_human(
69
+ 'https://atomic-fedsession.test', 'message-board', 'portal-human-race',
70
+ jsonb_build_object('sub','portal-human-race','iat',200), 'Portal Human Race'
71
+ );
72
+ <waiting ...>
73
+ step revoke_commit: COMMIT;
74
+ step portal_enroll: <... completed>
75
+ ERROR: human identity is durably revoked
76
+ step portal_commit: COMMIT;
77
+ step check:
78
+ select
79
+ (select count(*) from agent_board.fleet_human_revocations where issuer='https://atomic-fedsession.test') as markers,
80
+ (select count(*) from agent_board.agents where metadata #>> ARRAY['federation','subject'] = 'portal-human-race' and status='active') as active_humans,
81
+ (select count(*) from agent_board.enrollment_federation_audit where issuer='https://atomic-fedsession.test') as audits;
82
+
83
+ markers|active_humans|audits
84
+ -------+-------------+------
85
+ 1| 0| 1
86
+ (1 row)
87
+