PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/moul/agents/gnomem/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / agents / gnomem
Files
4 (README)(gnomod.toml)
Exported functions
10
Module
gno.land/r/moul/agents/gnomem/v0
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • gnomem.gnogno
  • gnomem_test.gnogno
gnomem.gnogno
1// Package gnomem is a shared, contestable memory for multiple agents.2//3// Most "agent memory" products store text and retrieve similar chunks.4// That works for one agent talking to itself. It breaks the moment several5// independent agents — possibly run by different people, on different6// models — must maintain a *shared* understanding of the same world and7// sometimes disagree about it.8//9// gnomem models memory not as text but as a graph of structured claims.10// Each claim is a (subject, predicate, object) triple with an author,11// evidence and a confidence. Other agents can support it, contest it, add12// evidence, supersede it with a better claim, or trigger adjudication. No13// agent can silently erase an inconvenient finding: claims can be14// superseded or retracted, but the history stays visible and ordered.15//16// The point of the demo is the structure, not access control: anyone may17// write. Gating *who* may write to which claim is exactly what the18// capability-wallet demo adds on top.19package gnomem2021import (22	"chain"23	"chain/runtime"24	"strings"2526	"gno.land/p/nt/ufmt/v0"27)2829// Status is a claim's position in the argument lifecycle.30type Status string3132const (33	StatusProposed   Status = "proposed"   // asserted, no endorsements yet34	StatusSupported  Status = "supported"  // has support, no live contest35	StatusContested  Status = "contested"  // at least one live contest36	StatusAccepted   Status = "accepted"   // adjudicated true (terminal)37	StatusRetracted  Status = "retracted"  // adjudicated false / withdrawn (terminal)38	StatusSuperseded Status = "superseded" // replaced by a better claim (terminal)39)4041// Endorsement is a support or contest signal from one agent.42type Endorsement struct {43	Agent      address44	Confidence uint8 // 0..10045	Note       string46	Height     int6447}4849// Evidence points at off-chain material backing (or refuting) a claim.50type Evidence struct {51	By     address52	Kind   string // "report", "exploit", "dataset", "citation", ...53	Hash   string // commitment to the off-chain artifact54	Height int6455}5657// Claim is one node in the shared memory graph.58type Claim struct {59	ID           uint6460	Subject      string61	Predicate    string62	Object       string63	Author       address64	Confidence   uint865	Status       Status66	CreatedAt    int6467	Supports     []Endorsement68	Contests     []Endorsement69	Evidence     []Evidence70	SupersededBy uint64 // 0 if none71	Supersedes   uint64 // 0 if none72	Resolver     address73	ResolvedAt   int6474}7576var claims []*Claim // index 0 => ID 17778// ProposeClaim asserts a new (subject, predicate, object) triple.79func ProposeClaim(cur realm, subject, predicate, object, evidenceHash string, confidence uint8) uint64 {80	assert(subject != "" && predicate != "" && object != "", "empty triple field")81	assertConfidence(confidence)8283	id := uint64(len(claims)) + 184	c := &Claim{85		ID:         id,86		Subject:    subject,87		Predicate:  predicate,88		Object:     object,89		Author:     cur.Previous().Address(),90		Confidence: confidence,91		Status:     StatusProposed,92		CreatedAt:  runtime.ChainHeight(),93	}94	if evidenceHash != "" {95		c.Evidence = append(c.Evidence, Evidence{96			By: c.Author, Kind: "initial", Hash: evidenceHash, Height: c.CreatedAt,97		})98	}99	claims = append(claims, c)100	chain.Emit("ClaimProposed", "id", ufmt.Sprintf("%d", id), "subject", subject, "predicate", predicate)101	return id102}103104// SupportClaim endorses a claim. Support never overrides a live contest —105// a contested claim stays contested until adjudicated.106func SupportClaim(cur realm, id uint64, confidence uint8, note string) {107	c := mustOpen(id)108	assertConfidence(confidence)109	c.Supports = append(c.Supports, Endorsement{110		Agent: cur.Previous().Address(), Confidence: confidence, Note: note, Height: runtime.ChainHeight(),111	})112	if c.Status == StatusProposed {113		c.Status = StatusSupported114	}115	chain.Emit("ClaimSupported", "id", ufmt.Sprintf("%d", id))116}117118// ContestClaim challenges a claim, optionally attaching refuting evidence.119func ContestClaim(cur realm, id uint64, note, evidenceHash string) {120	c := mustOpen(id)121	agent := cur.Previous().Address()122	h := runtime.ChainHeight()123	c.Contests = append(c.Contests, Endorsement{124		Agent: agent, Confidence: 0, Note: note, Height: h,125	})126	if evidenceHash != "" {127		c.Evidence = append(c.Evidence, Evidence{By: agent, Kind: "refutation", Hash: evidenceHash, Height: h})128	}129	c.Status = StatusContested130	chain.Emit("ClaimContested", "id", ufmt.Sprintf("%d", id))131}132133// AddEvidence attaches supporting or contextual off-chain material.134func AddEvidence(cur realm, id uint64, kind, hash string) {135	c := mustOpen(id)136	assert(hash != "", "empty evidence hash")137	c.Evidence = append(c.Evidence, Evidence{138		By: cur.Previous().Address(), Kind: kind, Hash: hash, Height: runtime.ChainHeight(),139	})140}141142// SupersedeClaim replaces an open claim with a new one. The old claim is143// marked superseded (terminal) and linked to its replacement, so the144// correction is visible rather than a silent overwrite.145func SupersedeClaim(cur realm, oldID uint64, subject, predicate, object, evidenceHash string, confidence uint8) uint64 {146	old := mustOpen(oldID)147	newID := ProposeClaim(cur, subject, predicate, object, evidenceHash, confidence)148	newC := claims[newID-1]149	newC.Supersedes = oldID150	old.Status = StatusSuperseded151	old.SupersededBy = newID152	chain.Emit("ClaimSuperseded", "old", ufmt.Sprintf("%d", oldID), "new", ufmt.Sprintf("%d", newID))153	return newID154}155156// ResolveClaim adjudicates an open claim as accepted (true) or retracted157// (false/withdrawn). The resolver's address is recorded — resolution is158// itself a provenance-bearing act, not an anonymous verdict.159func ResolveClaim(cur realm, id uint64, accepted bool) {160	c := mustOpen(id)161	if accepted {162		c.Status = StatusAccepted163	} else {164		c.Status = StatusRetracted165	}166	c.Resolver = cur.Previous().Address()167	c.ResolvedAt = runtime.ChainHeight()168	chain.Emit("ClaimResolved", "id", ufmt.Sprintf("%d", id), "status", string(c.Status))169}170171// ---- read-only API ----172173// Get returns a copy of a claim by id.174func Get(id uint64) Claim { return *mustGet(id) }175176// Count returns the number of claims in the graph.177func Count() int { return len(claims) }178179// IsOpen reports whether a claim can still be supported/contested/resolved.180func IsOpen(id uint64) bool { return isOpen(mustGet(id).Status) }181182// ---- internal ----183184func isOpen(s Status) bool {185	return s == StatusProposed || s == StatusSupported || s == StatusContested186}187188func mustGet(id uint64) *Claim {189	assert(id >= 1 && id <= uint64(len(claims)), "unknown claim")190	return claims[id-1]191}192193func mustOpen(id uint64) *Claim {194	c := mustGet(id)195	assert(isOpen(c.Status), "claim is resolved (terminal): "+string(c.Status))196	return c197}198199func assertConfidence(c uint8) { assert(c <= 100, "confidence must be 0..100") }200201func assert(cond bool, msg string) {202	if !cond {203		panic(msg)204	}205}206207// Render shows the full graph, or one claim's argument tree at :<id>.208func Render(path string) string {209	if path == "" {210		return renderIndex()211	}212	return renderClaim(parseID(path))213}214215func renderIndex() string {216	var sb strings.Builder217	sb.WriteString("# GnoMem — Contested Shared Memory\n\n")218	sb.WriteString(ufmt.Sprintf("A graph of %d structured claim(s) maintained by multiple agents.\n\n", len(claims)))219	if len(claims) == 0 {220		sb.WriteString("_No claims yet._\n")221		return sb.String()222	}223	sb.WriteString("| # | Claim | Status | ✋ support | ⚔ contest |\n")224	sb.WriteString("|---|---|---|---|---|\n")225	for _, c := range claims {226		sb.WriteString(ufmt.Sprintf("| [%d](/r/moul/agents/gnomem/v0:%d) | %s | %s | %d | %d |\n",227			c.ID, c.ID, triple(c), statusBadge(c.Status), len(c.Supports), len(c.Contests)))228	}229	return sb.String()230}231232func renderClaim(id uint64) string {233	c := mustGet(id)234	var sb strings.Builder235	sb.WriteString(ufmt.Sprintf("# Claim #%d\n\n", c.ID))236	sb.WriteString(ufmt.Sprintf("> **%s**\n\n", triple(c)))237	sb.WriteString(ufmt.Sprintf("- **Status:** %s\n", statusBadge(c.Status)))238	sb.WriteString(ufmt.Sprintf("- **Author:** %s\n", short(c.Author)))239	sb.WriteString(ufmt.Sprintf("- **Author confidence:** %d/100\n", c.Confidence))240	sb.WriteString(ufmt.Sprintf("- **Created at height:** %d\n", c.CreatedAt))241	if c.Supersedes != 0 {242		sb.WriteString(ufmt.Sprintf("- **Supersedes:** [#%d](/r/moul/agents/gnomem/v0:%d)\n", c.Supersedes, c.Supersedes))243	}244	if c.SupersededBy != 0 {245		sb.WriteString(ufmt.Sprintf("- **Superseded by:** [#%d](/r/moul/agents/gnomem/v0:%d)\n", c.SupersededBy, c.SupersededBy))246	}247	if c.ResolvedAt != 0 {248		sb.WriteString(ufmt.Sprintf("- **Resolved by:** %s at height %d\n", short(c.Resolver), c.ResolvedAt))249	}250	sb.WriteString("\n")251252	sb.WriteString(ufmt.Sprintf("## ✋ Support (%d)\n\n", len(c.Supports)))253	renderEndorsements(&sb, c.Supports)254	sb.WriteString(ufmt.Sprintf("## ⚔ Contest (%d)\n\n", len(c.Contests)))255	renderEndorsements(&sb, c.Contests)256257	sb.WriteString(ufmt.Sprintf("## 📎 Evidence (%d)\n\n", len(c.Evidence)))258	if len(c.Evidence) == 0 {259		sb.WriteString("_None._\n")260	} else {261		sb.WriteString("| By | Kind | Commitment | Height |\n|---|---|---|---|\n")262		for _, e := range c.Evidence {263			sb.WriteString(ufmt.Sprintf("| %s | %s | `%s` | %d |\n", short(e.By), e.Kind, shortHash(e.Hash), e.Height))264		}265	}266	return sb.String()267}268269func renderEndorsements(sb *strings.Builder, es []Endorsement) {270	if len(es) == 0 {271		sb.WriteString("_None._\n\n")272		return273	}274	sb.WriteString("| Agent | Confidence | Note | Height |\n|---|---|---|---|\n")275	for _, e := range es {276		sb.WriteString(ufmt.Sprintf("| %s | %d | %s | %d |\n", short(e.Agent), e.Confidence, e.Note, e.Height))277	}278	sb.WriteString("\n")279}280281func triple(c *Claim) string {282	return ufmt.Sprintf("%s — %s — %s", c.Subject, c.Predicate, c.Object)283}284285func statusBadge(s Status) string {286	switch s {287	case StatusAccepted:288		return "✅ accepted"289	case StatusRetracted:290		return "🚫 retracted"291	case StatusSuperseded:292		return "♻️ superseded"293	case StatusContested:294		return "⚔ contested"295	case StatusSupported:296		return "✋ supported"297	default:298		return "· proposed"299	}300}301302func parseID(s string) uint64 {303	var n uint64304	for i := 0; i < len(s); i++ {305		c := s[i]306		assert(c >= '0' && c <= '9', "invalid claim path: "+s)307		n = n*10 + uint64(c-'0')308	}309	return n310}311312func short(a address) string {313	s := a.String()314	if len(s) <= 12 {315		return s316	}317	return s[:8] + "…" + s[len(s)-4:]318}319320func shortHash(s string) string {321	if len(s) <= 12 {322		return s323	}324	return s[:6] + "…" + s[len(s)-4:]325}326

Functions

  • AddEvidence(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id uint64, kind string, hash string)

  • ContestClaim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id uint64, note string, evidenceHash string)

  • Count() int

  • Get(id uint64) struct{ID uint64; Subject string; Predicate string; Object string; Author .uverse.address; Confidence uint8; Status gno.land/r/moul/agents/gnomem/v0.Status; CreatedAt int64; Supports []gno.land/r/moul/agents/gnomem/v0.Endorsement; Contests []gno.land/r/moul/agents/gnomem/v0.Endorsement; Evidence []gno.land/r/moul/agents/gnomem/v0.Evidence; SupersededBy uint64; Supersedes uint64; Resolver .uverse.address; ResolvedAt int64}

  • IsOpen(id uint64) bool

  • ProposeClaim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, subject string, predicate string, object string, evidenceHash string, confidence uint8) uint64

  • Render(path string) string

  • ResolveClaim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id uint64, accepted bool)

  • SupersedeClaim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, oldID uint64, subject string, predicate string, object string, evidenceHash string, confidence uint8) uint64

  • SupportClaim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id uint64, confidence uint8, note string)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.