code wiki / (root) / nx_offer_ledger.nx

nx_offer_ledger.nx source

↩ module page · 146 lines · 4725 B

1// nx_offer_ledger.nx -- licensing outreach / offer tracker. For each 2// TO_ACQUIRE target (a person/host we want to license), record the agent/contact 3// and track the offer through a state machine: 4// 5// open -> PENDING --send--> SENT --accept--> ACCEPTED 6// \----------------decline---> DECLINED 7// 8// On ACCEPTED the caller closes the loop: reclassify the host OWNED 9// (nx_fetch_rights) + mint a grant (nx_rights_ledger) so the talent becomes 10// product-usable. Respectful + legal: nothing is product-usable until a real 11// accepted offer + license exists. Mirrors the nx_rights_ledger pattern. 12// 13// contact_ref is an id into a contacts store (name/email/agent details = a 14// later rung); here it just carries the link. 15// license_tier: ORIGINAL 16 17import "nx_syscalls.nx" 18import "nx_tier.nx" 19 20const NX_OF_PENDING: nx_int = 0 21const NX_OF_SENT: nx_int = 1 22const NX_OF_ACCEPTED: nx_int = 2 23const NX_OF_DECLINED: nx_int = 3 24const NX_OF_N: nx_int = 4 25 26const NX_OF_OK: nx_int = 0 27const NX_OF_ERR_FULL: nx_int = 1 28const NX_OF_ERR_NOT_FOUND: nx_int = 2 29const NX_OF_ERR_BAD_TRANSITION: nx_int = 3 30 31struct NxOffer { 32 offer_id: nx_int, 33 target_bk: nx_int, 34 contact_ref: nx_int, 35 state: nx_int, 36 opened_us: nx_size, 37 decided_us: nx_size, 38} 39 40struct NxOfferLedger { 41 offers: *NxOffer, 42 capacity: nx_size, 43 count: nx_size, 44} 45 46const NX_OF_BYTES: nx_size = 48 47 48func nx_offer_ledger_new(capacity: nx_size) -> *NxOfferLedger { 49 let l: *NxOfferLedger = (sys_mmap(24)) as *NxOfferLedger 50 l.offers = (sys_mmap(capacity * NX_OF_BYTES)) as *NxOffer 51 l.capacity = capacity 52 l.count = 0 53 return l 54} 55 56func _of_at(l: *NxOfferLedger, idx: nx_size) -> *NxOffer { 57 return (l.offers as i64 + (idx as i64) * NX_OF_BYTES) as *NxOffer 58} 59 60func _of_find(l: *NxOfferLedger, offer_id: nx_int) -> nx_int { 61 var i: nx_size = 0 62 while i < l.count { 63 let o: *NxOffer = _of_at(l, i) 64 if o.offer_id == offer_id { return i as i64 } 65 i = i + 1 66 } 67 return -1 68} 69 70// open a PENDING outreach record for a prospective target (additive). 71func nx_offer_open(l: *NxOfferLedger, offer_id: nx_int, target_bk: nx_int, contact_ref: nx_int, now_us: nx_size) -> nx_int { 72 if l.count >= l.capacity { return NX_OF_ERR_FULL } 73 let o: *NxOffer = _of_at(l, l.count) 74 o.offer_id = offer_id 75 o.target_bk = target_bk 76 o.contact_ref = contact_ref 77 o.state = NX_OF_PENDING 78 o.opened_us = now_us 79 o.decided_us = 0 80 l.count = l.count + 1 81 return NX_OF_OK 82} 83 84// PENDING -> SENT (offer made to the agent/contact). 85func nx_offer_send(l: *NxOfferLedger, offer_id: nx_int, now_us: nx_size) -> nx_int { 86 let idx: nx_int = _of_find(l, offer_id) 87 if idx < 0 { return NX_OF_ERR_NOT_FOUND } 88 let o: *NxOffer = _of_at(l, idx as nx_size) 89 if o.state != NX_OF_PENDING { return NX_OF_ERR_BAD_TRANSITION } 90 o.state = NX_OF_SENT 91 return NX_OF_OK 92} 93 94// SENT -> ACCEPTED (they agreed; caller then mints the license). 95func nx_offer_accept(l: *NxOfferLedger, offer_id: nx_int, now_us: nx_size) -> nx_int { 96 let idx: nx_int = _of_find(l, offer_id) 97 if idx < 0 { return NX_OF_ERR_NOT_FOUND } 98 let o: *NxOffer = _of_at(l, idx as nx_size) 99 if o.state != NX_OF_SENT { return NX_OF_ERR_BAD_TRANSITION } 100 o.state = NX_OF_ACCEPTED 101 o.decided_us = now_us 102 return NX_OF_OK 103} 104 105// PENDING or SENT -> DECLINED. 106func nx_offer_decline(l: *NxOfferLedger, offer_id: nx_int, now_us: nx_size) -> nx_int { 107 let idx: nx_int = _of_find(l, offer_id) 108 if idx < 0 { return NX_OF_ERR_NOT_FOUND } 109 let o: *NxOffer = _of_at(l, idx as nx_size) 110 if o.state == NX_OF_ACCEPTED { return NX_OF_ERR_BAD_TRANSITION } 111 if o.state == NX_OF_DECLINED { return NX_OF_ERR_BAD_TRANSITION } 112 o.state = NX_OF_DECLINED 113 o.decided_us = now_us 114 return NX_OF_OK 115} 116 117func nx_offer_state(l: *NxOfferLedger, offer_id: nx_int) -> nx_int { 118 let idx: nx_int = _of_find(l, offer_id) 119 if idx < 0 { return -1 } 120 let o: *NxOffer = _of_at(l, idx as nx_size) 121 return o.state 122} 123 124// is there an ACCEPTED offer for this target? 125func nx_offer_is_accepted(l: *NxOfferLedger, target_bk: nx_int) -> nx_int { 126 var i: nx_size = 0 127 while i < l.count { 128 let o: *NxOffer = _of_at(l, i) 129 if o.target_bk == target_bk { 130 if o.state == NX_OF_ACCEPTED { return 1 } 131 } 132 i = i + 1 133 } 134 return 0 135} 136 137func nx_offer_count_by_state(l: *NxOfferLedger, state: nx_int) -> nx_int { 138 var hits: nx_int = 0 139 var i: nx_size = 0 140 while i < l.count { 141 let o: *NxOffer = _of_at(l, i) 142 if o.state == state { hits = hits + 1 } 143 i = i + 1 144 } 145 return hits 146}