Documentation / Routing & quorum aggregation
HiNet — Network Routing & Quorum Aggregation
Spec status: Draft v0.1 · Sibling to HiNet-Technical-Spec.md (extends peer-protocol, qCoreInferenceSession, QuorumMembership) and HiNet-Sovereign-Intelligence-Vision.md §5 (the three ask-modes) · Grounded in Whitepaper §2 (right-sizing), §3 (spectrum router + fidelity↔singularity), §6A/§6B (economy, membrane, lease).
This spec defines how a query becomes an answer across owned iCores: choosing whether to answer locally or assemble a qCore, selecting the minimal-sufficient node set by competence, respecting membranes, combining outputs (committee/MoA vs weight-merge/MoErging), and producing attributable, consent-gated, non-leaking receipts that feed the pay-per-use split.
Legend. [EXISTS] already built in app/osx/hinetd. [NEW] to build. [MVP] first networked milestone. [LATER] deferred. [OPEN] unresolved decision.
Central-infra note. All central services here (registry/discovery index, receipt ledger, settlement, relay) run in the Quorumz GCP project but on their own dedicated resources for the mind.quorumz.com / HiNet product — separate service accounts, DBs, and buckets from Quorumz's own workloads. The registry is a phonebook + competence index, never an inference broker: routing decisions are made on the asker's own node (sovereign routing), so the platform cannot silently re-route or read answers.
0. Vocabulary (reused exactly)
| Term | Meaning | Where |
|---|---|---|
| iCore | one human's owned MoE (frozen anchor ⊕ Δ_private ⊕ Δ_public + drafter). iCore == 1 human. |
WP §2–§3 [EXISTS] as hinetd |
Δ_public |
anchor-locked, consented, generalized skill projection — the income-producing expert the network routes to | WP §2, §6A |
| iQuorum / iQuorumz | consenting assembly of iCores; ad-hoc (auto-selected) or predefined (named, @-mentionable) | Vision §2/§5 |
| qCore | the instantiated quorum for one query — a membership set + an aggregation mode. Ephemeral by default; may be promoted to a standing merged model | WP §3, Tech-Spec qCoreInferenceSession |
| iCorp | rigid, org-gated iQuorum answering as one business identity; internal iCores hidden | Vision §2, WP §6B |
| membrane | org/gov-gated boundary governing what compounds inside and what crosses out | WP §6B |
| competence-signature routing | per-prompt selection of experts by advertised competence; right-sizes to the minimal sufficient set | WP §2–§3 |
| committee/MoA | cross-anchor, output-level composition — bigger system | WP §3 (Wang et al., 2024) |
| MoErging / weight-merge | same-frozen-anchor Δ_public task-vectors merged (TIES/DARE) into one bigger sparse LLM — decomposable |
WP §3 (Yadav et al., 2024) |
| consent grant / audit chain | ConsentGrant gate + tamper-evident hash-chain |
consent.py, audit.py [EXISTS] |
| ComputeBackend seam | every model call crosses as a signed WorkOrder → verified BackendReceipt |
Node-Packaging [EXISTS as seam] |
| Canonical Record (HCR) | CanonicalItem + Origin provenance |
canonical.py [EXISTS] |
Composition selection rule (the load-bearing invariant, WP §3 / changelog 0.6.0):
Merge complementary deltas · route conflicting deltas · retrieval-union for facts.
Everything below is a mechanization of that one rule under membranes, consent, and receipts.
1. The three ask-modes
Every query enters hinetd with an ask_mode. This is a new field on the existing chat body, so it rides the OpenAI-compatible path already built (server.py:chat_completions).
// POST /v1/chat/completions (extended; hinet_* are HiNet extensions, ignored by vanilla OpenAI clients)
{
"model": "icore-generalist",
"messages": [...],
"hinet_ask_mode": "own" | "network" | "auto", // NEW; default "own" (back-compat)
"hinet_scope": { "channels": [...] }, // EXISTS (RAG scope over own vault)
"hinet_quorum": { "target": "icore:<id>" | "iquorum:<id>" | "open", // Vision §5 ask targets
"budget_tokens": 4000, "budget_usd": 0.05, "latency_ms": 8000,
"sensitivity_ceiling": "personal", "allow_membrane_cross": false }
}
1.1 own — ask my own iCore (local only) [EXISTS]
Exactly today's path: personalize() retrieves from the owner's vault (consent-filtered, secret excluded), the local MLX model answers, nothing leaves the device. hinet_quorum is ignored. This is the sovereign default and the offline guarantee (/node/proof).
1.2 network — ask the network [MVP, NEW]
The query is routed to other iCores/iQuorumz/iCorps and answered by a qCore. The owner's own iCore is always a candidate member (usually the aggregator). Three targeting sub-modes (Vision §5):
- target: "icore:<id>" — ask one specific human's iCore.
- target: "iquorum:<id>" — ask a predefined named iQuorum (fixed membership, skip discovery).
- target: "open" — ask openly → the dynamic router (§2) selects the quorum.
1.3 auto — the mechanism decides [MVP, NEW]
AUTO answers the core product question "can I answer this myself, or do I need the network?" by right-sizing before routing (WP §2 "narrow → own iCore; broad → a few experts; general → escalate"). It never escalates a query the owner's own iCore already covers, and never merges when routing suffices — "more isn't better; over-assembling should lose."
AUTO decision (self-competence + breadth gate):
auto_decide(query, own_sig, budget) -> plan:
q = embed(query) # reuse the vault embedder (multilingual-e5) [EXISTS]
s_self = competence(q, own_sig) # how well MY iCore covers this (0..1)
breadth = generality(query) # #distinct domains touched (0..1); §2.1
cover = vault_coverage(q) # do I even hold facts on this? (RAG hit density)
if s_self >= τ_self and breadth <= β_narrow: # narrow + in my wheelhouse
return LOCAL # → identical to ask_mode=own
if cover >= κ and breadth <= β_narrow and offline: # I hold the facts and can't reach net
return LOCAL
# else escalate — but right-size the set (§2)
return NETWORK(route(query, budget))
τ_self, β_narrow, κ are node-local, owner-tunable knobs (defaults τ_self=0.62, β_narrow=0.34, κ=0.5). [OPEN] calibration of these against real queries — start conservative (bias to LOCAL) so AUTO never surprises the owner with a paid network call; expose a "this went to the network (N nodes, $X)" chip in the UI, and a per-query "answer locally instead" override.
How AUTO combines once it escalates is the router's job (§2) and the aggregator's job (§3). AUTO's only extra responsibility: it always seeds the candidate set with the owner's own iCore, so the network augments rather than replaces the owner's model, and the owner's node is the aggregator (it holds the private context that must never be sent outward).
2. The dynamic router — minimal-sufficient node selection
Runs on the asker's node (net/router.py [NEW]). Input: query + budget + membrane context. Output: a qCore plan = an ordered member set + an aggregation mode + per-member sub-prompts. Ties directly to WP §3 "competence-signature routing → right-size to the minimal sufficient set → pick mode by fidelity-need × latency budget → hierarchical router-of-routers at scale."
2.1 Competence signatures (the routing substrate) [NEW] — §2.5 replaces self-estimated strength
Each participating node publishes a CompetenceSignature to the registry (§4). As before it is derived from what the node already has (Δ_public skill clusters + de-identified vault domain centroids — never raw data). What changes (0.12.0): the per-speciality strength scalar is DELETED. A self-asserted number is unfalsifiable and was flagged as competence-inflation in open decision #5. Each speciality now carries a CompetenceAttestation bundle (§2.5) and the router derives a verified, decaying effective_strength from it — never from a raw assertion.
specialities: # routable competence — each carries a VERIFIABLE ATTESTATION, not a self-estimate
- domain: "tax:solidity-security@v3" # canonical domain-id from the GOVERNED shared taxonomy (§2.5.6) — NOT a free cluster label
centroid_ref: # D3 HARD GATE: publish cluster-id membership by default, never a raw invertible vector
form: "cluster_id" # cluster_id (MVP) | dp_centroid (LATER, only if E2 bounds embedding-inversion)
cluster_id: "tax:solidity-security@v3"
dp_centroid: null # 768-d DP-noised/quantized mean — null until E2-cleared (D3)
max_sensitivity: "normal" # SensitivityClass ceiling of the supporting items (HCR §4b); sensitive|secret ⇒ NEVER publicly attested (hard gate)
exposure: "public" # public | membrane | private — consent-gated; default private if max_sensitivity > normal
# ---- self-estimated `strength: 0.88` is REMOVED. effective_strength is DERIVED + DECAYING from the attestation. ----
attestation: # the CompetenceAttestation (schema + semantics in §2.5)
method_tier: "committed" # declared | committed | provenance | challenged | attested (§2.5.2 ladder)
corpus_density_proof: # T-A accountability layer — tamper-evident, NON-backdatable, disputable (NOT trust)
vault_root: "merkle:sha256:..." # Merkle root over salted domain-D HCR leaves (dedup by content_hash)
n_items: 1420 # after content_hash dedupe + novelty weighting
diversity: 0.71 # effective-rank / distinct-source / distinct-counterparty (anti-padding; NOT anti-fabrication)
months_populated: 9
span_days: 284
slope: "+0.06" # Theil–Sen over prior cycles' timestamped roots; >0 = densifying
root_chain: [ {root, n_D, tsa_token, log_index, at}, ... ] # one RFC3161+CT entry per sleep cycle (§2.5.3)
measured_in: "local" # local | tee (tee ⇒ measurement-integrity closed; RESEARCH on laptop, §2.5.2)
provenance_proof: # T2 zk external anchors — corroborates the source CHANNEL, not expertise [LATER]
first_party_fraction: 0.0 # 0 at MVP; raised only by zkEmail-DKIM/zkTLS/signed-git proofs
proofs: []
capability_cert: # T3 decentralized eval — counts toward trust ONLY when weight-bound (T1) [LATER/RESEARCH]
score: null
scorecard_ref: null
weight_bound: false # true iff a TEE test-drive bound answers to the committed local weights
verifier_set: [ "self", "tsa:freetsa.org" ] # who attested each component (self | TSA | grader ids | TEE vendor)
personhood: "account" # none | account | proof_of_personhood — GATES payout-bearing routing (§2.5.4)
attested_at: "2026-08-18T..Z"
expires_at: "2026-09-17T..Z" # tier-scaled TTL; expired ⇒ router collapses this speciality to `declared` weight
nonce: "..." # §3 SignedEnvelope single-use nonce (anti-replay)
signature: "ed25519:..." # k_sign over canonical(attestation || nonce || expires_at)
competence(q, sig) is no longer cosine × self_strength. It is now:
competence(q, sig) = max_s( match(q, s) × effective_strength(s, now) ) # match = cos(q, dp_centroid) or cluster-id hit
# effective_strength derived + decayed + tier-weighted + personhood-gated — §2.5.4
with the language-match gate and recency/availability prior unchanged. A declared/committed-only speciality contributes ~0 to payout-bearing routing (§2.5.4) — exactly the discipline the identity spec §4.3 already applies to unproven claims, now extended to the new accountability tier.
2.2 Right-sizing selection algorithm [NEW]
Greedy marginal-coverage selection — grow the set only while each added node materially covers something the current set doesn't, capped by budget. This is the concrete form of "minimal sufficient qCore."
def route(query, budget, ctx) -> QCorePlan:
q = embed(query)
subtopics = decompose(query) # 1..T facets (own model, one cheap local pass); T=1 for simple asks
cand = registry.discover(q, ctx.membrane) # candidate signatures, membrane-filtered (§2.3)
cand = [c for c in cand if consent_ok_to_ASK(c, ctx)] # asker won't send this query outside its own ceiling
# always seed with the owner's own iCore (AUTO/network augment, not replace)
selected = [own_node]
covered = coverage_vector(own_node, subtopics)
while budget.allows(len(selected)+1):
# pick the node with the largest MARGINAL coverage gain across still-weak subtopics
best, gain = argmax_marginal(cand, subtopics, covered)
if gain < ε_coverage: # nothing left worth adding → STOP (right-sized)
break
selected.append(best); cand.remove(best)
covered = update_coverage(covered, best, subtopics)
if min(covered) >= θ_sufficient: # every facet is now well-covered → STOP
break
mode = pick_aggregation_mode(selected, subtopics, budget, ctx) # §3.2
subprompts = shard(query, subtopics, selected, mode)
return QCorePlan(members=selected, mode=mode, subprompts=subprompts,
threshold=quorum_threshold(selected))
Notes:
- decompose/shard reuse the already-built local agent loop style (/v1/agent) — a single cheap local pass that emits facets, no extra model.
- ε_coverage and θ_sufficient implement "more isn't better": a second generalist that adds no new coverage is never added; a narrow query resolves to selected == [own_node] and collapses back to LOCAL.
- Hierarchical router-of-routers [LATER]: past ~10³ candidates, registry.discover returns cluster reps (pre-clustered competence regions); the node then drills into the winning cluster. Frequently co-activated sets are pre-merged into standing iQuorumz during consolidation (WP §3).
2.3 Membranes in routing (iCorp boundaries) [NEW]
Membrane is a hard pre-filter on candidates and a hard gate on receipts, before any competence math:
discover(q, ctx):
pool = registry.index(q)
if ctx.membrane.type == "icorp": # asker is inside an iCorp workspace
# internal view: all member iCores + internal iQuorumz are visible & routable
return pool.within(ctx.membrane.icorp_id) + pool.free_public_if(ctx.allow_external)
else: # public netizen
# free iCores routable individually; iCorps appear ONLY as single identities
return pool.free_icores() + pool.icorps_as_identity()
Consequences (enforced, not advisory):
- A public asker can never address an iCorp's internal iCores; the iCorp answers as one node (kind: "icorp", aggregate signature). Its internal fan-out happens inside the membrane and is invisible/opaque in the returned receipt.
- An iCorp member asking open inside the workspace routes over internal members freely (the "more streamlined path," Vision §5) and may additionally reach the public network only if allow_membrane_cross + org policy permit.
- Cross-membrane egress of the query itself is gated by the asker's own sensitivity_ceiling (a sensitive query is never shipped to an external node).
2.4 Quorum Memory — the standing-quorum cache [NEW, CORE]
The scaling primitive. §2.2 routes a query by embedding it and searching the whole competence index, then §3 assembles + aggregates N models. Doing that from scratch for every query does not scale (ANN over a global index + N cold fan-outs, per request). Quorum Memory is the answer: the network remembers which iCores compose well for which kinds of question, and warm-starts from that memory instead of re-deriving it. It is a KV cache for composition — the "keys/values" are the assembled quorums, cached so the composition is not recomputed.
2.4.1 The object
# StandingQuorum — a remembered, reusable assembly. Lives in the registry (global) + node-local (hot).
StandingQuorum = {
sq_id: str, # stable id, signed by curator
signature: vec[1024], # the cache KEY (topic-vector); KEYING mechanics owned by HiNet-Query-Classification-and-Quorum-Cache.md
radius: float, # near-match ball around the key (grows/shrinks with use)
members: [node_id], # the known-good set
mode: "committee"|"moerging",
warm_merge: {host, handle}|null, # if pre-merged (hot tier): the qCore host + merged-model handle
compat_class: str|null, # anchor DNA; required non-null for a warm_merge
stats: {n_uses, ewma_score, p50_latency_ms, last_used_at, member_hit_rate:{node_id:float}},
ttl: float, # decays; refreshed on use
}
The cache KEYING — query → topic-set → standing-quorum lookup (order-invariant set-key for exact hits + topic-vector for near-matches) — is owned by HiNet-Query-Classification-and-Quorum-Cache.md; StandingQuorum.signature is that key, left abstract here.
2.4.2 Three tiers (cold / warm / hot)
| Tier | Trigger | Cost | Mechanism |
|---|---|---|---|
| Cold (miss) | no standing quorum within radius | full discover + right-size (§2.2) + N-way committee |
the resulting assembly is recorded as a new/updated StandingQuorum |
| Warm (membership hit) | a standing quorum matches; mode=committee |
fan-out to members only — no discovery, no global ANN |
reuse membership; still N live calls but skips routing |
| Hot (pre-merged) | matches + warm_merge≠null (same-compat_class, frequently co-activated) |
one forward pass on the merged qCore | the cheapest, most scalable tier — the composition itself is cached as weights |
route(q) (replaces the naive path in §2.2 for the common case):
sq = quorum_memory.lookup(topics(q)) # set-key exact → topic-vector near-match (KEYING → Query-Classification doc); local hot cache first, then registry
if sq: # cache hit (exact or within radius)
members = sq.members
members = grow_if_underspecified(members, q) # add a specialist iff q shows a facet no member covers
members = shrink_if_overkill(members, q) # drop members whose predicted marginal < ε
ans, receipts = (serve_merged(sq.warm_merge, q) if sq.warm_merge and unchanged(members)
else committee(members, q))
quorum_memory.reinforce(sq, members, receipts) # EWMA score, hit-rates, radius, ttl
else:
members, mode = right_size(discover(q), q) # §2.2 cold path
ans, receipts = aggregate(members, mode, q)
quorum_memory.record(sig(q), members, mode, receipts)
2.4.3 Grow / shrink / decay (why the cache stays live, not stale)
A standing quorum is not a frozen list — it tracks the network's live question distribution:
- grow — a query inside the ball whose facets aren't covered by current members adds the winning specialist; if this recurs, the member joins the set and radius widens.
- shrink — a member whose member_hit_rate / marginal contribution falls below ε is dropped (and, if hot, triggers a re-merge or demotion to warm). Drop-the-delta stays exact (E1-decomposable).
- decay — ttl and ewma_score decay with disuse; a standing quorum that stops earning receipts is evicted (LRU-by-value). Membership drift beyond a threshold re-bases the signature/centroid.
- split / merge — if a ball accumulates a bimodal query population, it splits into two standing quorums; near-duplicate quorums merge. (Keeps the cache key-space clean — analogous to a router-of-routers cluster, §2.2.)
2.4.4 Where it lives + who curates it
- Node-local hot cache — each node keeps the standing quorums it participates in or frequently routes to (bounded LRU). First lookup is local → zero network hop on a hot hit. Survives registry outage (§9 degradation: cached candidates → LOCAL).
- Registry global index — the durable, signed catalog of standing quorums (the
signature-keyed ANN structure). The registry indexes standing quorums; it never reads answers and never forces a route — a node may always ignore the cache and cold-route (sovereignty preserved, §5.2). - Curation runs during consolidation ("sleep") — the same clock that trains each iCore (WP §3) mines the signed AnswerReceipt/QueryReceipt log (§5.3) for co-activation (which members answered together and scored well): forms new standing quorums, schedules hot-tier pre-merges on qCore hosts, prunes decayed ones. No raw queries are stored — only signatures + member ids + scores (no-leak, §5.2).
2.4.5 Consent, attribution, membranes (reused, not re-specified)
- A
StandingQuorummay only list a node that holds aquorum_answergrant; revocation instantly delists it from every standing quorum (drop-the-delta = drop-the-listing, §5.1). - Membrane scoping is inherited: an iCorp's internal standing quorums are curated + cached inside the membrane and are invisible to public routing (§2.3). A public standing quorum never contains an iCorp's internal
node_ids — only its aggregate identity. - Pre-merge (hot tier) still requires an attested qCore host (§3.1) so a contributed
Δ_publicis used-not-copied; a standing quorum'swarm_merge.hostrecords which. - Compat-class migration (§11.8): when the frozen anchor upgrades, all
hotstanding quorums invalidate theirwarm_mergeand demote towarmuntil re-merged against the new anchor;committeestanding quorums survive (mode is anchor-agnostic).
2.4.6 What this reuses vs adds
Reuses [EXISTS]: competence signatures (§2.1), the right-size selector (§2.2), committee/MoErging (§3), signed receipts + the audit hash-chain (§5.3), consent grants (§5.1), the consolidation clock (WP §3), registry discover/index (§4.1). Adds [NEW]: the StandingQuorum object + signature-keyed cache, the cold/warm/hot tiering in route(q), grow/shrink/decay/split-merge maintenance, and the consolidation-time curator. This is the concrete form of WP §3's "frequently co-activated sets pre-merged into standing iQuorumz."
2.5 Verifiable Competence Attestation [NEW]
Replaces the self-estimated strength (§2.1) and closes open decision #5 ("a node can over-claim strength"). A speciality is no longer asserted — it is detected (systematic accumulation, during "sleep"), committed + timestamped, signed, expiring, and decaying, and the router consumes a verified effective value derived from it.
Honesty first — read this before the mechanism. What the buildable-today MVP delivers is ACCOUNTABILITY, not trust. The commitment + RFC3161 timestamp + audit-chain + Ed25519 signature + expiry/decay + the systematic-detection gate make a competence claim tamper-evident, non-backdatable, self-expiring, and disputable. They do not make it true: density is a self-measurement over attacker-controllable data. A patient synthetic-corpus generator (diverse LLM output injected daily over real calendar months, distinct content_hashes, real timestamps, is_self=true) is metadata-identical to a real expert, and the canonical target persona — private notes / local files / WhatsApp with no DKIM/TLS anchor — is exactly the case no proof can separate. Therefore density/accumulation confers accountability weight only, never routable trust (§2.5.4 pins it to ~0 for payout-bearing routing). Real trust is layered on top by the three later/research methods in §2.5.2, and by proof-of-personhood. Everything below runs on the consolidation ("sleep") clock (WP §3) — the same clock that trains deltas and curates Quorum Memory (§2.4).
2.5.1 Auto-detection — the systematic-vs-occasional test [MVP, NEW]
A DensificationDetector runs each sleep cycle, unsupervised, over the vault's multilingual-e5 embeddings (the same 768-d space queries route in). It maintains DomainCells (online clusters; a new cell spawns for material far from every centroid — an emerging speciality needs no predefined list) and, per cell, a recency+novelty-weighted mass series across cycles. A cell registers as a speciality only when it is systematic, decided by the shape of the trajectory, not any single-cycle magnitude.
def detect_specialities(vault, history): # runs in consolidation, fully local, no network
for item in vault.new_or_changed(): # [EXISTS] sleep re-embeds these
item.vec = e5.embed(item.provenance_header + item.text)
cells = online_cluster(vault.embeddings) # reuse RAG index; centroids live in query space
out = []
for c in cells:
c.dedupe(by="content_hash") # [EXISTS HCR] copies/re-imports don't inflate
mass = recency_novelty_weighted_mass(c, history) # w_i = surprise (SuRe) → near-dups add ~0
sig = {
"magnitude": c.n_eff >= N_MIN and mass >= M_MIN, # not a handful, not 10k copies of one doc
"slope": theil_sen(history.mass_of(c)) > 0, # robust median-of-slopes; immune to one spike
"persistence": frac_cycles_with_positive_increment(c) >= P_MIN
and distinct_cycles(c) >= N_CYCLES and span_days(c) >= D_MIN,
"spread": effective_active_days(c) >= S_MIN, # exp(entropy of per-day histogram); anti-burst
"diversity": distinct_origins(c) >= SRC_MIN, # real expertise spans many threads (HCR Origin)
"eval_lift": domain_probe_recall_delta(c) >= C_MIN, # reuse the RAG sleep recall-delta gate
}
c.state = hysteresis(c.state, all(sig.values())) # Schmitt trigger: HIGH×N_CYCLES→active; LOW×M→lapse
if c.state == "active":
out.append(promote(c)) # → candidate speciality (commit → attest, §2.5.2)
return out # below-threshold cells stay PRIVATE, never advertised
- Systematic, by construction. A one-off mention lands in one cell, one cycle, one day, one source →
slope≈0,persistencefails,spreadfails → never registers. The mechanical engineer accreting notes/mail on thermal design over 9 months trips all six → auto-promotes. This is the systematic-vs-occasional distinction — it's the shape of the gate, not a threshold on a count. - Honest limit (metadata-twin attack). Every signal above is computed over self-controlled metadata and is LLM-cheap to fabricate at scale (diverse generation maximizes novelty/effective-rank; sources/counterparties/
is_selfare self-asserted). Detection decides what to attest; it does not decide what to trust. Trust comes only from §2.5.2 T1–T3 + personhood. - Bias conservative: miss rather than false-register (
[OPEN]calibration ofN_MIN…C_MINon the dev's own vault, E2). Cells whose mass is allsensitive/secretare never publicly attested (hard SensitivityClass ceiling, §2.5.4).
2.5.2 The proof ladder — accountability base + three trust methods [MVP → RESEARCH]
Each claim is proven by the cheapest mechanism that actually holds; no single root is load-bearing. The owner's three method labels map as: T1 = TEE, T2 = ZK-provenance, T3 = decentralized-eval. Build order ≠ tier strength (see caveats).
method_tier |
What it proves | Mechanism | Honest status |
|---|---|---|---|
declared |
nothing (self-asserted) | — | [EXISTS] — routable weight 0 |
committed (the MVP) |
accountability: this corpus existed, grew across committed months, wasn't backdated, was computed over a fixed commitment | Merkle/KZG over salted HCR leaves + RFC3161 TSA per cycle + CT-log chain + audit hash-chain + Ed25519 + expiry | [MVP] buildable now, cheap. Auditable, NOT trustworthy. Routable weight ~0 for payout-bearing |
provenance (T2 ZK) |
channel authenticity: a fraction of the mass is third-party-anchored material I genuinely received/produced | zkEmail-over-DKIM (headers already in source_meta), zkTLS/TLSNotary (forward-capture only), signed git commits — reveal only |
[LATER] buildable now, per-source. Proves receipt, not expertise (1000 Sybils subscribing to ieee.org all get "first-party" mass). Corroborator only; caps, never grants, routable trust |
challenged (T3 eval) |
capability: model answers fresh, provably-unseen domain-D probes | commit-then-reveal Merkle probe bank + drand beacon + RFC3161 + random staked grader committee + RLVR auto-checkable references + honeypots (not peer-median), short deadline | [LATER] buildable now. Defeated by a general/frontier model fronting the endpoint unless answers are weight-bound (T1). Counts toward trust only if weight_bound=true |
attested (T1 TEE) |
the real thing: the density stats / probe answers came from this identity's committed local weights | TEE quote binding {measure_code_hash, vault_root, model_hash} — CloudSandboxBackend attest-then-release-key (TDX/SEV-SNP + GPU-TEE) |
[RESEARCH] — HiNet's own §4.3 marks attested "NEW, research"; CloudSandboxBackend NOT built; the local Secure Enclave is a key coprocessor, cannot run the detector or a 30–80B model ⇒ unavailable to the laptop persona; cloud-CVM path moves data off-machine (sovereignty caveat). The only tier that closes both fabrication (T-A) and fronting (T3) |
zk_model |
trustless capability without a TEE | zkLLM/zkML over committed weights | [RESEARCH] — not buildable at scale/cost; no tier depends on it |
Orthogonal, and required before any payout-bearing trust: proof-of-personhood (personhood: proof_of_personhood). Calendar-cost is paid once and cloned across N vaults in parallel — it rate-limits, it does not resist Sybils. Owner-gating (one mind.quorumz.com account) is farmable. Until personhood ships ([LATER], D6), cap routable specialities per owner_ref and treat the accumulation curve as rate-limiting only.
2.5.3 Re-attestation cadence + decay [MVP, NEW]
Two clocks, two independent decays → growing domains ratchet up, abandoned ones lapse with no active revocation.
- Nightly (detection clock, local, free): re-score every cell; append one RFC3161-timestamped root to each active domain's
root_chain. This single append is what accrues the non-backdatable accumulation proof and costs real calendar time an attacker cannot compress (but can parallelize — §2.5.2). Mass is recency-weighted, so a domain with no fresh material decays every night on its own. - Re-attest (publish, slower — weekly→monthly): re-mint the
CompetenceAttestationfor any domain still passing; run the (costly)challenged/attestedproofs here. TTL scales with tier:committed30 d,provenance/challenged60–90 d,attested90 d. - Decay, enforced two ways: (1) expiry — the registry drops specialities past
expires_at(reuses the §3 nonce+expiry envelope); a node that stops running sleep never refreshes and lapses. (2) decayingeffective_strength— the router multiplies bydecay(now − last_growth) = 0.5^((now−last_growth)/H),H≈60 dfor density, longer for capability (skills fade slower than fact-density). Growing domains keeplast_growthfresh → strengthen and earn a higher tier; abandoned domains bleed toward the floor and cross expiry → vanish from routing. Symmetric to Quorum-Memoryttl/ewmadecay (§2.4) — competence and its standing quorums decay on the same clock.
2.5.4 How the §2.2 router consumes VERIFIED EFFECTIVE competence [NEW]
def effective_strength(s, now, ctx):
base = f(s.density, s.first_party_fraction, s.capability, s.usage_rep) # geometric mean: any factor≈0 kills it
decayed = base * 0.5**((now - s.last_growth)/H[s.tier])
tw = TIER_WEIGHT[s.method_tier] # declared:0 committed:~0 provenance:low
# challenged:low(0 unless weight_bound)
# attested:high
if not weight_bound(s): tw = min(tw, TIER_WEIGHT["committed"]) # fronting-safe: eval alone ≠ trust
pg = 1.0 if s.personhood == "proof_of_personhood" else PERSONHOOD_FLOOR
return match(ctx.q, s) * decayed * tw * pg
# HARD GATE — payout-bearing / high-value routing:
def payout_bearing_ok(s):
return s.method_tier == "attested" and s.personhood == "proof_of_personhood" and not s.cold_start
committedanddeclaredroute at ~0 for money. They are used for discovery, ranking hints, and dispute records — never to send a payout-bearing or high-value query alone. This is the identity spec §4.3'sdeclared-is-unweighted discipline, extended to the accountability tier.- Continuous between-attestation verification (receipts + Quorum-Memory ewma). The signed
AnswerReceipt/QueryReceiptanswer_acceptance(§5.3) andStandingQuorum.ewma_score(§2.4) feedusage_rep— but only to adjust DOWN or up-within-tier-cap, never to grant trust a proof didn't earn. Honest limits, enforced: (a) cold-start quarantine — a fresh attestation iscold_start=trueand barred from high-value routing until an independent-verification threshold accrues; (b) acceptance ≠ correctness — the asker is low-competence in D (that's why it asked), so plausibility-acceptance is farmable by collusion; payout-bearing acceptance requires auto-checkable references or a dispute-with-slashing, not the aggregator's plausibility judgment. StandingQuorumadmission (§2.4.5) requires a freshattestedspeciality for that domain, so Quorum Memory cannot cache a self-declared liar.
2.5.5 Threat mitigations (folded from the adversarial review) [NEW]
| Attack | Mitigation | Residual honest limit |
|---|---|---|
| Patient synthetic-corpus fabrication (metadata-twin) | density is accountability-only (§2.5.4 tw≈0); trust needs attested + provenance |
Unclosed below attested — stated plainly, not papered over |
| Frontier-model fronting the black-box eval | challenged counts only when weight_bound=true (TEE test-drive) |
eval alone proves "some model can answer," not earned expertise |
| Parallel Sybil farm (calendar-cost cloned N×) | proof-of-personhood required for payout + per-owner_ref speciality cap; calendar-cost is rate-limiting only |
personhood is [LATER]/D6 — until it ships, no payout-bearing trust |
| Cross-node corpus pooling (one dataset, N "first-party" experts) | personhood + [LATER] PSI corpus-overlap detection on leaf commitments |
committed density is non-exclusive by default |
| Grader collusion / niche cold-start | genesis platform-run/staked honest graders + RLVR references + honeypots slash on known answers (not median-deviation) | thin domains: don't route money on committee-only proofs |
| Backdated accumulation | RFC3161 + CT-log + append-only audit chain | — (this one genuinely holds) |
| Padding / copy-paste density | content_hash dedupe + effective-rank + distinct-source/counterparty | only bounds trivial duplication; LLM-diverse generation defeats it |
| Centroid/label leakage (Vec2Text inversion; the label itself is sensitive) | D3 hard gate: cluster-id only by default, dp_centroid only if E2-cleared; SensitivityClass ceiling hard-gate (sensitive/secret never publicly attested); per-domain owner opt-in; membrane-hidden excluded from public ANN | inversion risk on any published vector must be E2-bounded before dp_centroid ships |
| Replay / cross-node theft | fresh nonce + expiry + Ed25519 identity binding | — |
| Taxonomy fracture / root-chain re-basing exploit | governed shared taxonomy + deterministic split/merge re-basing (§2.5.6) before the domain-keyed chain is meaningful | [OPEN] governance/versioning |
2.5.6 Governed taxonomy + split/merge re-basing [MVP, NEW]
The root_chain, the centroid_ref, and cross-node routing are keyed on a stable canonical domain-id. If two nodes disagree what solidity-security is, centroids don't compare and routing is noise; if a cell splits/merges across cycles, the domain-keyed chain fractures — and an attacker can re-base to discard an unfavorable history. So this is load-bearing, not a footnote:
- The registry publishes a governed, versioned taxonomy (
tax:<domain>@v<n>); detector labels snap to it by e5-kNN against the embedded taxonomy table; the owner confirms/relabels (same owner-in-the-loop as RAG identity-merge). - Deterministic re-basing rule: on split, the child inherits the parent's
root_chainup to the split epoch with a signedrebased_fromlink; on merge, chains concatenate under a canonical parent — so history cannot be silently reset. Mirrors Quorum-Memory split/merge (§2.4.3).
2.5.7 What this reuses vs adds
Reuses [EXISTS]: the consolidation "sleep" clock + eval gate (WP §3); multilingual-e5 embeddings + vault chunk table (RAG); HCR content_hash/Origin/author.is_self/SensitivityClass + source_meta.headers DKIM (Canonical-Record); Ed25519 self-certifying identity + SignedEnvelope nonce/expiry (Identity §1/§3); audit hash-chain (audit.py); DeltaView leakage-gated public surface (classify.py); ComputeBackend.evaluate()→Scorecard + attestation_level (Node-Packaging §C); ConsentGrant + quorum_answer gate (§5.1); signed AnswerReceipt/QueryReceipt + Quorum-Memory ewma_score/decay (§2.4/§5); proof_level ladder + registry proof_refs (Identity §4.3). Adds [NEW]: the DensificationDetector + systematic gate; the CompetenceAttestation bundle replacing strength; the RFC3161/CT root_chain; the committed→attested tier ladder + weight_bound/personhood gating in effective_strength; the governed taxonomy + re-basing rule; POST /node/competence/{detect,attest}. Does NOT add / explicitly out: general zkLLM over model capability (zk_model, research); any claim that TEE is an MVP tier (it is not, on the laptop persona).
3. Aggregation modes — committee/MoA vs MoErging/weight-merge
Both realize "the whole is bigger," at different points on WP §3's fidelity ↔ singularity curve. The router picks per query.
3.1 The two mechanisms
(A) Committee / MoA — cross-anchor, output-level. [MVP]
Each selected iCore answers its sub-prompt on its own device with its own weights; only filtered text returns. An aggregator (the asker's own iCore) synthesizes a final answer. Optionally layered MoA (WP §3, Wang et al. 2024): proposers → aggregator, 1–2 layers. Bigger system, no interference tax, ~ceiling quality, needs an accurate router (§2). Only mode that works across different anchor DNAs / compat-classes, and the only one where no weights or raw data ever move — so it is the MVP and the privacy-default.
Combine step (aggregator, runs locally on asker's node):
final = aggregate(query, [ (member_i, answer_i, cite_i, competence_i) ... ]):
# weight proposer answers by (router competence × self-reported confidence × judge agreement)
cluster = semantic_cluster(answers) # dedupe agreeing answers (embedding + NLI contradiction check)
synth = own_model.compose(query, weighted(cluster)) # cite each contributing member as [n]
return synth, contribution_weights # weights feed the receipt/split (§5)
(B) MoErging / weight-merge — same frozen-anchor, one bigger single model. [LATER]
Selected iCores' Δ_public task-vectors (all trained against the same frozen anchor, FlexOlmo invariant) are merged with TIES/DARE on a qCore host into one bigger sparse LLM, served as a single model. Decomposable (drop a delta → the model re-forms without that member; exact opt-out, E1-verified). Cheaper at serve-time (one model, not N), persistent (a standing iQuorum can be pre-merged during consolidation), but carries the interference tax that grows with delta depth + member count (E1: ~28%/pack for heavily-overfit deltas; best merge 0.667 vs routing ceiling 0.934). Requires Δ_public to physically co-locate on the host → needs an attested qCore host (user-owned cloud iCore / iCore Prime, or a HiNet TEE) so a contributed delta is used-not-copied. BTX / distributed-MoE (Exo over LAN; Sukhbaatar et al. 2024) is the long-lived, larger-N variant [LATER].
Facts never weight-merge. Per the invariant, factual answers compose by retrieval-union: each member returns cited facts (like today's RAG citations), unioned at the aggregator — lossless — regardless of whether skills were merged or routed.
3.2 Which mode, when (the selector) [NEW]
pick_aggregation_mode(members, subtopics, budget, ctx):
if not same_compat_class(members): return COMMITTEE # cross-DNA → only output-level works
if any(m.is_icorp for m in members): return COMMITTEE # membrane: iCorp answers as a text unit
if deltas_conflict(members, subtopics): return COMMITTEE # "route conflicting" (WP §3 / 0.6.0)
if is_factual(subtopics): return RETRIEVAL_UNION# "retrieval-union for facts"
if standing_iquorum(members) and warm_merge_exists(members):
return MOERGING # reuse a pre-merged qCore (cheap, persistent)
if budget.latency_tight and n(members)<=3 and complementary(members):
return MOERGING # one model call < N network round-trips
return COMMITTEE # default: safe, ceiling-quality, no leakage
Decision inputs, all already grounded:
- same_compat_class ← anchor_passport.compat_class in the signature.
- deltas_conflict / complementary ← delta orthogonality signal (WP 0.6.0: conflict, not fact-vs-skill, governs mergeability). MVP proxy: speciality-centroid overlap + a small offline conflict table maintained during consolidation; [OPEN] a cheap online conflict estimator.
- warm_merge_exists ← a standing iQuorum previously pre-merged on a qCore host.
MVP simplification: ship COMMITTEE + RETRIEVAL_UNION only. MoErging/BTX are [LATER] because they require the attested qCore-host + Δ_public exchange plumbing. The selector above is built with all branches, but MoErging branches return COMMITTEE under a feature flag until the host exists — so no re-architecture when it lands.
4. The P2P layer — discovery, fan-out, assembly
4.1 MVP: signed HTTP to registered endpoints (via registry) [MVP]
Chosen for the first milestone. Rationale: hinetd is already an HTTP server (server.py); identity/signing already exist (Ed25519); a laptop node is loopback-only and behind NAT, so it cannot be a libp2p dialable peer without relays anyway. A central registry + relay on dedicated Quorumz-GCP resources gets us a working network fastest, while routing stays sovereign (on the asker's node).
Reachability. A laptop iCore is outbound-only. Two serve paths:
1. User-owned cloud iCore tier (WP §6, an existing tier): the owner's attested cloud tenant exposes the network endpoint directly. Preferred for always-on earners / iCore Prime.
2. Relay [MVP]: the laptop opens a persistent outbound WebSocket/HTTP2 tunnel to relay.mind.quorumz.com; the relay forwards signed quorum requests down it. The relay sees ciphertext-wrapped, signed envelopes and cannot read answers (end-to-end signed; optionally E2E-encrypted to the asker's pubkey). The relay is a dumb pipe, never an inference broker.
Central services (dedicated resources, Quorumz GCP):
| Service | Endpoint | Role | Status |
|---|---|---|---|
| Registry | POST /v1/nodes, GET /v1/discover |
competence index + phonebook (signed cards) | [MVP,NEW] |
| Relay | WSS /v1/relay/<node_id> |
forward signed requests to NAT'd nodes | [MVP,NEW] |
| Receipt ledger | POST /v1/receipts |
append signed receipts for settlement | [MVP,NEW] |
| Settlement | POST /v1/settle |
pay-per-use split (§5) | [LATER] |
Node network endpoints (new, gated; behind the relay/cloud tier — never the loopback UI origin):
| Endpoint | Role |
|---|---|
GET /v1/quorum/competence |
return this node's CompetenceSignature (freshness probe) |
POST /v1/quorum/answer |
answer ONE routed sub-prompt; returns a signed AnswerReceipt + filtered text, no raw data |
POST /v1/quorum/delta [LATER] |
serve/attest a Δ_public to a qCore host for MoErging |
4.2 Later: libp2p / Helia [LATER]
| Concern | Signed-HTTP + registry (MVP) | libp2p / Helia (later) |
|---|---|---|
| Discovery | central competence index (fast, simple, censorable) | Kademlia DHT / gossipsub topic per competence-cluster (decentralized, harder to rank) |
| Reachability | relay/cloud tier (NAT handled by relay) | libp2p AutoNAT + Circuit-Relay-v2 + hole-punching (DCUtR) |
| Identity | Ed25519 (already have) → maps 1:1 to libp2p PeerId | native PeerId |
| Transport auth | HTTP + detached Ed25519 sig + nonce | Noise-encrypted streams |
| Receipts | ledger rows on GCP | Helia/IPFS content-addressed receipts (CID = tamper-evident, portable) |
| Trust story | "platform runs the phonebook" | "no platform in the path" |
Recommendation: ship signed-HTTP MVP; keep every wire message transport-agnostic (§7) so the same QuorumRequest/AnswerReceipt ride a libp2p stream unchanged later. Adopt Helia first (for receipts — cheap win, real decentralization of the audit surface), gossipsub discovery second, full DHT last. Registry stays as an optional fast index even after DHT lands (hybrid, like a tracker beside a DHT).
Adopt-vs-build (2026-08) — SAM. SAM — Sovereign Agent Mesh (Google, Apache-2.0) already packages this whole "later" column: libp2p bootstrap/relay + environment-agnostic crypto identity + a control-plane registry + MCP tool routing across the mesh. It maps almost 1:1 onto the right-hand column above, so it is a candidate to adopt as the transport substrate rather than rebuild — HiNet rides it for discovery/relay/transport and keeps the intelligence layer (competence attestation §2.5, Quorum Memory §2.4, aggregation §3, economy §5) on top. Caveats to weigh: SAM is "not an officially supported Google product," and its identities register with the control plane whereas ours are self-certifying (registry-optional) — so keep our identity model (§2.1 / Node-Identity §1.2) and treat SAM as a swappable transport behind the transport-agnostic wire (§7). Signed-HTTP MVP stays P1; SAM/libp2p is the P3 transport to evaluate.
4.3 Result assembly
The asker's node fans out (bounded concurrency), collects AnswerReceipts, drops stragglers past the latency budget once the quorum threshold M-of-N is met (§6/§9), then runs aggregate() (§3.1) locally. Assembly always happens on the asker's node, because only it holds the private context and the final synthesis must not leave.
5. Attribution, receipts, consent, verifiable participation, no-leak
5.1 Consent gating (both sides) [EXISTS core, NEW use]
Reuse ConsentGrant.allowed_uses (consent.py) — add two uses: "quorum_answer" (this iCore may answer network queries) and "quorum_ask" (this node may send queries outward). The existing check(connector, account, scope, use, sensitivity) already enforces a sensitivity ceiling; network answering reuses it verbatim, keyed on a synthetic connector_id="network". A node with no quorum_answer grant simply never registers a serve endpoint → invisible to routing. Revocation (revoke_for) instantly removes it (drop-the-delta = drop-the-listing).
5.2 No raw data / no weights leave [NEW, enforced]
- Committee: a member returns only filtered text — the same
Δ_public/disclosure-filter "public mode" that governs what may leave (WP §2 "only filtered text leaves"). The/v1/quorum/answerhandler runs the answer through the disclosure filter + leakage gate before signing; raw vault chunks are used internally for retrieval but only cited (source label + date viaOrigin.display()), never shipped as content unless the answering owner's grant allows quoting. - Weight-merge: only the
Δ_publicprojection (already the "distilled, anchor-locked, leakage-gated" artifact) is ever contributed, and only to an attested qCore host.Δ_privateand vault never move. - Receipts carry hashes, not content (mirrors
audit.py, which is deliberately content-free).
5.3 Receipts + attribution [MVP,NEW]
Two signed objects, both appended to each side's existing audit hash-chain (audit.append(...)), so participation is locally tamper-evident with zero new crypto:
# AnswerReceipt — signed by the ANSWERING node, returned with its text
receipt_id: "arc_..."
query_id: "q_9f..." # correlates all legs of one qCore
answerer: "icore_ab12..." | "icorp_acme" # iCorp answers AS THE UNIT (members never named)
answered_at: "..."
subprompt_hash: "sha256:..." # what it was asked (content-free)
answer_hash: "sha256:..." # what it returned
tokens: { prompt: 812, completion: 240 }
self_confidence: 0.74
membrane: "free" | "icorp:acme"
price_quote_usd: 0.0016
verification: "signed" # MVP=Tier1; later "zk" (Tier5)
signature: "ed25519:..."
# QueryReceipt — assembled by the ASKER's node; the settlement source of truth
query_id: "q_9f..."
ask_mode: "auto" -> resolved "network"
aggregation_mode: "committee"
members:
- node: "icore_ab12...", answer_receipt: "arc_...", contribution_weight: 0.41 # from aggregate() (§3.1)
- node: "icorp_acme", answer_receipt: "arc_...", contribution_weight: 0.33
- node: "<own>", contribution_weight: 0.26 # aggregator/self
totals: { tokens: 1490, latency_ms: 3120 }
split: # pay-per-use (WP §6A/§6B)
platform_share_usd: 0.0008
payouts:
- to: "icore_ab12...", usd: 0.0021
- to: "icorp_acme", usd: 0.0017 # paid to the iCorp; internal iCores paid VIA the iCorp
final_answer_hash: "sha256:..."
created_at: "..."
signature: "ed25519:..." # asker-signed
Split algorithm [MVP defines, settlement LATER]:
payout(member) = pool_usd * (contribution_weight[member] / Σ weights)
pool_usd = price(query) - platform_share
contribution_weight = router_competence · answer_acceptance · judge_agreement
answer_acceptance = did the aggregator use it (1) or discard it as off-topic/contradicted (→0)? This prevents free-riding: a node that returns noise earns ~0 even if it "participated." iCorp attribution: a public receipt lists the iCorp as one payee and never references or pays internal iCores individually (membrane, WP §6B); internal split is computed inside the iCorp workspace from its own internal receipts.
5.4 Verifiable participation [MVP=Tier1, LATER=Tier5]
Ladder reuses the Technical-Spec verification tiers:
- Tier 0/1 (MVP): every AnswerReceipt is Ed25519-signed by the answering node and hash-chained on both audit logs → "node X genuinely produced answer with hash H at time T." Cheap, real, sufficient for honest-but-metered payouts + dispute records.
- Tier 3 (LATER): TEE attestation of the qCore host (for weight-merge — proves the delta ran unmodified).
- Tier 5 (LATER, research): ZK proof that the node actually ran its committed weights without revealing them (zkLLM; PUMA for MPC) — WP §6A/§9. This is what makes composition trustless at scale; explicitly out of MVP.
6. Routing algorithm — full pseudocode [NEW]
def answer(query, ask_mode, budget, ctx): # ctx: membrane, own_sig, sensitivity_ceiling
# --- 1. mode resolution ---------------------------------------------------
if ask_mode == "own":
return local_answer(query) # [EXISTS] personalize()+MLX
if ask_mode == "auto":
plan_kind = auto_decide(query, ctx.own_sig, budget) # §1.3
if plan_kind == LOCAL:
return local_answer(query)
# --- 2. targeting ---------------------------------------------------------
if ctx.target.startswith("icore:") or ctx.target.startswith("iquorum:"):
members = resolve_fixed_target(ctx.target) # skip discovery
mode = pick_aggregation_mode(members, [query], budget, ctx)
plan = QCorePlan(members, mode, shard(query, members, mode))
else: # "open"
plan = route(query, budget, ctx) # §2.2 right-sizing + §3.2 mode
if plan.members == [own_node]: # right-sized back to self
return local_answer(query)
# --- 3. consent + membrane pre-checks (asker side) ------------------------
assert consent_ok(ctx, use="quorum_ask", sens=classify(query)) # won't ship a too-sensitive query
plan.members = [m for m in plan.members if membrane_allows(ctx, m)] # §2.3
# --- 4. fan-out (bounded concurrency, hedged) -----------------------------
query_id = new_id()
legs = fan_out(plan, query_id, deadline=now()+budget.latency_ms) # §7 QuorumRequest per member
receipts = collect_until(legs,
threshold = plan.threshold, # M-of-N (§9)
deadline = budget.latency_ms,
hedge_after = p50_latency) # §9 speculative duplicate to a backup node
# --- 5. assemble locally (private context never left) ---------------------
if plan.mode in (COMMITTEE, RETRIEVAL_UNION):
final, weights = aggregate(query, receipts, local_context=own_vault) # §3.1
else: # MOERGING [LATER]
final, weights = qcore_host.merged_answer(query, plan.members) # §3.1(B)
# --- 6. receipts + audit --------------------------------------------------
qr = build_query_receipt(query_id, plan, receipts, weights, price(plan)) # §5.3
audit.append("quorum_answer_asked", "network", ctx.target, ref=query_id) # [EXISTS] hash-chain
ledger.submit(qr) # central, dedicated GCP
return final, qr
Server-side counterpart (/v1/quorum/answer, on a serving node):
def quorum_answer(req): # req: QuorumRequest (§7)
verify_sig(req); anti_replay(req.nonce, req.ts) # §9
if not consent.check("network", account="*", scope="*",
use="quorum_answer", sensitivity=req.sensitivity_hint):
return deny() # policy → 403, no data touched
hits = index.search(req.subprompt, filters=ceiling_filter()) # [EXISTS] own vault, secret excluded
draft = local_model.answer(req.subprompt, hits) # [EXISTS] MLX
text = disclosure_filter(draft, leakage_gate) # only filtered text may leave (WP §2)
rcpt = sign(AnswerReceipt(query_id=req.query_id, answer_hash=h(text), ...))
audit.append("quorum_answer_served", "network", req.asker, ref=req.query_id)
return { "text": text, "receipt": rcpt } # no raw chunks, no weights
7. Protocol / message schemas [NEW]
Transport-agnostic (HTTP body MVP; libp2p stream later). All signed with the existing Ed25519 identity.
# QuorumRequest — one leg, asker → member (via relay or direct)
type: "quorum.request/v1"
query_id: "q_9f..."
leg_id: "leg_2"
asker: "icore_zz..." # pubkey-addressable
subprompt: "..." # the sharded facet (may be the whole query if T=1)
sensitivity_hint: "personal" # asker's declared class → member enforces its own ceiling too
budget: { max_completion_tokens: 300, latency_ms: 6000, max_usd: 0.01 }
membrane_ctx: { asker_kind: "free" | "icorp", icorp_id: null }
want_receipt: true
nonce: "..." # anti-replay (§9)
ts: 1723958400
reply_to: "wss://relay.../n/icore_zz" # where to send the response (relay path)
signature: "ed25519:..."
# QuorumResponse — member → asker
type: "quorum.response/v1"
query_id: "q_9f..."; leg_id: "leg_2"
status: "ok" | "declined" | "timeout" | "policy_denied"
text: "...(disclosure-filtered)..."
citations: [ { label: "WhatsApp › Family · 2026-08-12", url: null } ] # Origin.display() [EXISTS]
receipt: { ...AnswerReceipt... } # §5.3
signature: "ed25519:..."
CompetenceSignature (§2.1), AnswerReceipt + QueryReceipt (§5.3), and QCorePlan (below) complete the set:
QCorePlan:
query_id: "q_9f..."
members: [ "icore_ab12...", "icorp_acme", "<own>" ]
mode: "committee" | "moerging" | "retrieval_union"
subprompts: { "icore_ab12...": "...", "icorp_acme": "..." }
threshold: 2 # M-of-N required to answer (§9)
deadline_ms: 6000
8. Sequence flows (text)
Flow A — AUTO stays local (right-sized to self).
Owner → hinetd POST /v1/chat/completions {ask_mode:"auto", "what did Dana say about the invoice?"}
hinetd: auto_decide → embed(q); s_self high (personal, in-vault), breadth low → LOCAL
hinetd: personalize() retrieves from vault → MLX answers → cite [1]
hinetd → Owner: answer (0 network calls, $0, offline-capable)
Flow B — ask-the-network, open, committee (MVP).
Owner → hinetd POST /v1/chat/completions {ask_mode:"network", target:"open",
"best pattern to secure a Solidity permit() against signature replay?", budget}
hinetd.route(): decompose→1 facet; discover(registry) → [solidity-sec iCore, audit iCorp, own]
right-size: own weak here → add solidity-sec iCore (+0.5 cov), add iCorp (+0.3) → STOP
pick_mode: cross-DNA + iCorp present → COMMITTEE ; threshold 2-of-3
hinetd: consent_ok(quorum_ask, sens=public) ✓ ; membrane: public asker, iCorp visible as identity ✓
hinetd → relay → {solidity iCore, Acme iCorp} (2 signed QuorumRequests, hedged)
solidity iCore: verify+consent✓ → vault search → MLX → disclosure filter → sign AnswerReceipt → text
Acme iCorp: internal fan-out INSIDE membrane (opaque) → answers AS unit → sign receipt
hinetd: both legs back < deadline → aggregate() locally (own model synthesizes, cites [1][2])
weights: solidity 0.5, iCorp 0.3, own 0.2
hinetd: build QueryReceipt + split; audit.append(); ledger.submit()
hinetd → Owner: synthesized answer + "answered by 2 network nodes · $0.004" chip
Flow C — MoErging on a qCore host (LATER).
Owner → hinetd {network, target:"iquorum:crypto-eng"} (a STANDING predefined iQuorum)
hinetd: members same compat_class, complementary deltas, warm merge exists → MOERGING
hinetd → qCore host (attested TEE / owner cloud iCore): merged model = anchor ⊕ TIES(Δ_public[members])
qCore host: single forward pass over the bigger sparse LLM → answer (+ TEE attestation)
hinetd: retrieval-union of members' cited FACTS layered on top (facts never merge)
hinetd: QueryReceipt attributes by delta-activation share; audit; ledger
hinetd → Owner: answer + attestation ref
Flow D — iCorp member asks openly inside the workspace.
Member → hinetd(workspace) {network, target:"open", allow_membrane_cross:false}
route.discover: membrane=icorp:acme → candidates = ALL internal member iCores + internal iQuorumz
(public network excluded by policy)
right-size + COMMITTEE over internal members → aggregate
QueryReceipt: internal attribution retained INSIDE membrane; nothing crosses out; SaaS-metered, not pay-per-use
9. Latency & failure handling [MVP]
- Quorum threshold M-of-N: answer as soon as
Mlegs return (defaultM = ceil(N/2), min 1 beyond self). Late legs are dropped and do not earn (no receipt materialized). - Deadline + hedging: each leg has
latency_ms; if a leg exceedsp50, fire a speculative duplicate to the next-best candidate (cuts tail latency; only the first responder is paid). - Streaming: stream the aggregator's synthesis to the owner as soon as
Mlegs land; a straggler that arrives mid-synthesis is ignored for this turn. - Graceful degradation: if
< Mlegs return before deadline → fall back to the owner's own iCore answer, labeled "answered locally — network incomplete." AUTO never hard-fails a query. - Anti-replay / auth:
nonce + tswindow (±120s) on everyQuorumRequest; duplicate nonce → drop. Relay enforces per-node rate limits. - Flaky-node circuit breaker: rolling error/timeout rate per
node_id; over threshold → drop from candidate pool for a cool-down; reflected as loweredavailability_7din its signature. - Membrane/consent failures are silent to the network: a
policy_deniedleg returns a signed decline (for the audit trail) but no data and no partial content. - Idempotency:
query_id + leg_iddedupe so a relay retransmit never double-charges or double-appends. - Registry outage: nodes cache the last competence index locally (TTL'd); routing degrades to cached candidates, then to LOCAL — never to a broken chat.
10. MVP vs later
| Capability | MVP [MVP] |
Later [LATER] |
|---|---|---|
| Ask-modes | own [EXISTS], network, auto |
— |
| Targeting | specific iCore, predefined iQuorum, open |
— |
| Router | competence-signature + greedy right-sizing (flat index) | hierarchical router-of-routers; online conflict estimator |
| Aggregation | committee/MoA + retrieval-union | MoErging/weight-merge; BTX/distributed-MoE (Exo LAN) |
| qCore host | none (committee needs none) | attested TEE / user-cloud host for delta-merge |
| P2P | signed-HTTP + central registry + relay | libp2p (PeerId/gossipsub/DHT); Helia receipts (first) |
| Membranes | free-iCore + iCorp-as-identity pre-filter; internal workspace routing | cross-membrane externalization policies |
| Attribution | signed AnswerReceipt/QueryReceipt + audit-chain; split computed |
on-chain/micropayment settlement |
| Verifiable participation | Tier 1 (signed + hash-chained) | Tier 3 (TEE), Tier 5 (zkLLM/MPC) |
| Reachability | relay tunnel / user-cloud tier | libp2p AutoNAT + Circuit-Relay + hole-punch |
11. Open decisions [OPEN]
- AUTO thresholds (
τ_self,β_narrow,κ) — calibrate against real query logs; risk of surprising the owner with paid network calls. Default conservative (bias LOCAL) + a visible "went to network" chip + per-query local-override. - Delta-conflict estimator — MVP uses centroid overlap + an offline conflict table from consolidation; an online, cheap conflict signal is unsolved (feeds
routevsmerge). - Query-privacy on egress — even a "public" query can leak intent. Need a query-side disclosure filter symmetric to the answer-side one, and possibly a private-information-retrieval option for the registry lookup.
- iCorp internal split fairness — how internal receipts credit member iCores under the lease (contribution stays with the iCorp on exit, but pay while employed) — governed inside the membrane; schema TBD.
- Sybil / competence-inflation — a node can over-claim
strength. Need reputation feedback:answer_acceptancehistory down-weights liars over time;[OPEN]staking/slashing. - Registry trust — central index is censorable/rankable by the platform. Hybrid DHT + Helia receipts is the mitigation path; decide when the decentralization cost is worth the latency.
- Contribution-weight ground truth —
aggregate()'s weights drive real money; an LLM-judge aggregator is gameable. Consider structured/consensus checks (Tech-Spec Thought-Convergence) for high-value queries. - Compat-class migration — when the anchor upgrades (Qwen3-Next → next MoE), standing merged qCores and
compat_classsignatures must re-base; routing must not silently mix classes mid-migration.
12. What this reuses vs adds
Reused [EXISTS]: OpenAI-compatible /v1/chat/completions + /v1/agent tool-loop (server.py), personalize() retrieval, MemoryIndex hybrid RAG + Origin citations, ConsentStore.check/allowed_uses, AuditLog hash-chain (append/verify), CanonicalItem/Origin, Ed25519 node identity, ComputeBackend WorkOrder/Receipt seam, SourceConnection/Registry patterns, /node/proof guarantee.
Added [NEW]: hinet_ask_mode/hinet_quorum body fields; net/router.py (right-sizing selector + mode picker); CompetenceSignature; /v1/quorum/{competence,answer,delta}; central registry+relay+ledger on dedicated Quorumz-GCP resources; QuorumRequest/QuorumResponse/AnswerReceipt/QueryReceipt/QCorePlan; two new consent uses (quorum_ask/quorum_answer); disclosure-filter-on-egress; committee aggregator; (later) qCore merge host + verifiable-participation ladder.