@consiliency/agent-board-schema 1.56.0 → 1.58.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/20261007000100_agent_board_onboard_requests.sql +139 -0
- package/migrations/20261008000100_agent_board_hosted_delegates.sql +3152 -0
- package/package.json +1 -1
- package/schema-manifest.json +21 -3
- package/src/tooling.test.mjs +8 -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 +1134 -0
- package/tests/agent_board_ledger_authority.test.sql +34 -5
- package/tests/agent_board_membership_current_row_class.test.sql +3 -1
- package/tests/agent_board_onboard_requests.test.sql +353 -0
- package/tests/agent_board_rowid.test.sql +18 -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 +278 -2
- package/tests/catalog/p_metadata_parameters.json +48 -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_withdraw_evict_race.out +235 -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_withdraw_evict_race.spec +145 -0
|
@@ -616,6 +616,14 @@
|
|
|
616
616
|
{
|
|
617
617
|
"id": "20261006000100_agent_board_room_roster_active_first",
|
|
618
618
|
"sha256": "637480feeca07dbb2fe7a4624dc6d063d0c1f23e6ea3c3ee9a946ad43de4e34e"
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"id": "20261007000100_agent_board_onboard_requests",
|
|
622
|
+
"sha256": "fbdbecfb1c78e2d1b16b37845a74082dcdf1241c61c0356b992e1e01baddc41c"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"id": "20261008000100_agent_board_hosted_delegates",
|
|
626
|
+
"sha256": "ef57647e29b8afc788dc8c481a0165b10a3c448aae12b8901901b653216bc3a8"
|
|
619
627
|
}
|
|
620
628
|
]
|
|
621
629
|
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
-- ONBOARD (v11) SL-2: the caller's own join requests (IF-0-ONBOARD-4) and a service-side
|
|
2
|
+
-- invite label lookup for the consent page (IF-0-ONBOARD-11). Additive: two new read-only
|
|
3
|
+
-- functions and one index. schema_version stays 8.
|
|
4
|
+
--
|
|
5
|
+
-- Sources read, each at its latest definition:
|
|
6
|
+
-- * agent_board.current_agent_id() -- 20260920000100 (the resolver
|
|
7
|
+
-- request_join_board, 20260810000100, calls);
|
|
8
|
+
-- * agent_board.board_membership_events -- 20260806000100 (the append-only
|
|
9
|
+
-- consent ledger; seq is the total order, created_at is wall-clock age);
|
|
10
|
+
-- * agent_board.boards.join_request_ttl_days -- 20260806000100;
|
|
11
|
+
-- * the emitter _emit_membership_event -- 20260807000100: a request made by the
|
|
12
|
+
-- subject through request_join_board is `target-authored` / `requested`;
|
|
13
|
+
-- * agent_board.board_invite_tokens -- 20260724000100. invite_board_for_display
|
|
14
|
+
-- checks only the frozen IF-0-ONBOARD-11 subset: not revoked, expires_at > now(), uses
|
|
15
|
+
-- remaining. The redeem core (latest 20260909000100) refuses MORE -- a suspended or
|
|
16
|
+
-- fleet-revoked creator, a lapsed ceiling, a removed agent, fleet-bounded invites -- so a
|
|
17
|
+
-- code that displays a board can still fail to redeem.
|
|
18
|
+
|
|
19
|
+
-- =============================================================================
|
|
20
|
+
-- 1. list_my_board_requests() -- IF-0-ONBOARD-4
|
|
21
|
+
-- =============================================================================
|
|
22
|
+
-- WHICH REQUESTS. The ledger, never the membership row. A request is a (board, caller) with
|
|
23
|
+
-- at least one event where agent_id is the caller, provenance = 'target-authored' and
|
|
24
|
+
-- result_state = 'requested'. board_memberships.created_by_agent_id is NOT a source: the
|
|
25
|
+
-- sink overwrites it on every later write (an approval names the approver), so it cannot say
|
|
26
|
+
-- who asked.
|
|
27
|
+
--
|
|
28
|
+
-- IDENTITY. From the session only, by the resolver request_join_board uses. There is no
|
|
29
|
+
-- parameter, and a null identity (service_role, anon, a revoked credential) returns nothing.
|
|
30
|
+
--
|
|
31
|
+
-- CURRENT STATE. The caller's membership row on that board, chosen active-first (MBROWID 3a,
|
|
32
|
+
-- the key every current-standing reader uses), or 'none' when no row exists. A rejected request
|
|
33
|
+
-- reads 'left' (REJECTSEM, #89: a refusal lands on the recoverable state).
|
|
34
|
+
--
|
|
35
|
+
-- EXPIRY. expires_at = the latest request event's created_at + the board's
|
|
36
|
+
-- join_request_ttl_days. expired mirrors the consent predicates exactly
|
|
37
|
+
-- (created_at < now() - ttl): an expired request no longer counts as consent. It is a property
|
|
38
|
+
-- of the REQUEST and is reported whatever the membership's current state.
|
|
39
|
+
create or replace function agent_board.list_my_board_requests()
|
|
40
|
+
returns table(
|
|
41
|
+
board_id uuid,
|
|
42
|
+
board_name text,
|
|
43
|
+
board_slug text,
|
|
44
|
+
requested_at timestamptz,
|
|
45
|
+
membership_state text,
|
|
46
|
+
expires_at timestamptz,
|
|
47
|
+
expired boolean
|
|
48
|
+
)
|
|
49
|
+
language plpgsql
|
|
50
|
+
stable
|
|
51
|
+
security definer
|
|
52
|
+
set search_path = agent_board, public
|
|
53
|
+
as $$
|
|
54
|
+
declare
|
|
55
|
+
v_actor uuid := agent_board.current_agent_id();
|
|
56
|
+
begin
|
|
57
|
+
if v_actor is null then
|
|
58
|
+
return;
|
|
59
|
+
end if;
|
|
60
|
+
|
|
61
|
+
return query
|
|
62
|
+
select
|
|
63
|
+
b.id,
|
|
64
|
+
b.name,
|
|
65
|
+
b.slug,
|
|
66
|
+
req.created_at,
|
|
67
|
+
coalesce(cur.membership_state, 'none'),
|
|
68
|
+
req.created_at + make_interval(days => b.join_request_ttl_days),
|
|
69
|
+
req.created_at < now() - make_interval(days => b.join_request_ttl_days)
|
|
70
|
+
from (
|
|
71
|
+
-- The latest request event per board, by seq (the ledger's total order).
|
|
72
|
+
select distinct on (e.board_id) e.board_id, e.created_at
|
|
73
|
+
from agent_board.board_membership_events e
|
|
74
|
+
where e.agent_id = v_actor
|
|
75
|
+
and e.provenance = 'target-authored'
|
|
76
|
+
and e.result_state = 'requested'
|
|
77
|
+
order by e.board_id, e.seq desc
|
|
78
|
+
) req
|
|
79
|
+
join agent_board.boards b on b.id = req.board_id
|
|
80
|
+
left join lateral (
|
|
81
|
+
select bm.membership_state
|
|
82
|
+
from agent_board.board_memberships bm
|
|
83
|
+
where bm.board_id = req.board_id
|
|
84
|
+
and bm.agent_id = v_actor
|
|
85
|
+
order by case when bm.membership_state in ('joined', 'subscribed') then 0 else 1 end,
|
|
86
|
+
bm.created_at desc, bm.id desc
|
|
87
|
+
limit 1
|
|
88
|
+
) cur on true
|
|
89
|
+
order by req.created_at desc, b.id desc;
|
|
90
|
+
end;
|
|
91
|
+
$$;
|
|
92
|
+
|
|
93
|
+
comment on function agent_board.list_my_board_requests() is
|
|
94
|
+
'IF-0-ONBOARD-4: the caller''s own join requests as they stand now. Source is the consent ledger (board_membership_events: agent_id = caller, provenance target-authored, result_state requested), never board_memberships.created_by_agent_id, which later writers overwrite. Identity is current_agent_id() only; there is no parameter and a null identity returns nothing, so service_role (no caller identity) is refused EXECUTE. Per board: id, name, slug, the latest request event''s time, the current membership state chosen active-first (MBROWID 3a) or none, expires_at = requested_at + join_request_ttl_days, and expired (the request no longer counts as consent). Requests made before the ledger existed carry only a board-authored backfill_neutral event and are not returned. No per-row history.';
|
|
95
|
+
|
|
96
|
+
revoke all on function agent_board.list_my_board_requests() from public, anon, service_role;
|
|
97
|
+
grant execute on function agent_board.list_my_board_requests() to authenticated;
|
|
98
|
+
|
|
99
|
+
-- =============================================================================
|
|
100
|
+
-- 2. invite_board_for_display(p_code_sha256) -- IF-0-ONBOARD-11
|
|
101
|
+
-- =============================================================================
|
|
102
|
+
-- The Portal's consent page shows which board an in-chat enrollment will join, and it holds
|
|
103
|
+
-- only the digest (the code itself never leaves the agent). The digest is the lowercase hex
|
|
104
|
+
-- sha256 of the code text; the argument is compared case-insensitively.
|
|
105
|
+
--
|
|
106
|
+
-- Only a code passing the IF-0-ONBOARD-11 subset resolves: not revoked, not expired, and uses
|
|
107
|
+
-- remaining. This is narrower than the redeem core (see the header), so display is not a promise
|
|
108
|
+
-- that redeem will succeed. Anything else -- including an unknown digest -- returns no row, one uniform
|
|
109
|
+
-- answer. Codes are 256-bit, so the digest is not a practical oracle; EXECUTE is service_role
|
|
110
|
+
-- only regardless, because the Portal calls it server-side.
|
|
111
|
+
create index if not exists idx_agent_board_board_invite_tokens_code_sha256
|
|
112
|
+
on agent_board.board_invite_tokens (encode(extensions.digest(code, 'sha256'), 'hex'));
|
|
113
|
+
|
|
114
|
+
create or replace function agent_board.invite_board_for_display(p_code_sha256 text)
|
|
115
|
+
returns table(
|
|
116
|
+
board_id uuid,
|
|
117
|
+
board_name text,
|
|
118
|
+
board_slug text,
|
|
119
|
+
preset_role text
|
|
120
|
+
)
|
|
121
|
+
language sql
|
|
122
|
+
stable
|
|
123
|
+
security definer
|
|
124
|
+
set search_path = agent_board, public
|
|
125
|
+
as $$
|
|
126
|
+
select b.id, b.name, b.slug, t.preset_role
|
|
127
|
+
from agent_board.board_invite_tokens t
|
|
128
|
+
join agent_board.boards b on b.id = t.board_id
|
|
129
|
+
where encode(extensions.digest(t.code, 'sha256'), 'hex') = lower(p_code_sha256)
|
|
130
|
+
and t.revoked_at is null
|
|
131
|
+
and t.expires_at > now()
|
|
132
|
+
and (t.max_uses is null or t.uses_count < t.max_uses);
|
|
133
|
+
$$;
|
|
134
|
+
|
|
135
|
+
comment on function agent_board.invite_board_for_display(text) is
|
|
136
|
+
'IF-0-ONBOARD-11: resolves an invite code''s digest (lowercase hex sha256 of the code, compared case-insensitively) to (board_id, board_name, board_slug, preset_role) for display on the Portal consent page. Only a usable code resolves -- not revoked, expires_at > now(), and max_uses null or uses_count < max_uses (a subset of the redeem core''s checks, so a displayed board can still fail to redeem); revoked, expired, exhausted and unknown codes return no row. Read-only. EXECUTE is service_role only: the Portal calls it server-side.';
|
|
137
|
+
|
|
138
|
+
revoke all on function agent_board.invite_board_for_display(text) from public, anon, authenticated;
|
|
139
|
+
grant execute on function agent_board.invite_board_for_display(text) to service_role;
|