RESEARCH LOG - SyberLabs/RISE GitHub Wiki

Affect research log

Date: 2026-09-29

This log is the record of what was tried, refused, or left unrun. It is not a claim that the remaining priors are psychological facts.

What the first version actually does

The runnable text models are lexical-vad-v1 and contextual-window-v1. The first averages a compact in-repo lexicon and ignores negation. The second applies a three-token negation window and an intensifier to the next lexicon word, then a linear map. Both are deterministic and local. The benchmark report is docs/affect/BENCHMARK.md, regenerated by npm run affect:benchmark.

On the constructed probe "I am not happy.", the baseline stays positive and the window encoder goes negative. That is the evidence the window is doing work. It is not evidence that the magnitudes match any human rater.

Directional checks that held on the archive sample: Paradise Lost's opening woe is negative in valence; Whitman's "I celebrate myself" is positive; the Dostoevsky sentence scores higher tension than the Vitruvius sentence about order. Irony was not solved. Austen and Dickinson are in the report so a person can see the outputs. Dickinson's "kindly" sits next to "Death". The encoder has no figure of speech.

Runs on 2026-09-29

No hosted API credential was in the environment. The three missing runs were executed locally and stored. They are not imported by the player.

PERT-EmoPair (edsi-umd/PERT-EmoPair, roberta-large, prompted, CPU). Mean forward about 143 ms. Valence lands on the EmoBank 1–5 scale and orders the sample: Whitman 3.68, Paradise Lost 2.37, the negation probe 1.76. Mapped with (raw - 3) / 2. Arousal and dominance are not on that scale. Calibration sentences put a still room near arousal −0.47 and fury near 0.76, so arousal is shifted by (raw + 0.6) / 1.6. Dominance already sat inside about −0.6 to 0.5 and is only clamped. Raw scores are in docs/affect/emopair-scores.json.

Reward-EmoPair (edsi-umd/Reward-EmoPair, CPU). Mean forward about 312 ms. The 4.2 GB checkpoint includes optimizer state and did load. Valence is a compressed 1–5 regression (Whitman 3.63, Paradise Lost 2.46). Arousal and dominance are mapped through the checkpoint's published norm_params.json. Crime and Faustus score high arousal; Vitruvius scores low. The same file holds both models.

Local teacher. Qwen/Qwen2.5-0.5B-Instruct emitted JSON for every passage and was not usable: it rated Whitman's celebration at valence −0.9 and several passages outside the requested range. Qwen/Qwen2.5-1.5B-Instruct replaced it. That run is docs/affect/teacher-scores.json, served by scripts/affect/teacher-server.mjs and called through AFFECT_TEACHER_URL. It separates Whitman (0.99) from Paradise Lost (−0.98) and marks the negation probe −1. It also rates Dickinson's death poem at valence 0.99, so it is a weak judge, not a norm. The hook still records unavailable when the URL is unset.

MiniLM probe. Frozen Xenova/all-MiniLM-L6-v2 (q8) embeddings, linear head, ridge λ = 0.01 chosen by leave-one-out against mapped PERT targets. Leave-one-out mean absolute error: valence 0.136, arousal 0.149, dominance 0.276. Correlation of those predictions with the targets: valence −0.19, arousal 0.55, dominance 0.37. The valence probe does not generalize. Whitman's leave-one-out valence is −0.04 against a target of 0.34, and the negation probe flips from −0.62 to 0.09. The benchmark column is the leave-one-out prediction. Weights and errors are in docs/affect/minilm-probe.json. This is not a distillation from human preferences.

scripts/affect/fit-readout.mjs still exits with status 2 until 24 judgments are marked annotatorKind: "human". The window encoder was not refit.

Reproduce:

python3 scripts/affect/score-emopair.py
node scripts/affect/distill-minilm.mjs
python3 scripts/affect/score-teacher.py
node scripts/affect/teacher-server.mjs
AFFECT_TEACHER_URL=http://127.0.0.1:8765 npm run affect:benchmark

Rejected

