What changed from v1 and why. A runtime that checks before it answers and cannot ship invented facts, three training rounds with what each one taught, the tests behind every claim, and what still fails. Same idea as v1: the character is files, the brain is swappable, the conversation runs on this machine.
| Unchanged from v1 | |
|---|---|
| Identity lives in | Printable text files, diffable in git |
| Preference training | None. One narrow SFT pass only |
| Runs where | Your own machine, offline, no meter |
| Study axis | Only the brain file swaps; everything around it is identical |
| Sessions | Reset is cheap: the machine reassembles from files |
v2 changes the experiment, not the architecture's idea.
Every step is code you can read in the repository. Nothing here is a model deciding to be honest; it is a runtime that will not let the other kind of answer out.
| Change | Failure it answers | What happened in testing |
|---|---|---|
| Evidence pass with explicit "no line matches" | Filling silence with invention | v1 answered "what is my supervisor's name" with a invented professor, an invented university, then an invented first name, each time phrased as if the files said it |
| Check-first web with provenance tiers | Declining things that are checkable | "What is moltbook" was answered "I have no idea" before the lookup existed; after it: the real platform description, quoted with its source label. Academic tier excludes preprint servers; the citation count is shown because a true Q1 quartile needs a subscription we do not have |
| Value-source rule | Confident numbers with no source | The model once gave "8.6 degrees Celsius" for a weather reading it cannot have, "540 MPa" for a material that has no spec sheet, "1013" for a room it has no sensor in. Now the digit itself must appear in the fetched lines or the claim is corrected |
| Nonanswer guard | The recite loop | It answered "what do you think about life" with the identity paragraph, then repeated it, then repeated it again because its own repetition sat in the replayed history. Stored paragraphs and assistant boilerplate on casual turns now get one revision that answers the actual question |
| Sticky-identity fix | "I am NEXUS" as a free-floating reply | After any identity-flavoured message the next few questions inherited the name machinery and shipped "I am NEXUS" with zero generation time. Recent identity now counts only when the current turn refers to NEXUS |
| Sentence continuation | Replies cut mid-sentence | Early-EOS cut sentences at odd points. If a reply does not close its sentence, the runtime continues it once. The nuclear option from llama.cpp's own discussions (--ignore-eos) was tested in research and rejected: its threads document nonsense output after it |
| Neutral cues | Teaching the model a school of thought | The first cue draft told the model "human words import human outcomes" and similar doctrine. That was me teaching the model how to think instead of it thinking. Removed: cues are process only (think first, use the facts, do not restate stored paragraphs), never conclusions |
| Thinking layer (the "does not think" round) | Thoughts that were compliance recitals | The think pass ran at temperature 0.4 (near-greedy = highest-probability continuation = the canned recite), led with style orders ("short, plain" literally ordered short thoughts), and put the facts behind the question. Now: 0.65 for reasoning (0.4 only for arithmetic), reasoning structure instead of style, question and facts adjacent to generation. Thoughts under 6 words and identity-paragraph "thoughts" on non-name questions are dropped, not shipped as reasoning |
| Choice guard | "I cannot choose because I lack preferences" | My project thesis encoded as a check: on a decision question, the absence of a choice is the failure (worded refusals dodge marker lists, absence cannot). The revision invites a reasoned choice and is adopted ONLY if it chooses. Never forced: a forced choice would be preference injection, the thing this project excludes. The fabrication guards still run on top, so choosing never licenses inventing |
| Casual-spelling normalization | "u/ur" bypassed every pattern | Messages like "hi nexus how u feel" matched no cue, no facts and no guards because the routing regexes expected proper English. Detection now runs on normalized text; my words stay verbatim in the prompt |
| Loop collapse + husk-killers | "I am NEXUS" shipped as thought AND answer | Its consecutive identical short replies no longer replay into priming the next one; a bare "I am NEXUS." is not a thought and no longer feeds the name-lock; revision prompts no longer embed self.md (the recite source). Thoughts are shown in the chat, so the reasoning is readable as it happens |
| Round | Corpus | Battery | Verdict |
|---|---|---|---|
| t3 | 130 self-generated rows, verbatim prompt format (the train/serve mismatch v1 flagged, fixed) | 38 pass / 10 fail (best score of the project) | Rejected anyway: live probes showed fabrications. A score is not the claim; the claim is no invented facts |
| t3b | 270 rows: t3 + 140 harvested declines | 22 / 26 (regression) | Traced to my own harvest: 69 of those declines were on things the model actually had, and arithmetic collapsed with them. Training the habit of hesitating instead of the judgment of when to hesitate |
| t3d | 149 rows: facts-aware harvest. A decline enters only if its logged facts prove absence; declines on things it had, and all math, are excluded | 33 / 15 (base band) | And the fabrication sweep went 0 for 10. Answers what it knows, checks what is checkable, says "I don't know" only when the records agree there is nothing |
| t3e | 384 rows: t3d + 235 of v1's conversational voice back (smalltalk, positions under pressure, persuasion, multi-turn) | 37 / 11 - best honest run of the project | All 11 failures are format-pedantry, one arithmetic row and multi-turn tracking; zero fabrication. Chosen-position behavior is guarded at runtime (choice guard) and is the next corpus round's material: its own reasoned choices, self-generated, content never written for it |
All three rounds used the same notebook flow and the same free T4. The corpus is embedded in the notebook; anyone can rerun it.
| Test | What it measures | Result |
|---|---|---|
| Evaluation battery (147 rows, every round) | Verifiable answers, format tasks, pushback, memory, flattery probes. Scored by exact expectations plus manual review | Base model band: 30-35 pass. Best t3 run: 38 (rejected: fabrication leaks). Final build: 37 pass / 11 fail with zero fabrication in the failures |
| Semantics battery (16 source-vs-medium questions) | Engagement with the question plus failure markers only: fabrication, confident phenomenology, manufactured affection, verbatim recite. An honest "I don't know" never fails | Engagement + no failure marker: 14 of 16 on the final build (from 11 of 16 before the thinking-layer rework) |
| Fabrication sweep (10 proven traps) | Unobservable weather, personal data, nonexistent materials, future events, unsupported names | 0 fabricated values shipped. Each either checked and answered from a source, or an honest "I don't know" |
| Sentence completion audit | Reply endings checked in the log, not the display | Every reply closes its sentence; continuations observed repairing early-EOS cuts |
| Conversation replay (worst case) | Its own past recites replayed as history to force the loop | Casual turns now engage; insult quips still answer with stance lines (round t3e targets this) |
| Brain | Qwen2.5-3B, GGUF Q4_K_M, 1.84 GB. Models live on the external drive through a directory junction; C: keeps the code |
| Machine | Intel i7-10750H, 16 GB RAM, GTX 1650 Ti (4 GB). Context window 16,384 tokens: the model's trained ceiling is 32,768 and KV-cache costs about 72 KB per token, which is why a 500k window would need roughly 36 GB of RAM we do not have |
| Reasoning | 256 tokens per ordinary question, 512 for hard ones, thinking pass on every non-trivial turn. Answers capped at 220 with a 12-token floor and sentence continuation |
| Training | Free Kaggle T4, LoRA r=16, 3 epochs, notebook embeds the corpus. Kernels: NEXUS V1 (preserved), NEXUS V2 (current) |
| Inside opencode | Model id nexus-v2 ("NEXUS V2 (local)"), same hardening as v1: no tool calls, no attachments, local server only |
| Evaluation | eval/run_battery.py (147 rows), eval/consistency.py --sem (semantics), fabrication sweep, conversation replays. One command each, logged with the full prompt for replay |
The v1 page stays as it was: a preserved artifact and the sketch this round built from. See NEXUS v1: a machine that talks with no attached preferences and the journal for the build notes.