Policy Rules Reference

Introduction

The Axis Descriptor Lab includes a server-side relabelling endpoint, POST /api/relabel, used by the Auto (policy) toggle in the UI.

That endpoint tracks the current axis policy shipped in pipeworks_mud_server for the bundled world:

  • data/worlds/pipeworks_web/policies/axes.yaml

  • data/worlds/pipeworks_web/policies/thresholds.yaml

The mud server remains the runtime authority. Axis Lab keeps a checked-in lab-side copy of the current ordering and thresholds in app/relabel_policy.py so the UI can inspect and relabel deterministically without expanding the older local-mirror model into a second source of truth.

Mechanism

Matching uses inclusive score ranges derived from the mud-server thresholds.yaml files.

For each known axis:

  1. Ranges are checked in declared order.

  2. A label matches when min_score <= score <= max_score.

  3. Unknown axes are left unchanged.

  4. If a score falls outside every configured range, the existing label is preserved because the lab schema requires a non-empty string label.

Canonical Axis Order

The standalone slider UI uses the same full-axis order as the mud-server axes.yaml file:

  1. physique

  2. wealth

  3. health

  4. demeanor

  5. age

  6. facial_signal

  7. legitimacy

  8. visibility

  9. moral_load

  10. dependency

  11. risk_exposure

When the chat page is connected to a mud server, the selected world’s active_axes order is shown first, and any remaining axes fall back to the canonical order above.

Policy Table

Physique

Score Range

Label

0.00 – 0.16

frail

0.17 – 0.32

hunched

0.33 – 0.48

skinny

0.49 – 0.64

wiry

0.65 – 0.80

broad

0.81 – 1.00

stocky

Wealth

Score Range

Label

0.00 – 0.19

poor

0.20 – 0.39

modest

0.40 – 0.59

well-kept

0.60 – 0.79

wealthy

0.80 – 1.00

decadent

Health

Score Range

Label

0.00 – 0.19

sickly

0.20 – 0.39

limping

0.40 – 0.59

weary

0.60 – 0.79

scarred

0.80 – 1.00

hale

Demeanor

Score Range

Label

0.00 – 0.19

timid

0.20 – 0.39

suspicious

0.40 – 0.59

resentful

0.60 – 0.79

alert

0.80 – 1.00

proud

Age

Score Range

Label

0.00 – 0.24

young

0.25 – 0.49

middle-aged

0.50 – 0.74

old

0.75 – 1.00

ancient

Facial Signal

Score Range

Label

0.00 – 0.14

understated

0.15 – 0.29

pronounced

0.30 – 0.44

exaggerated

0.45 – 0.59

asymmetrical

0.60 – 0.74

weathered

0.75 – 0.89

soft-featured

0.90 – 1.00

sharp-featured

Legitimacy

Score Range

Label

0.00 – 0.24

sanctioned

0.25 – 0.49

tolerated

0.50 – 0.74

questioned

0.75 – 1.00

illicit

Visibility

Score Range

Label

0.00 – 0.24

hidden

0.25 – 0.49

discrete

0.50 – 0.74

routine

0.75 – 1.00

conspicuous

Moral Load

Score Range

Label

0.00 – 0.24

neutral

0.25 – 0.49

burdened

0.50 – 0.74

conflicted

0.75 – 1.00

corrosive

Dependency

Score Range

Label

0.00 – 0.24

optional

0.25 – 0.49

useful

0.50 – 0.74

necessary

0.75 – 1.00

unavoidable

Risk Exposure

Score Range

Label

0.00 – 0.24

benign

0.25 – 0.49

straining

0.50 – 0.74

hazardous

0.75 – 1.00

eroding

Summary

Axis

Labels

Order Source

physique

6

axes.yaml

wealth

5

axes.yaml

health

5

axes.yaml

demeanor

5

axes.yaml

age

4

axes.yaml

facial_signal

7

axes.yaml

legitimacy

4

axes.yaml

visibility

4

axes.yaml

moral_load

4

axes.yaml

dependency

4

axes.yaml

risk_exposure

4

axes.yaml

Total: 11 axes, 52 configured labels.

Implementation Details

Source location

app/relabel_policy.py

Endpoint

POST /api/relabel

Data structures

AXIS_ORDER, AXIS_LABEL_ORDER, and RELABEL_POLICY: dict[str, list[tuple[float, float, str]]]

Matching algorithm

Inclusive range scan; first tuple satisfying min_score <= score <= max_score wins

Unknown axes

Passed through unchanged

Unmatched scores

Existing label preserved, because the lab payload schema requires a non-empty string label

Return value

New AxisPayload with relabelled axes and unchanged policy_hash, seed, and world_id