Files
organism/elements/neuron/appunti/2026-06-19-tripartite-synapse_v10.md
T
2026-06-21 19:42:46 +02:00

511 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tripartite Synapse — Pseudocode v10
> Companion document: `tripartite_synapse_v10_biology.md` explains the biological
> meaning of every variable and behavior. This document is the logic only.
---
## Conventions
```
SCOPE = { DAY, NIGHT }
CONTEXT = { AP, NOT_AP, bAP, NOT_bAP, CONTINUOUS }
COMPONENTS = { PRE, POST, DEND, SOMA, AXON, ASTRO }
DAY variables
budget fast resource (energy + consumables), consumed by behavior
fast_trace local record, decays in mss, biases next behavior
possible_tag accumulates from fast_trace, decays in smin
endurance_need accumulates on interrupted local success, decays in smin
DAY→NIGHT bridge
tag decays in hours; POST: CANDIDATE → STABLE
NIGHT variables
energy assembly ATP, NOT recoverable
material structural proteins, RECOVERABLE after decay
structure strength ceiling — READ in DAY, WRITTEN in NIGHT
budget_ceiling endurance ceiling — READ in DAY, WRITTEN in NIGHT
LOCALITY RULE
every evaluation uses only local state + signals that have arrived.
no component reads another compartment's internal state.
CLEFT MESSAGE CHANNELS (the only PRE/POST/ASTRO interaction — each writes, others read)
glutamate PRE → POST, ASTRO (forward transmitter; cleared by ASTRO)
astro_Dserine ASTRO → POST (NMDA co-agonist gate)
retro_NO POST → PRE (+) (NO/BDNF: "release reached a responsive target")
retro_eCB POST → PRE () (endocannabinoid: "over-driven, suppress release" = DSE)
Each channel decays/clears; a component reads a channel into a local copy and computes locally.
```
---
## Saturating form (used wherever a graded signal drives output)
```
sat(x, K) = x / (K + x)
```
---
## Fixed parameters
```
K_release K_AMPA K_Dserine
Mg_eject Ca_STP Ca_TAG eCB_thr
elig dop_thr tag_thr tag_expiry
traj_thr endur_thr
spillover inactivation overload
homeostatic_ceiling decay_rate capacity_decay_rate recycle
dopamine NE ACh // organism broadcast (external)
glucose // vascular ceiling (external)
geometry // dendritic topology (external)
```
---
---
# DAY
Execution contexts (AP, bAP, CONTINUOUS): run behavior, spend budget, deposit traces.
Replenishment contexts (NOT_AP, NOT_bAP): competitive refill, ship downstream, decay traces, set tags.
---
## Pool-filling primitives
Two shapes share the core "rise toward a ceiling, bounded by the gap, paying budget":
```
// PRIVATE: fill own pool from own reserve toward own ceiling, at a rate cap
fill(pool, ceiling, rate_cap, cost, budget):
amount = min(rate_cap, ceiling - pool)·Δt // bounded by rate AND gap
pool += amount
budget -= amount·cost
// CONTESTED: fill toward ceiling by a rationed share of a shared supply S
refill(component c from supply S):
demand = c.budget_ceiling - c.budget // claim = gap to ceiling
total = Σ demand over components on S
factor = min(1, S / (total + ε))
c.budget += demand × factor // never exceeds ceiling
S -= demand × factor
```
Choose by source: a pool drawn from a **private reserve** uses `fill`; a pool drawn from a
**contested shared supply** uses `refill`. The distinction is biologically real — RRP comes
from the bouton's private reserve pool, while operational budget comes from astrocytic lactate
that neighbours compete for.
---
## PRE
```
// ─── PRESYNAPSE EXTERNAL INTERFACE ────────────────────────────────────────
// PRE computes locally. Everything below crosses its boundary as a signal it
// emits or a resource/signal it receives. It never reads another component's state.
//
// OUTPUT (PRE writes; others read)
// glutamate → POST, ASTRO forward transmitter; ASTRO clears it
//
// RESOURCES IN (others write; PRE reads in NOT_AP)
// astro_lactate[syn] ← ASTRO primary fast fuel → pre_budget
// axon_ship_pre ← AXON secondary fuel → pre_budget
// ship(axon_budget → pre_budget, gap_to(pre))
// pre_material ← AXON (NIGHT) AZ proteins (RIM, Munc13, VGCC subunits)
// pre_energy ← SOMA (NIGHT) assembly ATP for active-zone construction
//
// BACKWARD MESSAGES IN (POST writes from its own state; PRE reads)
// retro_NO (+) ← POST "release reached a responsive target" → endurance
// retro_eCB () ← POST DSE: "over-driven, release less" → brake
//
// CLEFT SELF-FEEDBACK (PRE reads the channel it writes)
// glutamate ← cleft spillover autoreceptor brake (mGluR2/3 on PRE)
//
// ORGANISM BROADCAST IN (external; arrives as a local level)
// dopamine ← VTA gates pre_tag (the non-local coincidence)
// NE, ACh ← LC, basal excitability/threshold context
//
// OWN STRUCTURE (written NIGHT, read DAY)
// pre_structure slot_ceiling, VGCC_coupling, refill_ceiling
// pre_budget_ceiling endurance ceiling (bounds replenishment)
//
// EMERGENCY
// shockwave_lockdown ← ASTRO global Ca²⁺ wave overrides PRE
// ──────────────────────────────────────────────────────────────────────────
DAY | AP:
// SENSE — deposit fast trace (residual Ca²⁺ from this spike; also drives release)
pre_fast_trace += spike_Ca(input_freq)
// BEHAVE — release, or fail if depleted
if pre_budget < release_cost:
suppress(NT_flux)
// EVALUATE (endurance) — interrupted LOCAL success, confirmed by retro_NO
if pre_fast_trace > traj_thr:
pre_endurance_need += pre_fast_trace × (1 + retro_NO_local)
exit
drive = sat(pre_fast_trace, K_release) × (1 - retro_eCB_local) // received DSE brake
if RRP > 0:
NT_flux = RRP × drive
// EMIT — glutamate into cleft (read by POST, ASTRO)
glutamate += NT_flux·Δt
RRP -= NT_flux·Δt; pre_budget -= NT_flux·fusion_cost
if glutamate > spillover: drive *= brake // own-cleft autoreceptor brake
// no RECOVER here — RRP refills in NOT_AP; high-frequency firing depletes
// faster than it recovers → short-term depression deepens
DAY | NOT_AP:
// RECEIVE — latch arrived backward messages; replenish budget (contested supply)
retro_NO_local = retro_NO
retro_eCB_local = retro_eCB
refill(pre from astro_lactate[syn] + axon_ship_pre)
// RECOVER — refill RRP from private reserve toward its ceiling
fill(RRP, pre_structure.slot_ceiling, pre_structure.refill_ceiling, vatpase_cost, pre_budget)
// EVALUATE (strength) — eligibility → possible_tag → tag (needs dopamine)
if pre_fast_trace > elig: pre_possible_tag += pre_fast_trace
if dopamine > dop_thr and pre_possible_tag > tag_thr:
pre_tag += dopamine × pre_possible_tag
// DECAY — all traces and channels recede, closing their windows
pre_fast_trace *= decay(100ms)
pre_possible_tag *= decay(s)
pre_endurance_need *= decay(min)
pre_tag *= decay(hr)
dopamine *= decay(ms) // broadcast transient fades
retro_NO *= decay(s); retro_eCB *= decay(s) // backward channels clear
```
---
## POST
```
DAY | NOT_bAP:
refill(post from astro_lactate[syn] + dend_ship_post)
// SOURCE 1 — AMPA: current + small Ca + begins Mg ejection
a = sat(glutamate, K_AMPA)
AMPA_current = a × AMPA_surface; Vm += AMPA_current
post_fast_trace += AMPA_Ca·AMPA_current; post_budget -= AMPA_cost
// SOURCE 2 — NMDA: large Ca if local coincidence
if Vm > Mg_eject and astro_Dserine > thr and glutamate > 0:
post_fast_trace += NMDA_Ca(glutamate)·rise_speed(); post_budget -= NMDA_cost
retro_NO += NO_emit(post_fast_trace); post_budget -= NO_synth_cost
// POST → PRE (+): nNOS coupled to NMDA emits NO/BDNF — "your release was effective"
// backward brake to PRE (): strong depolarization → endocannabinoid (DSE)
if Vm > eCB_thr:
retro_eCB += eCB_emit(Vm); post_budget -= eCB_synth_cost
// POST → PRE (): "I am over-driven — reduce release"
post_fast_trace *= decay(ms)
// CASE 1 — short-term potentiation: fill slots from private reserve (no dopamine)
// NOT generic fill(): rate is Ca-driven, and the else-branch is the STD consequence
if post_fast_trace > Ca_STP:
AMPA_surface = min(AMPA_surface + Ca_insert(post_fast_trace),
post_structure.slot_ceiling) // private: spine endosomal reserve
post_budget -= traffic_cost
else:
AMPA_surface = max(AMPA_surface - drift·Δt, baseline) // STD = consequence
// interrupted success (LOCAL: my Ca was climbing toward a tag)
if post_budget < req_cost and post_fast_trace > traj_thr and post_fast_trace_rising:
post_endurance_need += post_fast_trace
// CASE 2 — tagging CANDIDATE
if post_fast_trace > Ca_TAG: post_possible_tag += post_fast_trace
post_possible_tag *= decay(min); post_endurance_need *= decay(min)
post_budget -= pka_cost
dopamine *= decay(ms)
if dopamine > dop_thr and post_possible_tag > tag_thr:
post_tag += dopamine × post_possible_tag // STABLE
post_tag *= decay(hr)
DAY | bAP:
// SOURCE 3 — bAP: depolarization + Ca, amplifies existing signal
Vm += bAP_depol × dend_structure.bAP_fidelity; post_budget -= bAP_cost
if post_possible_tag > Ca_TAG: post_fast_trace += bAP_Ca_boost()
```
---
## DEND
```
DAY | bAP:
bAP_local, reached = propagate(SOMA.fired, dend_structure.bAP_fidelity,
dend_budget, geometry)
dend_budget -= prop_cost × reached
// interrupted success (LOCAL: my branch was strongly active)
if reached < full and dend_fast_trace > traj_thr:
dend_endurance_need += dend_fast_trace
dend_fast_trace += bAP_Ca(bAP_local) + spine_spillover(); dend_fast_trace *= decay(300ms)
dend_budget -= branch_Ca_cost
branch_Vm = integrate(POST.Vm, spines); dend_budget -= integrate_cost
DAY | NOT_bAP:
dend_fast_trace *= decay(300ms); dend_endurance_need *= decay(min)
refill(dend from astro_lactate[branch] + soma_ship_dend)
ship(dend_budget → post_budget, gap_to(post))
if dend_fast_trace > elig: dend_possible_tag += dend_fast_trace
dend_possible_tag *= decay(s); dopamine *= decay(ms)
if dopamine > dop_thr and dend_possible_tag > tag_thr:
dend_tag += dopamine × dend_possible_tag
dend_tag *= decay(hr)
if dend_tag > tag_expiry and dend_budget > translate_cost:
dend_budget -= translate_cost
commit_threshold *= 1/(1 + ACh·gain)
```
---
## SOMA
```
DAY | AP:
threshold = soma_structure.baseline / (1) // baseline strength
× (1 + soma_adaptation)
× neuromod(NE, ACh)
can_fire = soma_Na_inactivation < inactivation
if branch_Vm > threshold and can_fire:
if soma_budget < ap_cost:
// interrupted success (LOCAL: nuclear Ca climbing toward CREB)
if soma_fast_trace > traj_thr and soma_fast_trace_rising:
soma_endurance_need += soma_fast_trace
exit
fired = True; soma_budget -= ap_cost
soma_Na_inactivation += ap_amp // → refractory (emergent)
soma_adaptation += ap_contrib // → threshold rise
soma_fast_trace += nuclear_Ca() // → plasticity
soma_budget -= nuclear_cost
if soma_fast_trace > elig: soma_possible_tag += soma_fast_trace
soma_possible_tag *= decay(s); dopamine *= decay(ms)
if dopamine > dop_thr and soma_possible_tag > tag_thr:
soma_tag += dopamine × soma_possible_tag
soma_tag *= decay(hr); soma_budget -= creb_cost
DAY | NOT_AP:
// bottom-up alignment: suprathreshold input during refractory (LOCAL)
if branch_Vm > threshold and soma_Na_inactivation > inactivation:
soma_refractory_alignment += (branch_Vm - threshold) × soma_Na_inactivation
recovery = base_recovery × (1 + soma_refractory_alignment)
soma_Na_inactivation *= decay(τ_Na / recovery)
soma_adaptation *= decay(τ_adapt)
soma_fast_trace *= decay(τ_nuclear)
soma_refractory_alignment *= decay(τ_align) // self-limiting
soma_endurance_need *= decay(min)
fill(soma_budget, soma_budget_ceiling, mito_output, 0, soma_budget) // private: own mitochondria, no external cost
branch_Vm = integrate(DEND.branch_Vm, branches)
ship(soma_budget → dend_budget, gap_to(dend))
ship(soma_budget → axon_budget, gap_to(axon))
```
---
## AXON
```
DAY | AP:
reliability = axon_structure.propagation × (1 - fail(axon_fast_trace))
if axon_budget < prop_cost:
reliability *= budget_factor
// interrupted success (LOCAL: I was propagating a strong train)
if axon_fast_trace > traj_thr:
axon_endurance_need += axon_fast_trace
delivered = fired × reliability; axon_budget -= prop_cost × delivered
axon_fast_trace += delivered; axon_fast_trace *= decay(s)
DAY | NOT_AP:
axon_fast_trace *= decay(s); axon_endurance_need *= decay(min)
refill(axon from soma_ship_axon + astro_lactate[shaft])
ship(axon_budget → pre_budget, gap_to(pre))
if axon_fast_trace > elig: axon_possible_tag += axon_fast_trace
axon_possible_tag *= decay(s); dopamine *= decay(ms)
if dopamine > dop_thr and axon_possible_tag > tag_thr:
axon_tag += dopamine × axon_possible_tag
axon_tag *= decay(hr)
```
---
## ASTRO
```
DAY | CONTINUOUS:
astro_central_budget += glycolysis(glucose)·Δt // root, capped by glucose
// demand-weighted lactate allocation across territory
for each astrosynapse i:
demand[i] = clearance_load[i] × astro_structure[i].delivery_eff
factor = min(1, astro_central_budget / (Σ demand · lactate_cost + ε))
for each i:
astro_lactate[i] = demand[i] × factor
astro_central_budget -= astro_lactate[i] × lactate_cost
// per-astrosynapse fast operation (synapse i)
glutamate[i] -= astro_structure[i].EAAT × glutamate[i]·Δt
astro_central_budget -= clearance × EAAT_cost
astro_Dserine[i] += astro_structure[i].Dserine_tonic·Δt
if glutamate[i] > spillover:
astro_fast_trace[i] += mGluR_Ca(); astro_fast_trace[i] *= decay(s)
want = sat(astro_fast_trace[i], K_Dserine) × Ds_max
got = min(want, astro_central_budget × Ds_frac)
// interrupted success (LOCAL: I was under high demand)
if got < want and astro_fast_trace[i] > traj_thr:
astro_endurance_need[i] += (want - got)
astro_Dserine[i] += got; astro_central_budget -= got × Ds_cost
drive_pre[i] *= brake // same signal, PRE brake
if astro_fast_trace[i] > elig: astro_possible_tag[i] += astro_fast_trace[i]
astro_possible_tag[i] *= decay(s); dopamine *= decay(ms)
if dopamine > dop_thr and astro_possible_tag[i] > tag_thr:
astro_tag[i] += dopamine × astro_possible_tag[i]
astro_tag[i] *= decay(hr)
astro_endurance_need[i] *= decay(min)
if astro_fast_trace[i] > overload: trigger(lockdown)
```
---
## Special — Shockwave Lockdown
```
DAY or NIGHT | OVERLOAD:
Vm = HYPERPOLARIZED; AMPA_surface = mass_internalize() → post reserve
axon_fast_trace += overdrive(); astro_central_budget -= emergency_cost
```
---
---
# NIGHT
Build ceilings (structure = strength, budget_ceiling = endurance) from DAY evidence.
Two economies (energy: astrocyte→astrosynapse ; material: soma→spine/bouton) compete.
Unmaintained ceilings decay; recovered material funds the rest.
---
## Step 1 — Replenish and distribute
```
NIGHT | 1:
// energy economy (astrocyte central → astrosynapses, tag-weighted)
astro_central_budget += overnight_glycolysis(glucose)·Δt
astro_central_energy += overnight_astro_energy()·Δt
astro_central_material += astro_cellbody_synth()·Δt
W = Σ astro_tag[i] over astro_tag[i] > tag_expiry
for each i with astro_tag[i] > tag_expiry:
w = astro_tag[i]/W
astro_energy[i] += astro_central_energy × w
astro_material[i] += astro_central_material × w
// material economy (soma → branch/axon → spine/bouton)
soma_budget += overnight_mito()·Δt
soma_energy += overnight_soma_energy()·Δt
soma_material += CREB_synth(soma_tag)·Δt // bottleneck
dend_material += soma_material × f_dend; axon_material += soma_material × f_axon
soma_material -= (f_dend + f_axon)·soma_material
post_material += dend_material × f_spine; dend_material -= f_spine·dend_material
pre_material += axon_material × f_bouton; axon_material -= f_bouton·axon_material
{pre,post,dend,axon}_energy += soma_energy × f_energy[·]
{pre,post,dend,axon}_budget += astro_lactate_reserve × f[·]·Δt
```
## Step 2 — Strength commits (raise structure)
```
NIGHT | 2:
coherence = (pre_tag, post_tag, astro_tag all > tag_expiry) ? bonus : 1
for each component c with c_tag > tag_expiry:
Δ = min(slot_cost, c_material, c_energy × f)
c_structure += Δ × (coherence if c in {pre,post,astro} else 1)
c_material -= Δ; c_energy -= Δ × assembly_cost
if Δ < slot_cost: queue(c_strength_deficit → next NIGHT)
// astro_structure self-reinforcing: higher → future LTP easier
```
## Step 2b — Endurance commits (raise budget_ceiling)
```
NIGHT | 2b:
// driven by endurance_need (interrupted local success), NO dopamine
// competes with step 2 for the SAME material + energy
for each component c with c_endurance_need > endur_thr:
Δ = min(cap_cost, c_material × f_cap, c_energy × f_cap)
c_budget_ceiling += Δ
c_material -= Δ; c_energy -= Δ × biogenesis_cost
if Δ < cap_cost: queue(c_endurance_deficit → next NIGHT)
```
## Step 3 — Passive decay (both ceilings, by neglect)
```
NIGHT | 3:
remaining = total_material - consumed_by_commits
maint = remaining × maint_frac / synapse_count
for each synapse:
{pre,post,dend,astro}_structure -= decay_rate·Δt
{pre,post,dend,astro}_budget_ceiling -= capacity_decay_rate·Δt
if maint ≥ maint_cost:
structure += full_maint; budget_ceiling += full_cap_maint
else:
structure += maint × frac; budget_ceiling += maint × cap_frac
// both drift down — depotentiation / endurance-loss by neglect
for each synapse with net_change < 0:
rec = |net_change| × recycle
{pre,post,astro}_material += rec × frac // material recovered, energy not
```
## Step 4 — Homeostatic scaling
```
NIGHT | 4:
if soma_tag > homeostatic_ceiling:
s = homeostatic_ceiling / soma_tag
for each synapse:
post_structure.slot_ceiling *= s; pre_structure.slot_ceiling *= s
soma_material += Σ reduction × recycle
```
## Step 5 — Clear traces
```
NIGHT | 5:
all fast_trace = 0; all possible_tag = 0; all endurance_need = 0
soma_Na_inactivation = soma_adaptation = soma_refractory_alignment = 0
for each tag: if tag < tag_expiry: tag = 0 // else carry forward
// structure and budget_ceiling PERSIST
```
---
## One-view summary
```
DAY behavior runs within structure (strength) and budget_ceiling (endurance),
both filled by competition; consumes budget; deposits fast_trace.
fast_trace + non-local coincidence → tag (strength evidence)
depletion + interrupted LOCAL success → endurance_need (endurance evidence)
traces decay in NOT/CONTINUOUS contexts.
NIGHT tag → raise structure
endurance_need → raise budget_ceiling
both draw the SAME material + energy → strength and endurance compete
unmaintained ceilings decay → freed material funds the rest.
LOCALITY every evaluation uses only local state + arrived signals.
cross-compartment influence travels only as signals that become local.
```