Skip to content

Commit 61dc162

Browse files
author
Kevan
committed
refactor: bond → link — full terminology rename + architecture docs
WHAT CHANGED: - Renamed 'bond' to 'link' across entire codebase (social graph edge, not financial bond) - models/bond.py → models/link.py (Bond → Link class) - API: /api/field/bond → /api/field/link - Config: FIELD_MAX_BONDS → FIELD_MAX_LINKS, BOND_STATE_* → LINK_STATE_* - Schemas: BondCreateSchema → LinkCreateSchema - DB table: bonds → links, column: bond_count → link_count - _bond_founders.py → _link_founders.py FILES MODIFIED (22): Python: app.py, config.py, models/{link,member,__init__}.py, core/{network,rewards,identity,validation,node_telemetry, energy_exchange}.py, api/routes.py, ai/ask_helios.py, _bootstrap_founders.py, _link_founders.py, _verify_client_ready.py JS: static/js/{network-viz,static-fallback}.js HTML: templates/{earnings,network}.html Docs: README.md, SYSTEM_MAP.md, REPO_OVERVIEW.md NEW DOCUMENTS (4): docs/SYSTEM_STATE_AUDIT.md — Full 42-file audit with risk register docs/HELIOS_ARCHITECTURE_MAP.md — Three-module architecture diagram docs/TERMINOLOGY_REFACTOR_PLAN.md — Rename rationale and execution plan docs/ISSUANCE_LAYER_BLUEPRINT.md — Future issuance layer gate checklist DATABASE: Rebuilt fresh with 13 founders + 26 links (new schema) VERIFIED: All 12 client readiness tests pass
1 parent cffbb67 commit 61dc162

27 files changed

Lines changed: 1295 additions & 362 deletions

README.md

Lines changed: 65 additions & 65 deletions
Large diffs are not rendered by default.

REPO_OVERVIEW.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Working tree: **clean**
5555

5656
| Module | Class / Role |
5757
|---|---|
58-
| `network.py` | `FieldEngine` — Power of 5, BFS field traversal, bond creation |
58+
| `network.py` | `FieldEngine` — Power of 5, BFS field traversal, link creation |
5959
| `energy_exchange.py` | `EnergyExchange` — conservation law, $100 atomic split |
6060
| `rewards.py` | `PropagationEngine` — 3-phase settlement, hop decay |
6161
| `certificates.py` | `CertificateEngine` — HC-NFT mint/redeem/cancel, RRR covenant |
@@ -91,7 +91,7 @@ Working tree: **clean**
9191
| Model | State Machine | Role |
9292
|---|---|---|
9393
| `member.py` | 5 states (instantiated → stable) | Node in the field |
94-
| `bond.py` | 4 states | Undirected peer bond (ordered pair, unique constraint) |
94+
| `link.py` | 4 states | Undirected peer link (ordered pair, unique constraint) |
9595
| `certificate.py` | 3 states (active → redeemed / cancelled) | HC-NFT stored energy battery |
9696
| `vault_receipt.py` | 4 states (MVR custody FSM) | Physical metal receipt |
9797
| `energy_event.py` || Immutable ledger (7 event types) |
@@ -112,7 +112,7 @@ Working tree: **clean**
112112
| Blueprint | Prefix | Key endpoints |
113113
|---|---|---|
114114
| `identity_bp` | `/api/identity` | create, verify, recover, QR |
115-
| `field_bp` | `/api/field` | bond, dissolve, graph, status |
115+
| `field_bp` | `/api/field` | link, dissolve, graph, status |
116116
| `network_bp` | `/api/network` | field traversal, BFS graph |
117117
| `energy_bp` | `/api/energy` | inject, propagate, conservation |
118118
| `wallet_bp` | `/api/wallet` | balance, send, xaman payload |
@@ -134,7 +134,7 @@ Working tree: **clean**
134134
| Route | Template | Description |
135135
|---|---|---|
136136
| `/` | `index.html` | 3D spinning coin, neural lattice BG |
137-
| `/dashboard` | `dashboard.html` | Balance, history, bond status |
137+
| `/dashboard` | `dashboard.html` | Balance, history, link status |
138138
| `/field` | `network.html` | D3 force-directed neural lattice |
139139
| `/ask` | `ask.html` | GPT-4 chat + ElevenLabs voice |
140140
| `/treasury` | `treasury.html` | Metal reserves, MVR |
@@ -171,7 +171,7 @@ Working tree: **clean**
171171
assert token_allocation == 100% # 40 + 35 + 15 + 10
172172
assert absorption_pools == 100% # 40 + 25 + 20 + 15
173173
assert energy_allocation == 100% # 45 + 20 + 15 + 10 + 10
174-
assert FIELD_MAX_BONDS == 5 # Power of 5
174+
assert FIELD_MAX_LINKS == 5 # Power of 5
175175
assert PROPAGATION_MAX_HOPS == 15 # Energy horizon
176176
assert ENTRY_FEE_USD == 100 # Atomic entry
177177
assert CERTIFICATE_CANCEL_FRICTION == 0.02 # 2% burn

