forum trust circle: trust-gated content exchange via subscription graph

readme: document trust circle design

readme: tone down trust circle language to match existing style

remove forum_enabled toggle: subscribing IS trusting, no intermediate state
This commit is contained in:
blankie 2026-06-17 19:10:32 +00:00
parent 6f700c213f
commit f680931c8c
5 changed files with 232 additions and 17 deletions

View file

@ -105,6 +105,20 @@ class ForumDB:
db.execute("ALTER TABLE synced_instances ADD COLUMN consecutive_failures INTEGER DEFAULT 0")
except Exception:
pass
db.execute(
"CREATE TABLE IF NOT EXISTS forum_trust_sources ("
" instance_hash TEXT NOT NULL,"
" source_hash TEXT NOT NULL,"
" hops INTEGER NOT NULL,"
" PRIMARY KEY (instance_hash, source_hash)"
")"
)
db.execute(
"CREATE TABLE IF NOT EXISTS forum_trust ("
" instance_hash TEXT PRIMARY KEY,"
" min_hops INTEGER NOT NULL"
")"
)
db.commit()
db.close()
@ -676,6 +690,106 @@ class ForumDB:
finally:
self.return_db(db)
# --- Forum Trust ---
def add_trust_source(self, instance_hash, source_hash, hops):
db = self.get_db()
try:
db.execute(
"INSERT OR IGNORE INTO forum_trust_sources "
"(instance_hash, source_hash, hops) VALUES (?, ?, ?)",
(instance_hash, source_hash, hops),
)
existing = db.execute(
"SELECT hops FROM forum_trust_sources "
"WHERE instance_hash=? AND source_hash=?",
(instance_hash, source_hash),
).fetchone()
if existing and hops < existing["hops"]:
db.execute(
"UPDATE forum_trust_sources SET hops=? "
"WHERE instance_hash=? AND source_hash=?",
(hops, instance_hash, source_hash),
)
self._recompute_trust_view(db)
db.commit()
finally:
self.return_db(db)
def remove_trust_source(self, source_hash):
db = self.get_db()
try:
rows = db.execute(
"WITH RECURSIVE cascade(h) AS ("
" VALUES(?)"
" UNION ALL"
" SELECT fts.instance_hash FROM forum_trust_sources fts"
" INNER JOIN cascade c ON fts.source_hash = c.h"
") SELECT h FROM cascade",
(source_hash,),
).fetchall()
cascade_hashes = [r["h"] for r in rows]
placeholders = ",".join("?" for _ in cascade_hashes)
db.execute(
f"DELETE FROM forum_trust_sources WHERE source_hash IN ({placeholders})",
cascade_hashes,
)
self._recompute_trust_view(db)
db.commit()
finally:
self.return_db(db)
def remove_by_hash(self, instance_hash):
self.remove_trust_source(instance_hash)
db = self.get_db()
try:
db.execute(
"DELETE FROM forum_trust_sources WHERE instance_hash=?",
(instance_hash,),
)
self._recompute_trust_view(db)
db.commit()
finally:
self.return_db(db)
def is_trusted(self, instance_hash):
db = self.get_db()
try:
row = db.execute(
"SELECT 1 FROM forum_trust WHERE instance_hash=?", (instance_hash,)
).fetchone()
return row is not None
finally:
self.return_db(db)
def get_trust_hops(self, instance_hash):
db = self.get_db()
try:
row = db.execute(
"SELECT min_hops FROM forum_trust WHERE instance_hash=?", (instance_hash,)
).fetchone()
return row["min_hops"] if row else None
finally:
self.return_db(db)
def get_all_trusted_hashes(self):
db = self.get_db()
try:
return [
r["instance_hash"] for r in db.execute(
"SELECT instance_hash FROM forum_trust"
).fetchall()
]
finally:
self.return_db(db)
def _recompute_trust_view(self, db):
db.execute("DELETE FROM forum_trust")
db.execute(
"INSERT INTO forum_trust (instance_hash, min_hops) "
"SELECT instance_hash, MIN(hops) FROM forum_trust_sources GROUP BY instance_hash"
)
# --- Peer Liveness ---
def record_sync_result(self, peer_hash, success):