MaxBodyLen
untyped bigint// post body (roadmap 4.1)
Value
(1000 <untyped> bigint)
MaxMediaCIDs
untyped bigint// stored per post; pin/serve pipeline is P2
Value
(4 <untyped> bigint)
MaxCIDLen
untyped bigint// defensive cap on a single CID string
Value
(128 <untyped> bigint)
FeedPageSize
untyped bigint// posts per rendered page / default JSON window
Value
(20 <untyped> bigint)
MaxPageLimit
untyped bigint// hard cap on any JSON read window (DoS guard)
Value
(100 <untyped> bigint)
MaxRenderPage
untyped bigint// deepest gnoweb page; beyond → use the cursor API
Value
(50 <untyped> bigint)
MaxRepliesPerPost
untyped bigintValue
(500 <untyped> bigint)
FlagThreshold
untyped bigint// unique flags before auto-hide
Value
(5 <untyped> bigint)
MinAccountAgeForFlag
untyped bigint// blocks since first post (~1-2h)
Value
(1200 <untyped> bigint)
FlagsPerDayBudget
untyped bigint// per address per BlocksPerDay window
Value
(10 <untyped> bigint)
BlocksPerDay
untyped bigint// ~5s blocks; approximation is fine
Value
(17280 <untyped> bigint)
MinPostIntervalBlocks
untyped bigintValue
(2 <untyped> bigint)
YoungMinPostIntervalBlocks
untyped bigintValue
(12 <untyped> bigint)
YoungAccountBlocks
untyped bigint// first ~day
Value
(17280 <untyped> bigint)
Post
typeValue
memba_feed_v1.Post
flagBudget
typeValue
memba_feed_v1.flagBudget
posts
*avl.Tree// padID(id) -> \*Post (live + hidden + not-yet-swept tombstones)
- OID
- 0a00bd…f2d6:78
posts details
liveFeed
*avl.Tree// padID(id) -> true
- OID
- 0a00bd…f2d6:80
liveFeed details
byAuthor
*avl.Tree// author + ":" + padID(id) -> true
- OID
- 0a00bd…f2d6:82
byAuthor details
byParent
*avl.Tree// padID(parent) + ":" + padID(child) -> true
- OID
- 0a00bd…f2d6:84
byParent details
liveCount
uint64// number of keys in liveFeed
Value
0
replyCount
*avl.Tree// padID(parent) -> uint64 (live replies)
- OID
- 0a00bd…f2d6:86
replyCount details
nextPostID
uint64// monotonic; NEVER iterated by reads
Value
1
lastPostH
*avl.Tree// addr -> int64 (last CreatePost height)
- OID
- 0a00bd…f2d6:88
lastPostH details
firstSeenH
*avl.Tree// addr -> int64 (first write interaction height)
- OID
- 0a00bd…f2d6:90
firstSeenH details
flags
*avl.Tree// padID(id) -> \*avl.Tree (flagger addr -> true)
- OID
- 0a00bd…f2d6:92
flags details
flagSpend
*avl.Tree// addr -> \*flagBudget
- OID
- 0a00bd…f2d6:94
flagSpend details
reactions
*avl.Tree- OID
- 0a00bd…f2d6:96
reactions details
tombstones
*avl.Tree// padID(id) -> true
- OID
- 0a00bd…f2d6:100
tombstones details
moderators
*avl.Tree- OID
- 0a00bd…f2d6:98
moderators details
paused
boolValue
false
owner
.uverse.addressValue
<gnolang.StringValue>
init.32
func()- OID
- 0a00bd…f2d6:19
init.32 details
padID
func(id uint64) stringpadID zero-pads to 12 digits so AVL string order == numeric order. 12 digits ≥ 31,000 years of one post per block — effectively unbounded.
- OID
- 0a00bd…f2d6:21
padID details
getPost
func(id uint64) (*memba_feed_v1.Post, bool)- OID
- 0a00bd…f2d6:22
getPost details
mustGetPost
func(id uint64) *memba_feed_v1.Post- OID
- 0a00bd…f2d6:23
mustGetPost details
authorKey
func(addr .uverse.address, id uint64) string- OID
- 0a00bd…f2d6:24
authorKey details
parentKey
func(parent uint64, child uint64) string- OID
- 0a00bd…f2d6:25
parentKey details
getReplyCount
func(parent uint64) uint64- OID
- 0a00bd…f2d6:26
getReplyCount details
addToLiveIndexes
func(p *memba_feed_v1.Post)addToLiveIndexes registers a visible post in every live index (B1). A reply is only linked into its parent's byParent/replyCount indexes when the parent is still LIVE. On CreatePost the parent was just verified live, so this is always true there. The guard matters on the UnhidePost re-add path: if the parent was deleted+swept while the reply sat hidden, re-linking would recreate an orphan byParent/replyCount entry under a parent id no longer in \`posts\` (never sweepable again) — the exact leak SweepTombstones' byParent-prefix cleanup was added to prevent. An unhidden reply whose parent is gone simply becomes standalone live content, which is how a reply to a removed parent is already treated everywhere else.
- OID
- 0a00bd…f2d6:27
addToLiveIndexes details
removeFromLiveIndexes
func(p *memba_feed_v1.Post)removeFromLiveIndexes drops a post from every live index (hide/delete).
- OID
- 0a00bd…f2d6:28
removeFromLiveIndexes details
assertNotPaused
func()- OID
- 0a00bd…f2d6:29
assertNotPaused details
assertCallerIsOwner
func()- OID
- 0a00bd…f2d6:30
assertCallerIsOwner details
touchFirstSeen
func(addr .uverse.address, h int64)touchFirstSeen records the first write interaction height for an address.
- OID
- 0a00bd…f2d6:31
touchFirstSeen details
accountAge
func(addr .uverse.address, now int64) int64- OID
- 0a00bd…f2d6:32
accountAge details
PauseRealm
func()- OID
- 0a00bd…f2d6:33
PauseRealm details
UnpauseRealm
func()- OID
- 0a00bd…f2d6:34
UnpauseRealm details
IsPaused
func() bool- OID
- 0a00bd…f2d6:35
IsPaused details
TransferOwnership
func(newOwner .uverse.address)TransferOwnership moves realm ownership (deployer multisig rotation).
- OID
- 0a00bd…f2d6:36
TransferOwnership details
GetOwner
func() .uverse.address- OID
- 0a00bd…f2d6:37
GetOwner details
CreatePost
func(body string, replyTo uint64) uint64CreatePost publishes a post (replyTo == 0) or a reply (replyTo == parent id). Open write: any wallet, subject to the block cooldown and body caps. Returns the new post id.
- OID
- 0a00bd…f2d6:38
CreatePost details
EditPost
func(id uint64, newBody string)EditPost lets the author replace the body of a visible post.
- OID
- 0a00bd…f2d6:39
EditPost details
DeletePost
func(id uint64)DeletePost soft-deletes the author's own post: content cleared, dropped from every live index (frees render slots immediately — B1), queued for hard-GC (B2). Replies stay: they render as replies to an unavailable post.
- OID
- 0a00bd…f2d6:40
DeletePost details
FlagPost
func(id uint64)FlagPost files a community flag. Guards, in order: - flag rights are EARNED BY PARTICIPATION: the caller must have a firstSeen record (anchored by their first successful CreatePost) at least MinAccountAgeForFlag blocks old. A failed flag cannot anchor age itself — an on-chain abort reverts every write in the tx, so recording firstSeen here and then panicking would revert the record and deadlock pure flaggers; requiring a prior post is the honest, implementable account-age gate (realms cannot query global account age); - one flag per address per post; - per-day flag budget per address (blunts coordinated flag-brigades). At FlagThreshold unique flags the post auto-hides (reversible via UnhidePost).
- OID
- 0a00bd…f2d6:41
FlagPost details
reactionEmojis
[]stringreactionEmojis is the fixed on-chain reaction set. Changing it is a realm version bump (redeploy), so it is deliberately small and stable.
- OID
- 0a00bd…f2d6:43
reactionEmojis details
isReactionEmoji
func(e string) bool- OID
- 0a00bd…f2d6:44
isReactionEmoji details
reactionSubKey
func(emoji string, addr .uverse.address) stringreactionSubKey namespaces a reactor's entry within a post's reaction tree. The NUL separator cannot appear in a fixed-set emoji or a bech32 address, so (emoji, addr) round-trips unambiguously.
- OID
- 0a00bd…f2d6:45
reactionSubKey details
HasReacted
func(id uint64, emoji string, addr .uverse.address) boolHasReacted reports whether addr currently has the given emoji on the post. O(log n) point lookup — never a scan.
- OID
- 0a00bd…f2d6:46
HasReacted details
AddReaction
func(id uint64, emoji string)AddReaction records the caller's emoji reaction. A repeat aborts (rather than no-op) so an optimistic client's double-tap cannot silently burn gas twice — the client gates the button on HasReacted / indexed state.
- OID
- 0a00bd…f2d6:47
AddReaction details
RemoveReaction
func(id uint64, emoji string)RemoveReaction removes the caller's emoji reaction (toggle-off). Allowed even on a hidden/deleted post so a reactor can always retract; aborts if the caller had not reacted with that emoji.
- OID
- 0a00bd…f2d6:48
RemoveReaction details
assertCallerIsOwnerOrModerator
func()- OID
- 0a00bd…f2d6:49
assertCallerIsOwnerOrModerator details
IsModerator
func(addr .uverse.address) boolIsModerator reports whether addr currently holds the moderator role.
- OID
- 0a00bd…f2d6:50
IsModerator details
AddModerator
func(addr .uverse.address)AddModerator grants the moderator role (owner only).
- OID
- 0a00bd…f2d6:51
AddModerator details
RemoveModerator
func(addr .uverse.address)RemoveModerator revokes the moderator role (owner only).
- OID
- 0a00bd…f2d6:52
RemoveModerator details
ModRemovePost
func(id uint64)ModRemovePost permanently hides a post by moderation. Emits an audited ModAction. The node is tombstoned for hard-GC like an author delete.
- OID
- 0a00bd…f2d6:53
ModRemovePost details
UnhidePost
func(id uint64)UnhidePost clears flags and restores a flag-hidden post to the live set.
- OID
- 0a00bd…f2d6:54
UnhidePost details
SweepTombstones
func(limit int) intSweepTombstones hard-removes up to \`limit\` soft-deleted posts, reclaiming AVL storage so post+delete spam cannot accrete permanent state. Permissionless by design (state-shrink hygiene primitive, not a refund path). Bounded + idempotent: keep \`limit\` small (1-10); re-running drains the next batch and stops at 0. Returns the number of posts swept. For a swept post that was a PARENT, its surviving replies' byParent links (\`padID(parent):padID(child)\`) would otherwise be orphaned under an id no longer in \`posts\` — a permanent leak plus a read inconsistency (replies still enumerable, getReplyCount() disagreeing). So the sweep range-deletes that byParent prefix; the reply posts themselves stay as standalone live content (their parent was removed by its own author). Bounded because the live reply set per post is capped at MaxRepliesPerPost — but a reply-heavy parent makes one sweep step do up to that many removes, so keep \`limit\` small (1) when draining known reply-heavy tombstones.
- OID
- 0a00bd…f2d6:55
SweepTombstones details
GetTombstoneCount
func() intGetTombstoneCount returns how many soft-deleted posts await hard-GC.
- OID
- 0a00bd…f2d6:56
GetTombstoneCount details
jsonEscape
func(s string) stringjsonEscape escapes a string for embedding in a JSON string literal.
- OID
- 0a00bd…f2d6:57
jsonEscape details
postJSON
func(p *memba_feed_v1.Post) stringpostJSON is the qeval read fallback. Note it exposes \`mediaCids\` (P2) and \`repostOf\` (P1) which the CANONICAL indexed path (chain.Emit → backend → feed\_rpc → UI) does NOT carry yet — PostCreated emits neither, the proto reserves repost\_of, and there is no media column. A future dev wiring the qeval fallback must not assume those two are plumbed end-to-end.
- OID
- 0a00bd…f2d6:58
postJSON details
boolStr
func(b bool) string- OID
- 0a00bd…f2d6:59
boolStr details
clampLimit
func(limit int) int- OID
- 0a00bd…f2d6:60
clampLimit details
GetPostJSON
func(id uint64) stringGetPostJSON returns one post (any state — the indexer needs tombstones too).
- OID
- 0a00bd…f2d6:61
GetPostJSON details
listWindow
func(tree *avl.Tree, cursorKey string, limit int, extract func(...)) []uint64listWindow walks \`tree\` REVERSE (newest first) starting below cursorKey ("" = from the newest), collecting up to limit ids via extract.
- OID
- 0a00bd…f2d6:62
listWindow details
idFromPadded
func(key string) uint64- OID
- 0a00bd…f2d6:63
idFromPadded details
idFromComposite
func(key string) uint64- OID
- 0a00bd…f2d6:64
idFromComposite details
idsToJSON
func(ids []uint64) string- OID
- 0a00bd…f2d6:65
idsToJSON details
ListFeedJSON
func(cursor uint64, limit int) stringListFeedJSON returns the newest live posts strictly older than cursor (cursor == 0 → from the top). Pass the last id of the previous window as the next cursor. ReverseIterate treats BOTH bounds as inclusive (avl/v0 TraverseInRange), so "strictly older than cursor" = end bound padID(cursor-1): ids are integers, keys are fixed-width, hence key \< padID(cursor) ⟺ key ≤ padID(cursor-1).
- OID
- 0a00bd…f2d6:66
ListFeedJSON details
ListUserJSON
func(addr string, cursor uint64, limit int) stringListUserJSON returns a user's newest live posts strictly older than cursor (same inclusive-bound rule as ListFeedJSON).
- OID
- 0a00bd…f2d6:67
ListUserJSON details
ListRepliesJSON
func(parent uint64, cursor uint64, limit int) stringListRepliesJSON returns a post's live replies, OLDEST first (conversation order), starting strictly after cursor (0 → from the beginning).
- OID
- 0a00bd…f2d6:68
ListRepliesJSON details
GetStatsJSON
func() stringGetStatsJSON returns realm-level counters (monotonic id is informational — no read iterates it).
- OID
- 0a00bd…f2d6:69
GetStatsJSON details
Render
func(path string) string- OID
- 0a00bd…f2d6:70
Render details
collectPage
func(tree *avl.Tree, prefix string, endKey string, k uint64) []uint64collectPage walks a live index reverse and returns the ids for window k (1-based). Scan is bounded: k is capped at MaxRenderPage by callers.
- OID
- 0a00bd…f2d6:71
collectPage details
renderPostLine
func(sb *strings.Builder, p *memba_feed_v1.Post)- OID
- 0a00bd…f2d6:72
renderPostLine details
renderFeedPage
func(k uint64) string- OID
- 0a00bd…f2d6:73
renderFeedPage details
renderUserPage
func(addr string, k uint64) string- OID
- 0a00bd…f2d6:74
renderUserPage details
renderPost
func(id uint64) string- OID
- 0a00bd…f2d6:75
renderPost details
truncAddr
func(addr .uverse.address) string- OID
- 0a00bd…f2d6:76
truncAddr details
sanitizeForRender
func(s string) stringsanitizeForRender strips markdown-sensitive characters to prevent injection.
- OID
- 0a00bd…f2d6:77