@consiliency/agent-board-schema 1.55.0 → 1.57.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/20261006000100_agent_board_room_roster_active_first.sql +118 -0
- package/migrations/20261007000100_agent_board_onboard_requests.sql +139 -0
- package/package.json +1 -1
- package/schema-manifest.json +21 -3
- package/src/tooling.test.mjs +8 -2
- package/tests/agent_board_membership_current_row_class.test.sql +462 -0
- package/tests/agent_board_onboard_requests.test.sql +353 -0
- package/tests/agent_board_room_roster.test.sql +262 -24
- package/tests/agent_board_rowid.test.sql +32 -6
- package/tests/catalog/function_execute_privileges.json +18 -0
- package/tests/catalog/p_metadata_parameters.json +8 -0
|
@@ -612,6 +612,14 @@
|
|
|
612
612
|
{
|
|
613
613
|
"id": "20261005000100_agent_board_enroll_token_single_use",
|
|
614
614
|
"sha256": "317d7b41432b36a2e38cc64940838e173e425014e3e256a96d832202b250e82d"
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"id": "20261006000100_agent_board_room_roster_active_first",
|
|
618
|
+
"sha256": "637480feeca07dbb2fe7a4624dc6d063d0c1f23e6ea3c3ee9a946ad43de4e34e"
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"id": "20261007000100_agent_board_onboard_requests",
|
|
622
|
+
"sha256": "fbdbecfb1c78e2d1b16b37845a74082dcdf1241c61c0356b992e1e01baddc41c"
|
|
615
623
|
}
|
|
616
624
|
]
|
|
617
625
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
-- ROOMCONTRACT-ACTIVEFIRST (message-board#542): the owner/admin roster chooses current
|
|
2
|
+
-- standing ACTIVE-FIRST, as every other acting membership reader does (MBROWID 3a).
|
|
3
|
+
--
|
|
4
|
+
-- THE DEFECT. 20261003000100 chose the caller's standing (authorization) and each
|
|
5
|
+
-- member's inclusion (projection) from the LATEST board_memberships row alone:
|
|
6
|
+
-- `order by created_at desc, id desc`. The active-membership unique index is PARTIAL
|
|
7
|
+
-- (idx_agent_board_board_memberships_active_unique, WHERE membership_state in
|
|
8
|
+
-- ('joined','subscribed')), so one active row can coexist with newer non-active rows
|
|
9
|
+
-- (removed / left / requested / invited). MBROWID 3a (20260803000100) ruled that every
|
|
10
|
+
-- reader acting on "current standing" prefers the active row when one exists; join_board,
|
|
11
|
+
-- update_board_membership, _upsert_board_membership_state and
|
|
12
|
+
-- list_board_pending_memberships all do. The roster did not, so an active owner or admin
|
|
13
|
+
-- with a newer non-active row was refused with 42501 and omitted from every roster —
|
|
14
|
+
-- while the rest of MB (and Portal's self view, which reduces active-first as MBROWID
|
|
15
|
+
-- requires) treated them as active.
|
|
16
|
+
--
|
|
17
|
+
-- THE FIX. Both selection sites take the MBROWID 3a key, then the existing total order:
|
|
18
|
+
-- order by case when membership_state in ('joined','subscribed') then 0 else 1 end,
|
|
19
|
+
-- created_at desc, id desc
|
|
20
|
+
-- Everything else is unchanged: signature, projection, STABLE, SECURITY DEFINER,
|
|
21
|
+
-- search_path, the 42501 message, the result order, and the grants.
|
|
22
|
+
--
|
|
23
|
+
-- The class this belongs to is pinned from the catalog, not from this list:
|
|
24
|
+
-- tests/agent_board_membership_current_row_class.test.sql derives every statement that
|
|
25
|
+
-- picks ONE board_memberships row by recency and requires the active-first key, or a
|
|
26
|
+
-- named exemption whose filter it asserts exactly. This migration fixes the only two
|
|
27
|
+
-- sites that class found without the key; the exemptions are recorded there.
|
|
28
|
+
--
|
|
29
|
+
-- CREATE OR REPLACE keeps the ACL and the COMMENT, but both are restated below anyway:
|
|
30
|
+
-- the COMMENT's text described latest-row semantics and must change, and the grants are
|
|
31
|
+
-- restated so this file alone says what the function's posture is.
|
|
32
|
+
|
|
33
|
+
create or replace function agent_board.list_board_members(p_board_id uuid)
|
|
34
|
+
returns table(
|
|
35
|
+
membership_id uuid,
|
|
36
|
+
board_id uuid,
|
|
37
|
+
agent_id uuid,
|
|
38
|
+
handle text,
|
|
39
|
+
display_name text,
|
|
40
|
+
agent_type text,
|
|
41
|
+
membership_state text,
|
|
42
|
+
role text,
|
|
43
|
+
created_by_agent_id uuid,
|
|
44
|
+
membership_created_at timestamptz,
|
|
45
|
+
membership_updated_at timestamptz
|
|
46
|
+
)
|
|
47
|
+
language plpgsql
|
|
48
|
+
stable
|
|
49
|
+
security definer
|
|
50
|
+
set search_path = agent_board, public
|
|
51
|
+
as $$
|
|
52
|
+
declare
|
|
53
|
+
v_actor uuid := agent_board.current_agent_id();
|
|
54
|
+
begin
|
|
55
|
+
-- Authorization precedes disclosure. Creator identity is deliberately absent:
|
|
56
|
+
-- only the caller's current membership row can establish authority, and the
|
|
57
|
+
-- current row is the ACTIVE one when one exists (MBROWID 3a), else the latest.
|
|
58
|
+
if v_actor is null
|
|
59
|
+
or not exists (
|
|
60
|
+
select 1
|
|
61
|
+
from (
|
|
62
|
+
select bm.membership_state, bm.role
|
|
63
|
+
from agent_board.board_memberships bm
|
|
64
|
+
where bm.board_id = p_board_id
|
|
65
|
+
and bm.agent_id = v_actor
|
|
66
|
+
order by case when bm.membership_state in ('joined', 'subscribed') then 0 else 1 end,
|
|
67
|
+
bm.created_at desc, bm.id desc
|
|
68
|
+
limit 1
|
|
69
|
+
) actor_standing
|
|
70
|
+
where actor_standing.membership_state in ('joined', 'subscribed')
|
|
71
|
+
and actor_standing.role in ('owner', 'admin')
|
|
72
|
+
) then
|
|
73
|
+
raise exception 'only a board owner or admin may list board members'
|
|
74
|
+
using errcode = '42501';
|
|
75
|
+
end if;
|
|
76
|
+
|
|
77
|
+
-- Choose exactly one current row per agent (active-first, MBROWID 3a), then
|
|
78
|
+
-- keep only agents whose current row is active.
|
|
79
|
+
return query
|
|
80
|
+
select
|
|
81
|
+
latest.id,
|
|
82
|
+
latest.board_id,
|
|
83
|
+
latest.agent_id,
|
|
84
|
+
a.handle,
|
|
85
|
+
a.display_name,
|
|
86
|
+
a.agent_type,
|
|
87
|
+
latest.membership_state,
|
|
88
|
+
latest.role,
|
|
89
|
+
latest.created_by_agent_id,
|
|
90
|
+
latest.created_at,
|
|
91
|
+
latest.updated_at
|
|
92
|
+
from (
|
|
93
|
+
select distinct on (bm.agent_id) bm.*
|
|
94
|
+
from agent_board.board_memberships bm
|
|
95
|
+
where bm.board_id = p_board_id
|
|
96
|
+
order by bm.agent_id,
|
|
97
|
+
case when bm.membership_state in ('joined', 'subscribed') then 0 else 1 end,
|
|
98
|
+
bm.created_at desc, bm.id desc
|
|
99
|
+
) latest
|
|
100
|
+
join agent_board.agents a on a.id = latest.agent_id
|
|
101
|
+
where latest.membership_state in ('joined', 'subscribed')
|
|
102
|
+
order by
|
|
103
|
+
case latest.role
|
|
104
|
+
when 'owner' then 0
|
|
105
|
+
when 'admin' then 1
|
|
106
|
+
when 'member' then 2
|
|
107
|
+
when 'observer' then 3
|
|
108
|
+
end,
|
|
109
|
+
lower(a.handle),
|
|
110
|
+
latest.agent_id;
|
|
111
|
+
end;
|
|
112
|
+
$$;
|
|
113
|
+
|
|
114
|
+
comment on function agent_board.list_board_members(uuid) is
|
|
115
|
+
'Owner/admin-gated active board roster. Fails 42501 for a null actor (including service_role through this user-facing path), creator without current standing, or any caller whose current board membership is not active owner/admin. The current row is chosen active-first (MBROWID 3a): case when membership_state in (joined, subscribed) then 0 else 1 end, created_at desc, id desc — so an active row outranks a newer removed/left/requested/invited row. Returns each agent''s current row only when joined/subscribed, ordered owner/admin/member/observer then lower(handle), agent_id. Board-scoped and metadata-free.';
|
|
116
|
+
|
|
117
|
+
revoke all on function agent_board.list_board_members(uuid) from public, anon;
|
|
118
|
+
grant execute on function agent_board.list_board_members(uuid) to authenticated, service_role;
|
|
@@ -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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@consiliency/agent-board-schema",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.57.0",
|
|
4
4
|
"description": "Canonical, immutable, exact-pinnable agent_board schema bundle: ordered SQL migrations, digest + compatibility manifest, and deterministic materialize/plan/check tooling for adopters.",
|
|
5
5
|
"repository": "https://github.com/Consiliency/message-board.git",
|
|
6
6
|
"type": "module",
|
package/schema-manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": "agent_board_schema_manifest.v1",
|
|
3
3
|
"interface": "IF-0-MBPLANE-BUNDLE-1",
|
|
4
4
|
"package": "@consiliency/agent-board-schema",
|
|
5
|
-
"packageVersion": "1.
|
|
5
|
+
"packageVersion": "1.57.0",
|
|
6
6
|
"schemaVersion": 8,
|
|
7
7
|
"minClientVersion": "1.1.0",
|
|
8
8
|
"source": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"usage": "upsert (retention/monitoring defaults; on conflict do nothing)"
|
|
47
47
|
}
|
|
48
48
|
],
|
|
49
|
-
"migrationCount":
|
|
50
|
-
"aggregateSha256": "
|
|
49
|
+
"migrationCount": 155,
|
|
50
|
+
"aggregateSha256": "347357b36b5ee37fbde189e005993c40df1e63a2d9d247b53823761304ae127e",
|
|
51
51
|
"migrations": [
|
|
52
52
|
{
|
|
53
53
|
"order": 0,
|
|
@@ -1425,6 +1425,24 @@
|
|
|
1425
1425
|
"sourceRef": "message-board",
|
|
1426
1426
|
"bytes": 55964,
|
|
1427
1427
|
"sha256": "317d7b41432b36a2e38cc64940838e173e425014e3e256a96d832202b250e82d"
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
"order": 153,
|
|
1431
|
+
"id": "20261006000100_agent_board_room_roster_active_first",
|
|
1432
|
+
"filename": "20261006000100_agent_board_room_roster_active_first.sql",
|
|
1433
|
+
"origin": "message-board-forward",
|
|
1434
|
+
"sourceRef": "message-board",
|
|
1435
|
+
"bytes": 5470,
|
|
1436
|
+
"sha256": "637480feeca07dbb2fe7a4624dc6d063d0c1f23e6ea3c3ee9a946ad43de4e34e"
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
"order": 154,
|
|
1440
|
+
"id": "20261007000100_agent_board_onboard_requests",
|
|
1441
|
+
"filename": "20261007000100_agent_board_onboard_requests.sql",
|
|
1442
|
+
"origin": "message-board-forward",
|
|
1443
|
+
"sourceRef": "message-board",
|
|
1444
|
+
"bytes": 7655,
|
|
1445
|
+
"sha256": "fbdbecfb1c78e2d1b16b37845a74082dcdf1241c61c0356b992e1e01baddc41c"
|
|
1428
1446
|
}
|
|
1429
1447
|
],
|
|
1430
1448
|
"excludedBridge": {
|
package/src/tooling.test.mjs
CHANGED
|
@@ -38,9 +38,9 @@ describe('manifest integrity', () => {
|
|
|
38
38
|
expect(manifest.schemaVersion).toBe(8);
|
|
39
39
|
expect(manifest.minClientVersion).toMatch(/^\d+\.\d+\.\d+$/);
|
|
40
40
|
});
|
|
41
|
-
it('registers the four MBAUTHZ + four MBSENDAUTHZ + four MBSESSION + four MBDELEG + three MBFED + three MBHARDEN + two MBPORTALGATE + two MBPORTAL-PR32 + two ROOMOWN + two ROOMLINK + one ROOMDELEG + one LOCALAUTH + one ROOMUIAPI + one FEDSESSION + one FEDSESSION-AUTOJOIN + one GATENULL + one MEMBSTATE + one AGENTSDIR + one LEAVEIDEM + one ROLERESET + one MBROWID + one MBHYGIENE + one MBCONSENT-A + one MBCONSENT-B(a) + one MBCONSENT-B(i) + one MBCONSENT-B(ii) + one MBCONSENT-B(iii) + one MBHARDEN-#97 + one MBHARDEN-#118 + one INVITEPOLICY + one OBSGATE + one OBSGATE-2 + one OBSGATE-3 + one OBSGATE-4 + one FLEETMACHINERLS + one RESOLVENOOP + one ROOMDELEG-LANEB + one CLAIMKEY + two MINTHARDEN + one FLEETMACHINEHIJACK + one CLAIMGATE-SHADOW + one CLAIMGATE-ENFORCE + one FLEETMACHINEREACTIVATION + one DELEGCAPCEILING + one FLEETMACHINERECLAIM + one DELEGSOLEWRITER + one FLEETDOMAINRECLAIM + five ATOMICFLEETONBOARDING (onboarding + ceiling-lock + revocation-evidence + fedsession-gate + fedsession-lock-order) + one OUTBOXWAKE + one ENROLLLOCKORDER + one FEDPROVIDERABSENCE + one WAKERECOVERY + one CONSENTRECONCILE + one ENROLLRESUMPTION + one SIGNEDAUTHORITY + one SIGNERLIFECYCLE + one LEDGERAUTHORITY + one CEILINGLOCKCOMMENT + one LEDGERBOARDCREATE + one RECEIPTSUBJECTGATE + one TASKTHREADLOCKORDER + one CLAIMSUBJECTGATE + one FEDSESSIONIDENTITYGATE + one FEDIDENTITYSLUG + one INVITENODOWNGRADE + one SIGNEDWRITEFLAG + one SIGNEDWRITEMODEL + one RTCREDCLAIM + one ORIGINPOSTURE + one BOARDCLAIMPOLICY + one HEARTBEATPRESERVE + one LIVENESSDENOM + one OWNERLESSRENEWTTL + one OWNERLESSQUOTACENSUS + one FLEETDOMAINNODOWNGRADE + one OWNERLESSQUOTACONVERGE + one ADVISORYREVERTRESET + one CLAIMPOLICYRACE + one CLAIMPOLICYLOCKGRANT + one SESSIONCHALLENGESUPERSEDE + one ROOMCONTRACT + one CALLBACKCONSUMER + one ENROLLTOKENSINGLEUSE forward migrations (migrationCount = prior 113 + 5 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 =
|
|
41
|
+
it('registers the four MBAUTHZ + four MBSENDAUTHZ + four MBSESSION + four MBDELEG + three MBFED + three MBHARDEN + two MBPORTALGATE + two MBPORTAL-PR32 + two ROOMOWN + two ROOMLINK + one ROOMDELEG + one LOCALAUTH + one ROOMUIAPI + one FEDSESSION + one FEDSESSION-AUTOJOIN + one GATENULL + one MEMBSTATE + one AGENTSDIR + one LEAVEIDEM + one ROLERESET + one MBROWID + one MBHYGIENE + one MBCONSENT-A + one MBCONSENT-B(a) + one MBCONSENT-B(i) + one MBCONSENT-B(ii) + one MBCONSENT-B(iii) + one MBHARDEN-#97 + one MBHARDEN-#118 + one INVITEPOLICY + one OBSGATE + one OBSGATE-2 + one OBSGATE-3 + one OBSGATE-4 + one FLEETMACHINERLS + one RESOLVENOOP + one ROOMDELEG-LANEB + one CLAIMKEY + two MINTHARDEN + one FLEETMACHINEHIJACK + one CLAIMGATE-SHADOW + one CLAIMGATE-ENFORCE + one FLEETMACHINEREACTIVATION + one DELEGCAPCEILING + one FLEETMACHINERECLAIM + one DELEGSOLEWRITER + one FLEETDOMAINRECLAIM + five ATOMICFLEETONBOARDING (onboarding + ceiling-lock + revocation-evidence + fedsession-gate + fedsession-lock-order) + one OUTBOXWAKE + one ENROLLLOCKORDER + one FEDPROVIDERABSENCE + one WAKERECOVERY + one CONSENTRECONCILE + one ENROLLRESUMPTION + one SIGNEDAUTHORITY + one SIGNERLIFECYCLE + one LEDGERAUTHORITY + one CEILINGLOCKCOMMENT + one LEDGERBOARDCREATE + one RECEIPTSUBJECTGATE + one TASKTHREADLOCKORDER + one CLAIMSUBJECTGATE + one FEDSESSIONIDENTITYGATE + one FEDIDENTITYSLUG + one INVITENODOWNGRADE + one SIGNEDWRITEFLAG + one SIGNEDWRITEMODEL + one RTCREDCLAIM + one ORIGINPOSTURE + one BOARDCLAIMPOLICY + one HEARTBEATPRESERVE + one LIVENESSDENOM + one OWNERLESSRENEWTTL + one OWNERLESSQUOTACENSUS + one FLEETDOMAINNODOWNGRADE + one OWNERLESSQUOTACONVERGE + one ADVISORYREVERTRESET + one CLAIMPOLICYRACE + one CLAIMPOLICYLOCKGRANT + one SESSIONCHALLENGESUPERSEDE + one ROOMCONTRACT + one CALLBACKCONSUMER + one ENROLLTOKENSINGLEUSE + one ROOMCONTRACT-ACTIVEFIRST + one ONBOARD forward migrations (migrationCount = prior 113 + 5 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 155)', () => {
|
|
42
42
|
expect(manifest.migrationCount).toBe(manifest.migrations.length);
|
|
43
|
-
expect(manifest.migrationCount).toBe(
|
|
43
|
+
expect(manifest.migrationCount).toBe(155);
|
|
44
44
|
// MBSESSION switched enforcement on (scoped-send re-grant): the client-visible
|
|
45
45
|
// schema version bumped to 8. MBDELEG tightens delegation and MBFED adds only
|
|
46
46
|
// enrollment-only additive surface (identity_providers registry, enrollment audit,
|
|
@@ -340,6 +340,12 @@ describe('manifest integrity', () => {
|
|
|
340
340
|
'20261004000100_agent_board_callback_consumer_intent.sql',
|
|
341
341
|
// ENROLLTOKENSINGLEUSE (#521): a verified Portal token binds to at most one key.
|
|
342
342
|
'20261005000100_agent_board_enroll_token_single_use.sql',
|
|
343
|
+
// ROOMCONTRACT-ACTIVEFIRST (#542): list_board_members chooses current standing
|
|
344
|
+
// active-first (MBROWID 3a) at both its authorization and projection sites.
|
|
345
|
+
'20261006000100_agent_board_room_roster_active_first.sql',
|
|
346
|
+
// ONBOARD (v11): list_my_board_requests (IF-0-ONBOARD-4) and the service-only
|
|
347
|
+
// invite_board_for_display digest lookup (IF-0-ONBOARD-11).
|
|
348
|
+
'20261007000100_agent_board_onboard_requests.sql',
|
|
343
349
|
]) {
|
|
344
350
|
expect(names.has(f)).toBe(true);
|
|
345
351
|
}
|