SYSTEM_MAP.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ HTTP Response
7777
```
7878
config.py (HeliosConfig)
7979
├── core/network.py (FieldEngine)
80-
│ └── models/member.py, models/bond.py
80+
│ └── models/member.py, models/link.py
8181
8282
├── core/energy_exchange.py (EnergyExchange)
8383
│ └── core/rewards.py (PropagationEngine)
@@ -126,7 +126,7 @@ config.py (HeliosConfig)
126126

127127
```
128128
Member (node)
129-
├── has many Bonds (node_a / node_b — undirected, unique pair)
129+
├── has many Links (node_a / node_b — undirected, unique pair)
130130
├── has many Certificates (HC-NFTs)
131131
├── has many EnergyEvents (immutable ledger entries)
132132
├── has many Rewards (settlement records)
@@ -155,12 +155,12 @@ Space
155155
### 1. Node (Member) FSM
156156
```
157157
INSTANTIATED → ACKNOWLEDGED → CONNECTED → PROPAGATING → STABLE
158-
(created) (initiator (≥1 bond) (≥3 bonds) (5 bonds)
158+
(created) (initiator (≥1 link) (≥3 links) (5 links)
159159
paid)
160160
```
161-
Transition triggered automatically by `member.update_node_state()` on every bond change.
161+
Transition triggered automatically by `member.update_node_state()` on every link change.
162162

