code wiki / _hdl_build / nx_suite_share.nx
nx_suite_share.nx
buildroot/runtime/_hdl_build/nx_suite_share.nx
about
nx_suite_share.nx -- the family suite's sharing vocabulary (albums, contact cards, gifts) expressed
ENTIRELY as tuples on nx_rebac, the estate's one authorization plane. This REPLACES nx_share_plane,
which was a second implementation of a rule that already existed.
WHAT THE CONVERGENCE PROOF DECIDED (nx_share_convergence_gate: 7 agree, 2 declared divergences, 0 silent):
* the grant / revoke / check half was REDUNDANT -- both planes gave identical verdicts on every
scenario that mattered, so it is retired here rather than maintained twice;
* DIVERGENCE 1 (kept, deliberately): rebac lets anyone bootstrap the first grant on an OWNERLESS
object. For family media that is too loose -- an album nobody has claimed should not be shareable by
a passer-by -- so sg_grant REFUSES until someone has claimed it. This is a facade-level tightening
of a plane rule, which is allowed; loosening one would not be.
* DIVERGENCE 2 (migrated, not dropped): delegated re-sharing now rides the `curator` relation on the
new `album` object type in rb_expand -- a rewrite-table ROW, i.e. data on the shared plane, instead
of a capability bit in a private one.
* the GIFT half was the only genuinely new capability, and it is here: a gift MOVES ownership (the
giver stops being the owner) and the chain of holders stays recoverable from the append-only log via
rb_list_subjects_history. No second history is kept, because keeping one is how the duplicate began.
license_tier: ORIGINAL
dependencies 1 imports · 2 importers
imports: nx_rebac.nx
imported by: nx_connect_album.nxnx_suite_share_gate.nx
structs
| none |
consts
| 21 | const SG_VIEW: *u8 = "view\x00" |
| 22 | const SG_ADD: *u8 = "add\x00" |
| 23 | const SG_MANAGE: *u8 = "manage\x00" |
| 24 | const SG_R_VIEWER: *u8 = "viewer\x00" |
| 25 | const SG_R_CURATOR: *u8 = "curator\x00" |
| 26 | const SG_R_OWNER: *u8 = "owner\x00" |
| 27 | const SG_SYSTEM: *u8 = "system\x00" |
| 29 | const SG_E_NOTOWNER: i64 = -1 |
| 30 | const SG_E_UNCLAIMED: i64 = -2 |
| 31 | const SG_E_SELF: i64 = -3 |
| 32 | const SG_E_BADARG: i64 = -6 |
| 33 | const SG_MAXCHAIN: i64 = 64 |
functions
| 38 | func sg_obj(kind: *u8, id: i64, out: *u8) -> i64 |
| 46 | func sg_sub(uid: i64, out: *u8) -> i64 |
| 53 | func sg_owner_of(prefix: *u8, kind: *u8, id: i64) -> i64 |
| 61 | func sg_is_claimed(prefix: *u8, kind: *u8, id: i64) -> i64 |
| 67 | func sg_claim(prefix: *u8, owner: i64, kind: *u8, id: i64) -> i64 |
| 80 | func sg_grant(prefix: *u8, actor: i64, subj: i64, kind: *u8, id: i64, rel: *u8) -> i64 |
| 92 | func sg_revoke(prefix: *u8, actor: i64, subj: i64, kind: *u8, id: i64, rel: *u8) -> i64 |
| 102 | func sg_may(prefix: *u8, actor: i64, kind: *u8, id: i64, perm: *u8) -> i64 |
| 109 | func sg_gift(prefix: *u8, giver: i64, receiver: i64, kind: *u8, id: i64) -> i64 |
| 122 | func sg_provenance(prefix: *u8, kind: *u8, id: i64, out: *i64, cap: i64) -> i64 |
| 128 | func sg_viewers(prefix: *u8, kind: *u8, id: i64, out: *i64, cap: i64) -> i64 |