Skip to content

Psycho — Pathfinding Under Weight Ablation

Echo radiates in every direction. Psycho picks one and pays for it.

Echo answers what resonates with this. Psycho answers how memory gets from here to there — and, more usefully, what the observer's own values were doing to that route.


The question it answers

Every ranking function in INDB carries the observer's weights: what matters, what costs, what to avoid. You can argue about those weights forever. Psycho measures them instead.

It finds the route twice — once with the observer's valuation honoured, once with it removed — and reports the divergence. If both runs pick the same route, the valuation was decoration on this question. If they diverge, the gap is exactly what the valuation was buying.

This is a weight ablation, the same move used to test whether a term in any model is load-bearing. The psychopath profile is the ablation probe: the name describes what is removed from the cost function, not a claim about anyone.


Why zeroing the weights is not the design

The obvious version of this idea — "give every intermediate node zero weight and take the shortest path" — does not work. If every node costs zero, every route costs zero, every path ties, and shortest-path returns something arbitrary. Removing the cost removes the ranking signal along with it.

So Psycho ablates one class of weight and keeps the structural term:

Term What it is Ablated by psychopath?
token Echo's token-overlap harmonic no — raised
meta Echo's location and cyclic harmonic no — raised
emotion Echo's emotional harmonic yes, to zero
barrier the observer's negative token weights yes, ignored

A route still exists and is still ranked. Only the observer's valuation is gone.


The cost model

cost(a → b) = -log R(a, b) + barrier(b)

R is Echo's harmonic resonance under the profile's weights. Minimising a sum of -log R maximises the product of resonances along the route, so the cheapest path is the most plausible chain rather than merely the one with fewest hops.

barrier(b) is what the observer pays to pass through b. It comes from the negative entries of token_weights: {"harm": -6.0} reads as routing through anything tokened harm costs me 6. Positive weights describe what an observer wants to find, which is Prism's job — they do not shape a route.

Edges are rebuilt from the profile's weights on every run. The scores cached in the resonance graph were computed under the defaults, and reusing them would make the ablation a fiction.


Profiles

Profile Harmonics (token / emotion / meta) Valuation Role
neutral 0.2 / 0.3 / 0.5 honoured ×1 The baseline. Echo's own weights.
psychopath 0.4 / 0.0 / 0.6 ignored ×0 The ablation probe.
empath 0.15 / 0.55 / 0.3 doubled ×2 The opposite pole — an ablation needs something to lean against.

API

GET /api/v2/psycho/profiles

Lists the profiles and what each one removes.

POST /api/v2/psycho/path

curl -X POST https://api.indb.tech/api/v2/psycho/path \
  -H "Content-Type: application/json" \
  -d '{
    "from": "<event-id or free text>",
    "to":   "<event-id or free text>",
    "profile": "psychopath",
    "compare_to": "neutral",
    "token_weights": {"harm": -6.0}
  }'

from and to accept an event id or free text, which resolves by token and location overlap. compare_to: null returns a single route with no comparison.


Reading the result

neutral    (valuation honoured) : route/start → route/detour-a → route/detour-b → route/goal
                                  cost 7.34, 3 hops
psychopath (valuation ablated)  : route/start → route/gate → route/goal
                                  cost 3.93, 2 hops

identical_route                False
shared_prefix                  1
hop_delta                      -1
probe_cost_on_baseline_scale   11.32
detour_cost                    3.98
baseline_route_barrier         0.0
probe_route_barrier            6.0
barrier_walked_into            6.0
Field Meaning
identical_route True means the ablation changed nothing — no signal on this pair
shared_prefix How many nodes the two routes agree on before splitting
diverges_at The node where they part
probe_cost_on_baseline_scale The ablated route re-priced under the baseline, so both numbers answer the same question
detour_cost That figure minus the baseline's own cost — what the shortcut really costs
probe_route_barrier What the observer would pay to walk the ablated route
barrier_walked_into How much barrier the shortcut enters that the baseline avoided
verdict The above in a sentence

detour_cost is the headline. Large means the removed weights were genuinely steering. Near zero with different routes means they were steering without buying anything — a finding about your weights, not about the data.

Note that path.barrier_paid is not the interesting number: it is what the route cost under the profile that found it, and an ablated profile prices the barrier at zero by construction. probe_route_barrier is the honest figure.


Limits

  • Search is capped by max_hops (default 6) and max_visited (default 2000). A result carrying reason: "search budget exhausted" is not a statement that no route exists.
  • Neighbours come from the resonance graph, the causal index and the token index. Echo's semantic pass is deliberately skipped: it runs an embedding model per node, which is fine once and ruinous inside a search that expands thousands.
  • Edges below a minimum resonance are dropped, so two anchors sharing nothing stay disconnected instead of being joined by noise.
  • Psycho reads. It never writes an event, and it never invents one — every node on a route is something already ingested.

Try it

INDB_API_URL=http://127.0.0.1:8000 INDB_API_KEY=<writer-key> \
  python3 scripts/psycho_demo.py

Ingests a fork — a short chain through a costly node, a longer one around it — and prints the comparison above.