163-
### 2. Bond FSM
163+
### 2. Link FSM
164164
```
165165
PENDING → ACTIVE → INACTIVE
166166
└──→ DISPUTED
@@ -187,7 +187,7 @@ Each state change anchored to XRPL via 0-drop self-payment memo.
187187
| Type | Direction | Trigger |
188188
|---|---|---|
189189
| `ENERGY_IN` | External → system | $100 entry payment received |
190-
| `ENERGY_ROUTE` | Hop-by-hop | Propagation through a bond |
190+
| `ENERGY_ROUTE` | Hop-by-hop | Propagation through a link |
191191
| `ENERGY_STORE` | → Certificate | Energy locked into HC-NFT |
192192
| `ENERGY_POOL` | → Protocol pool | Post-hop-15 absorption |
193193
| `ENERGY_BURN` | → Destroyed | Cancel friction (2%), compliance |
@@ -202,7 +202,7 @@ Conservation law verified at every call: `∑IN = ROUTE + STORE + POOL + BURN`
202202

203203
| Destination | % | Amount |
204204
|---|---|---|
205-
| Propagation (bonds, 15 hops) | 45% | $45.00 |
205+
| Propagation (links, 15 hops) | 45% | $45.00 |
206206
| Treasury (metal spine) | 20% | $20.00 |
207207
| Protocol stability pool | 15% | $15.00 |
208208
| Network liquidity | 10% | $10.00 |

_bootstrap_founders.py

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Founding Network Bootstrap — Direct DB insertion for founding bonds.
2+
Founding Network Bootstrap — Direct DB insertion for founding links.
33
Bypasses cooldown because these are pre-existing paid members
44
being loaded into the system retroactively.
55
"""
@@ -10,7 +10,7 @@
1010
from datetime import datetime, timezone, timedelta
1111
from app import create_app
1212
from models.member import Member
13-
from models.bond import Bond
13+
from models.link import Link
1414
from config import HeliosConfig
1515

1616
app = create_app()
@@ -31,10 +31,10 @@
3131
'nakia-r.helios', # 12
3232
]
3333

34-
# Bond pairs — building a connected mesh
35-
# Chain bonds connect everyone in sequence
36-
# Cross bonds strengthen the topology
37-
bond_pairs = [
34+
# Link pairs — building a connected mesh
35+
# Chain links connect everyone in sequence
36+
# Cross links strengthen the topology
37+
link_pairs = [
3838
# Chain — connects everyone in sequence
3939
(0, 1), # elliot ↔ aaron
4040
(1, 2), # aaron ↔ ryan
@@ -48,7 +48,7 @@
4848
(9, 10), # joseph ↔ brian
4949
(10, 11), # brian ↔ blyss
5050
(11, 12), # blyss ↔ nakia
51-
# Cross bonds — strengthen the mesh (respecting max 5 per node)
51+
# Cross links — strengthen the mesh (respecting max 5 per node)
5252
(0, 6), # elliot ↔ eddie
5353
(0, 12), # elliot ↔ nakia
5454
(1, 7), # aaron ↔ dan
@@ -78,17 +78,17 @@
7878
print("FOUNDING NETWORK BOOTSTRAP")
7979
print("=" * 60)
8080

81-
# First, clean up any bonds from the earlier partial attempt
82-
existing_bonds = db.query(Bond).all()
83-
if existing_bonds:
84-
print(f"\nClearing {len(existing_bonds)} existing bonds from partial attempt...")
85-
for b in existing_bonds:
81+
# First, clean up any links from the earlier partial attempt
82+
existing_links = db.query(Link).all()
83+
if existing_links:
84+
print(f"\nClearing {len(existing_links)} existing links from partial attempt...")
85+
for b in existing_links:
8686
db.delete(b)
87-
# Reset all founder bond counts
87+
# Reset all founder link counts
8888
for hid in founders:
8989
m = db.query(Member).filter_by(helios_id=hid).first()
9090
if m:
91-
m.bond_count = 0
91+
m.link_count = 0
9292
m.node_state = "instantiated"
9393
db.commit()
9494
print(" Cleared.")
@@ -98,62 +98,62 @@
9898

9999
formed = 0
100100
skipped = 0
101-
bond_counts = {hid: 0 for hid in founders}
101+
link_counts = {hid: 0 for hid in founders}
102102

103-
print("\nForming bonds:\n")
103+
print("\nForming links:\n")
104104

105-
for idx, (i, j) in enumerate(bond_pairs):
105+
for idx, (i, j) in enumerate(link_pairs):
106106
a_id = founders[i]
107107
b_id = founders[j]
108108

109-
# Respect max 5 bonds per node
110-
if bond_counts[a_id] >= 5:
109+
# Respect max 5 links per node
110+
if link_counts[a_id] >= 5:
111111
print(f" FULL {a_id:<24} (5/5, skipping)")
112112
skipped += 1
113113
continue
114-
if bond_counts[b_id] >= 5:
114+
if link_counts[b_id] >= 5:
115115
print(f" FULL {b_id:<24} (5/5, skipping)")
116116
skipped += 1
117117
continue
118118

119-
node_a, node_b = Bond.ordered_pair(a_id, b_id)
119+
node_a, node_b = Link.ordered_pair(a_id, b_id)
120120

121121
# Check no duplicate
122-
existing = db.query(Bond).filter_by(node_a=node_a, node_b=node_b).first()
122+
existing = db.query(Link).filter_by(node_a=node_a, node_b=node_b).first()
123123
if existing:
124124
print(f" EXISTS {a_id:<24}{b_id}")
125125
skipped += 1
126126
continue
127127

128128
# Stagger timestamps so cooldown logic is satisfied
129-
bond_time = base_time + timedelta(minutes=idx * 5)
129+
link_time = base_time + timedelta(minutes=idx * 5)
130130

131-
bond = Bond(
131+
link = Link(
132132
node_a=node_a,
133133
node_b=node_b,
134-
state=HeliosConfig.BOND_STATE_ACTIVE,
134+
state=HeliosConfig.LINK_STATE_ACTIVE,
135135
initiated_by=a_id,
136-
created_at=bond_time,
137-
activated_at=bond_time,
136+
created_at=link_time,
137+
activated_at=link_time,
138138
)
139-
db.add(bond)
140-
bond_counts[a_id] += 1
141-
bond_counts[b_id] += 1
139+
db.add(link)
140+
link_counts[a_id] += 1
141+
link_counts[b_id] += 1
142142
formed += 1
143-
print(f" BONDED {a_id:<24}{b_id:<24} [{bond_counts[a_id]}/{bond_counts[b_id]}]")
143+
print(f" LINKED {a_id:<24}{b_id:<24} [{link_counts[a_id]}/{link_counts[b_id]}]")
144144

145145
# Update member records
146-
print("\nUpdating member bond counts and node states:\n")
146+
print("\nUpdating member link counts and node states:\n")
147147
for hid in founders:
148148
m = db.query(Member).filter_by(helios_id=hid).first()
149149
if m:
150-
m.bond_count = bond_counts[hid]
150+
m.link_count = link_counts[hid]
151151
m.update_node_state()
152-
print(f" {hid:<28} bonds={m.bond_count} state={m.node_state}")
152+
print(f" {hid:<28} links={m.link_count} state={m.node_state}")
153153

154154
db.commit()
155155

156-
print(f"\nBonds formed: {formed}")
156+
print(f"\nLinks formed: {formed}")
157157
print(f"Skipped (full/duplicate): {skipped}")
158158

159159
# Summary
@@ -166,6 +166,6 @@
166166
print(f"\nNetwork topology:")
167167
for state, count in sorted(states.items()):
168168
print(f" {state}: {count} nodes")
169-
print(f" Total bonds: {formed}")
169+
print(f" Total links: {formed}")
170170

171171
db.close()
Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
"""Form founding bonds — building the initial Helios network topology."""
1+
"""Form founding links — building the initial Helios network topology."""
22
import requests
33

44
BASE = 'http://localhost:5050'
55

6-
# Bond strategy: Create a connected founding network.
7-
# Each member bonds with their neighbors to form a chain,
8-
# then cross-bonds to strengthen the mesh.
9-
# Max 5 bonds per node, 24h cooldown between NEW bonds per pair.
10-
# Since these are all new, we can form them all now.
6+
# Link strategy: Create a connected founding network.
7+
# Each member links with their neighbors to form a chain,
8+
# then cross-links to strengthen the mesh.
9+
# Max 5 links per node.
1110

1211
founders = [
1312
'elliot-a.helios', # 0
@@ -25,10 +24,10 @@
2524
'nakia-r.helios', # 12
2625
]
2726

28-
# Bond pairs — building a connected mesh
29-
# Chain bonds (each member to next): 12 bonds
30-
# Cross bonds to strengthen topology: select extras
31-
bonds = [
27+
# Link pairs — building a connected mesh
28+
# Chain links (each member to next): 12 links
29+
# Cross links to strengthen topology: select extras
30+
links = [
3231
# Chain — connects everyone in sequence
3332
(0, 1), # elliot ↔ aaron
3433
(1, 2), # aaron ↔ ryan
@@ -42,7 +41,7 @@
4241
(9, 10), # joseph ↔ brian
4342
(10, 11), # brian ↔ blyss
4443
(11, 12), # blyss ↔ nakia
45-
# Cross bonds — strengthen the mesh
44+
# Cross links — strengthen the mesh
4645
(0, 3), # elliot ↔ veunca
4746
(0, 7), # elliot ↔ dan
4847
(1, 5), # aaron ↔ paul
@@ -58,34 +57,34 @@
5857
(0, 12), # elliot ↔ nakia (closing the ring)
5958
]
6059

61-
print("FOUNDING BOND FORMATION")
60+
print("FOUNDING LINK FORMATION")
6261
print("=" * 60)
6362

6463
formed = 0
6564
failed = 0
6665
saturated = 0
6766

68-
for i, j in bonds:
67+
for i, j in links:
6968
a = founders[i]
7069
b = founders[j]
71-
r = requests.post(f'{BASE}/api/field/bond', json={
70+
r = requests.post(f'{BASE}/api/field/link', json={
7271
'initiator_id': a,
7372
'peer_id': b,
7473
})
7574
d = r.json()
7675
if r.status_code == 201:
7776
istate = d['data'].get('initiator_state', '?')
7877
pstate = d['data'].get('peer_state', '?')
79-
print(f" BONDED {a:<24}{b:<24} [{istate}/{pstate}]")
78+
print(f" LINKED {a:<24}{b:<24} [{istate}/{pstate}]")
8079
formed += 1
8180
elif 'saturated' in str(d.get('error', '')).lower() or 'maximum' in str(d.get('error', '')).lower():
82-
print(f" FULL {a:<24}{b:<24} (max 5 bonds reached)")
81+
print(f" FULL {a:<24}{b:<24} (max 5 links reached)")
8382
saturated += 1
8483
else:
8584
print(f" SKIP {a:<24}{b:<24}{d.get('error', d)}")
8685
failed += 1
8786

88-
print(f"\nBonds formed: {formed}")
87+
print(f"\nLinks formed: {formed}")
8988
print(f"Saturated (max 5): {saturated}")
9089
print(f"Other skips: {failed}")
9190

@@ -96,6 +95,6 @@
9695
for hid in founders:
9796
r = requests.get(f'{BASE}/api/field/stats/{hid}')
9897
d = r.json()['data']
99-
bc = d.get('bond_count', 0)
98+
lc = d.get('link_count', 0)
10099
ns = d.get('node_state', '?')
101-
print(f" {hid:<28} bonds={bc} state={ns}")
100+
print(f" {hid:<28} links={lc} state={ns}")

_verify_client_ready.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@
3131
ref_id = d["data"]["helios_id"]
3232
print("2. REFERRER: OK |", ref_id)
3333

34-
# 3. Form bond
35-
r = c.post("/api/field/bond", json={"initiator_id": member_id, "peer_id": ref_id})
34+
# 3. Form link
35+
r = c.post("/api/field/link", json={"initiator_id": member_id, "peer_id": ref_id})
3636
d = r.get_json()
3737
if d["success"]:
38-
print("3. BOND: OK |", d["data"].get("message", "bonded"))
38+
print("3. LINK: OK |", d["data"].get("message", "linked"))
3939
else:
40-
print("3. BOND: FAIL |", d.get("error", ""))
40+
print("3. LINK: FAIL |", d.get("error", ""))
4141

4242
# 4. Inject energy
4343
r = c.post("/api/energy/inject", json={"member_id": member_id})
@@ -88,7 +88,7 @@
8888
# 12. Field status
8989
r = c.get("/api/field/status")
9090
d = r.get_json()
91-
print("12.FIELD: OK | nodes=%s bonds=%s" % (d["data"]["total_nodes"], d["data"]["total_bonds"]))
91+
print("12.FIELD: OK | nodes=%s links=%s" % (d["data"]["total_nodes"], d["data"]["total_links"]))
9292

9393
# Stripe check
9494
stripe = d["data"] if False else c.get("/api/infra/readiness").get_json()["data"]["providers"]["stripe"]
@@ -102,7 +102,7 @@
102102
print(" Stripe: %s" % ("LIVE" if stripe["ready"] else "NEEDS TEST KEYS (5 min setup)"))
103103
print(" Xaman: %s" % ("LIVE" if xaman["ready"] else "NEEDS APP CREDENTIALS (5 min setup)"))
104104
print(" Identity: OPERATIONAL")
105-
print(" Bonds: OPERATIONAL")
105+
print(" Links: OPERATIONAL")
106106
print(" Energy: OPERATIONAL")
107107
print(" Token: OPERATIONAL")
108108
print(" Database: SQLite (production uses PostgreSQL)")

ai/ask_helios.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ def _get_member_context(self, member_id: str) -> dict:
11391139
"member_since": member.created_at.isoformat(),
11401140
"display_name": member.display_name,
11411141
"node_state": member.node_state,
1142-
"bond_count": member.bond_count
1142+
"link_count": member.link_count
11431143
}
11441144
except Exception:
11451145
pass

0 commit comments

Comments
 (0)