Generative model as an online judge of quality. A hosted model asked whether an experience is good would be opaque and aimed at the wrong question. The teacher above returns axes. It is not a grade, and it is not consulted by the player.

Published numbers as if they were RISE numbers. The EmoPair columns are this corpus scored on this machine. They are not the paper's correlations copied onto Meditations.

Invented labels for the window readout. Fitting contextual-window-v1 to scores written in order to have labels was refused. The MiniLM probe uses PERT outputs as targets and reports leave-one-out error, including the failure on valence.

Hue to sadness. Blue's swatch is a light blue. The adapter records colorimetric warmth and leaves valence unset. White has no stable hue, so warmth is omitted. That is a scale choice about color temperature, stated as a measurement of the swatch, not a law about mood.

Emotion labels as the state. Cue counts can fill an auxiliary distribution. They do not replace the continuous axes, and they are not a trained multilabel head. The loss combination in the brief (regression, ranking, multilabel, distillation, temporal consistency) was not used. There is no teacher tensor and no preference set to weight those terms. Using all of them on synthetic targets would hide which term was doing the work.

One scalar value. Fused alignment can look acceptable while pace is not. The 520 WPM case is the demonstration: text, a still image, and quiet audio can sit at low arousal while pace is near the top of the logistic. The result keeps per-modality alignment so the pace can fail on its own. Conflict is zero when the intent marks contrast as deliberate.

WebGPU as a requirement. The readout is small enough that the JavaScript core is the runtime. On this machine a benchmark encoded the archive passages in about 0.045 ms each in JavaScript. The exported Gemm, run through onnxruntime-web on WASM, matched the JavaScript matrix product to within 3e-8 and took about 0.36 ms per call, slower than the JavaScript path. WebGPU was not requested. The snapshot is docs/affect/runtime-bench.json. Prefer the JavaScript core until a larger encoder exists.

Importing the layer from the player. Manual configuration must keep working with no model. The module is reached by an explicit import and by RISE_AFFECT. It is not on the first-load path.

Known failures of the window

Negation is not syntax. "Not very happy" works only because the intensifier does not consume the negation window; a longer clause will not. "But" counts as contrast, including Dickinson's "held but just ourselves", which is not contrast. "Fantastic" in Dostoevsky was left out of the lexicon because the word is not stably positive. Irony, understatement, and free indirect style are unmodeled. Low lexicon coverage is a caveat, not a neutral score.

The lexicon itself is an authoring prior for this repository. It is not the NRC VAD lexicon. Those tables were not copied.

Affect program

rise.affect-program.v1 names phrases from the chunker and may attach an experience state to some of them. A phrase it skips stays absent. admitAffectProgram re-chunks the text and refuses a drifted cut, a hash mismatch, a measured source, or a value outside range. It does not clamp. saveAffectProgram sets authority to user and leaves slot sources as written. npm run affect:export-brief writes a brief and a prompt generated from the same axes and refusal codes. The player does not import the program.

modulatePlateColorsAt and modulateFlameColorsAt apply one span to the fine color parameters those engines already read. Warmth turns hue. Arousal scales saturation or vibrancy around the authored value. Valence is not a hue. The engines do not call the modulator, so a reading with no program is unchanged.

The Emotions room places corpus passages, attractor swatches, and Living Flame scenes on one Thomas attractor. Position uses valence and arousal when both exist. Hue uses warmth. The chamber still does not import the layer.

modulateEnergyAt applies the same span to attractor and night-streak speed and to Living Flame energy. The signal is motionEnergy, so arousal is not counted twice. 0.5 leaves the authored value. Harmonograph and Klee already read arousal inside the conductor, and plate bloom, sparkle, chroma, and grain are not one energy number, so those engines are not channels.

What would change the readout

Human pairwise judgments, stored with recordJudgment and never edited, fitted with Bradley–Terry per question. The local teacher and the EmoPair scores are evidence beside the window encoder, not a replacement for those judgments. A MiniLM-class probe on 24 passages did not carry PERT valence out of sample. A larger labeled set would be required before that probe could replace the window.


Published from docs/affect/RESEARCH-LOG.md. Edits made here are overwritten on the next push to main.