Ledger: AGENTIC_CONTENT_QUALITY_TODOS_2026-06-13.md § Phase 0. Date:
2026-06-13. Verifier read every file/line cited below in-session.
Method#
- Fabrication scan:
grep -nE 'Math\.(sin|cos|exp|random)'over each named impl file, then read each hit in context to separate real math (DPO sigmoid, cosine-LR schedule, non-secret id suffix) from fabricated training/score curves (aMath.sin(step·k)oscillation of a step/round/progress counter with no model behind it). - Caller scan:
grep -rEl "from '@nous/training'|from '@nous/llm'"across the repo, excludingnode_modules,dist,.claude/worktrees, and*.spec.ts. Then inspected each importer's exact import list.
Caller findings (who consumes these packages, non-test)#
| Importer | Package | Touches a named fake? |
|---|---|---|
libs/nous/inference-acceleration/src/index.ts |
@nous/training |
No — pulls StreamDiffusion / DeepCache / FlowMatching accel only |
libs/nous/diffusion-alignment/src/index.ts |
@nous/training |
Type-only: re-exports DiffusionDPOTrainingRequest, DiffusionCurriculumDPOTrainingRequest, FluxDPOTrainingRequest types (no runtime use) |
V2/services/nous-anti-cheat-classifiers/src/nous-anti-cheat-classifiers.ts |
@nous/training |
No — anti-cheat training-plan symbols only |
libs/kalika/research-agents/src/nous-integration.ts |
@nous/llm |
No — agent/tool/delegation types only; not the reasoning files |
Runtime callers of the 15 named fakes outside lib+spec: zero. The only
cross-package dependency is @nous/diffusion-alignment re-exporting three
request types (not values). → Fail-loud must preserve those type exports;
deletion would require rewiring diffusion-alignment + training/index.ts.
Triage table#
Decision key: fail-loud = keep the typed interface, replace every fabricated
metric/score with throw new NotConfiguredError(...); keep = honest today,
Phase 1 wires it. Deletion was considered and rejected (see Rationale).
libs/nous/training/src/ (training metric fakers)#
| File | Fabrication evidence (file:line) | Non-test caller | Decision |
|---|---|---|---|
rlaif.ts |
deriveRoundMetrics :361 Math.sin(round*0.41)*0.025; :756 …+Math.sin(phase)*0.04; :761 …+Math.cos(phase)*0.08 — per-round reward/agreement = closed form of round + config, no model |
none | fail-loud (0.2) |
reward-modeling.ts |
:773 perplexity: Math.exp(min(10, validationLoss)) over a fabricated validationLoss; deriveRewardMetrics synthesizes accuracy/loss from step |
none | fail-loud (0.2) |
best-of-n-sampling.ts |
:413 candidate score phase = round*0.57 + sampleIndex*0.23 + promptId.length*0.04; :414 Math.sin(phase)*0.07+Math.cos(phase*0.61)*0.05 — scores by id string length, never reads candidate text |
none | fail-loud (0.2); real best-of-N lives in the content stack (Phase 2.2), not here |
dpo-training.ts |
:407 Math.sin(step*0.17)*0.08; :464 Math.cos(step*0.11)*0.02 fake metric curve. (:203/206 Math.exp(±value) = real DPO sigmoid — keep; :390 cosine-LR — keep) |
none | fail-loud (0.2) |
ppo-training.ts |
:206 Math.sin(update*0.15)*0.04 fake metric |
none | fail-loud (0.2) |
constitutional-ai.ts |
:406 Math.sin(step*0.16)*0.08; :511 Math.cos(step*0.12)*0.02 fake metric (:398 cosine-LR — keep) |
none | fail-loud (0.2) |
diffusion-dpo-training.ts |
:579 Math.sin(step*0.13)*0.07; :676 Math.cos(step*0.09)*0.02 (:288/291 DPO sigmoid, :562 cosine-LR — keep) |
type re-export only | fail-loud (0.2); preserve DiffusionDPOTrainingRequest type |
diffusion-curriculum-dpo.ts |
:1425 baseLoss*Math.exp(-trainingProgress*2.6)+… fabricated loss curve (:851 cosine-LR — keep) |
type re-export only | fail-loud (0.2); preserve DiffusionCurriculumDPOTrainingRequest type |
flux-dpo-training.ts |
:1148 0.72*Math.exp(-progress*2.1)+…; :1173 0.58*Math.exp(-progress*2.5) fabricated metric curves (:583 cosine-LR — keep) |
type re-export only | fail-loud (0.2); preserve FluxDPOTrainingRequest type |
iterative-refinement.ts |
:392 Math.exp(-(iteration-1)*0.45) diminishing-returns + :394 Math.sin(phase)*0.01 fabricated refinement-gain curve |
none | fail-loud (0.2). NB: ledger 0.1 listed this under llm/ — it is in training/. The honest critique→revise refiner is Phase 2.3, built fresh in the content stack |
libs/nous/llm/src/ (reasoning result fakers / prompt builders)#
| File | Nature (evidence) | Non-test caller | Decision |
|---|---|---|---|
tree-of-thought.ts |
generateCandidates :421 token-substitutes the first 3 tokenized keywords into fixed templates ("Analyze how ${keyA} drives the core failure pattern…"). No provider, no await. Returns a "reasoning tree" it did not reason → stub |
none | fail-loud (0.3) — require a real provider; name reserved for Phase 1–2 |
graph-of-thought.ts |
generateCandidates :406 same keyword-template fabrication, no provider |
none | fail-loud (0.3) — require a real provider |
multi-step-reasoning.ts |
No await/provider/llm seam anywhere; synchronous template logic emits "reasoning steps" |
none | fail-loud (0.3) — require a real provider |
critique-prompts.ts |
Honest prompt builder — returns {system,user,rubric,…} prompt strings; fabricates nothing. Gap is only "never sent to a model" |
none | keep — Phase 1 wires the rubric into the real judge |
reflection-prompts.ts |
Prompt builder + a heuristic self-reflection path (:292 word-count gate emitting "completeness" findings). Prompt-build = keep; the heuristic-finding path that asserts a reflection it didn't reason → fail-loud that path |
none | keep-and-fix (0.3) — keep prompt build, fail-loud the heuristic "analysis" output |
Rationale: fail-loud over deletion#
- CLAUDE.md is explicit: "Honest fail-loud seams … are the opposite of a
stub and the correct way to represent a real-but-absent integration" and
"When unsure: fail loud, or ask." A typed method that
throwsnot_configuredis the sanctioned representation. - Lower blast radius / reversible. Deletion = remove 15 impl + 15 spec
files, strip 15
export *lines fromtraining/index.ts, and rewire the 3 type re-exports in@nous/diffusion-alignment. Fail-loud keeps the public type surface intact, so no out-of-scope cascade into the diffusion libs. - Names + interfaces are reserved. Ledger 0.3/2.2/5.3 reserve these names
and the
*Request/*Resultcontracts for the real Phase 1–2/5 implementations. Keeping the contract means the real trainer/searcher drops into a defined shape rather than reinventing it. - The honest core survives. Input validation and pure config arithmetic (prompt/batch/token counts, real DPO sigmoid, cosine-LR schedules) are real and stay; only the fabricated metric/score emission becomes a loud throw.
Deletion remains a valid alternative if the maintainer prefers a smaller surface — it is a one-commit revert of the fail-loud husks plus the index/diffusion rewire. Recorded here so the choice is explicit, not silent.
Execution plan (drives 0.2 / 0.3)#
- 0.2 — add
NotConfiguredErrorto@nous/training; in each training file above, make the metric-emitting runtime path throw it; delete fabricated forecast fields from "planning diagnostics"; rewrite each spec to assert the throw + the surviving honest config math. Adversarial grepMath\.(sin|cos|exp)intraining/src/must return only DPO-sigmoid / cosine-LR / real-loss hits afterward. - 0.3 —
NotConfiguredErrorin@nous/llm;tree-of-thought/graph-of-thought/multi-step-reasoningrequire a provider and throw without one;reflection-promptskeeps prompt-build, fail-louds the heuristic finding path;critique-promptskept as-is. Specs rewritten accordingly.
0.2 completion status (2026-06-13) — scope boundary, logged not silent#
Done + verified (the RLHF / preference / alignment training family this
ledger targets): rlaif, reward-modeling, dpo-training, ppo-training,
constitutional-ai, diffusion-dpo-training, diffusion-curriculum-dpo,
flux-dpo-training, honesty-training, harmlessness-training,
helpfulness-training, ipo-training, kto-training, orpo-training,
safety-training, self-play-training, rejection-sampling,
preference-learning — 18 modules failed-loud. Each: Math.sin|cos|exp
adversarial grep CLEAN, fabricated expected* quality forecasts removed (real
config counts kept), spec asserts NotConfiguredError + not_configured code.
Verified by the parent (not subagent self-report): **@nous/training tsc
clean
- 645/645 tests pass;
@nous/diffusion-alignmenttsc clean + 3/3 pass.** The three*Requesttypes re-exported by@nous/diffusion-alignmentare preserved.
Cascade caught by the parent's full-lib build (the 0.1 cross-package scan
missed intra-package consumers): preference-learning composed
reward-modeling and read its removed forecasts; preference-aligned-inference
spec minted a FLUX artifact by running the now-failing trainer (rebuilt as a
typed artifact literal — a boundary test-double; impl unchanged);
diffusion-alignment spec asserted a removed forecast (repointed to a real
diagnostic).
NOT done — out of this ledger's scope (the dir-wide grep is over-broad vs
0.2's named target list). The identical Math.exp(-progress·k) fake-loss /
oscillation pattern also lives in the image-diffusion-distillation / base-SFT
training stack: supervised-fine-tuning, consistency-model-training,
lcm-lora-training, flow-matching-lcm-lora, scot-training (+ the ~20 PEFT
modules that compose instruction-tuning / supervised-fine-tuning). These are
a different domain (image/SFT training, the 2026-06-12 SOTA integration ledger),
and failing them loud cascades through the whole PEFT stack — explicitly not
the content-quality concern Phase 0 addresses. Tracked here so the remaining
grep hits are explained, not silently dropped. best-of-n-sampling and
iterative-refinement are Phase 0.3.
Legitimate Math.* that correctly remains in training/src: real DPO sigmoid
in logsigmoid losses, cosine-LR schedules, lognormal sigma noise schedules
(consistency-training-data-pipeline), cosine²/temporal-shape weighting
(deepcache), and Math.random().toString(36) non-secret id suffixes.
0.3 completion status (2026-06-13)#
Done + verified. Added NotConfiguredError to @nous/llm. The reasoning
engines that token-substituted templates with no model now require a real LLM
provider and throw without one: tree-of-thought.buildTree,
graph-of-thought.buildGraph, multi-step-reasoning.reason (all fabrication
helpers deleted; exported types/constructor/getStats preserved for the real
Phase 1–2 impl). critique-prompts and reflection-prompts keep their honest
prompt builders and model-output parsers (buildPrompt,
parseCritique, parseReflection) but fail-loud the heuristic finding paths
(critiqueResponse, analyzeDraft) that invented severity/scoreImpact
judgments from word-counts/regex with no model. In @nous/training,
best-of-n-sampling (scored candidates by id string length) and
iterative-refinement (exp/sin gain curve) fail loud like the rlaif family.
Verified by the parent: @nous/llm tsc clean + 423/423 tests pass;
@nous/training tsc clean + 647/647 pass. The real best-of-N / self-refine
for content are Phases 2.2 / 2.3 (built fresh in the content stack), not these
@nous/* husks.
0.4 completion status (2026-06-13)#
Done + verified. The four libs/yemaya/agents/src/quality-assurance/
scorers each exported an LLM-judge provider interface that was never wired
(declaration-only — the illusion that LLM judging exists) and fell back to a
fabricated quality default when the real path was absent:
narrative-quality-benchmarkaggregated caller-supplieddimensionScoresbut folded a fabricated?? 50for every missing dimension into the weighted "quality" (7 sites, incl. the subject↔reference comparison the subagent additionally found). Now aggregates only over present dimensions with renormalized weights, exposesscoredDimensions/dimensionCoverage, and throws honestly when zero dimensions are scored (no external consumers).dialogue-naturalness-scorer.parseLLMScoreResponsefabricated 50/0 when the real LLM response was unparseable; now returns{ reason }and leaves the score undefined so the rule-based score is left untouched.evaluateWithLLMalready fails loud (throws) without a handler.ending-satisfaction-predictor.predictSatisfactionfolded 0.5 pacing/conformity/surprise intooverallScorewhen no ending was set; now fails loud (guard) before any analysis (genuine extra violation the subagent found beyond the dead interface).mystery-fairness-validator: adversarial scan confirmed the remaining50s are legitimate per-subgenre config thresholds and the other defaults are domain-constant lookups / vacuous-truth divide-by-zero guards — no fabricated quality default. Only the dead interface was annotated.
All three dead provider interfaces are kept and annotated
Reserved for Phase 1 (content-quality-judge) wiring — NOT yet connected.
Verified by the parent: yemaya/agents tsc clean; 222/222 quality-assurance
tests pass.
Phase 0 net result#
The faked ML/reasoning/judge stack no longer emits a single fabricated metric,
score, reasoning trace, or quality judgment when its real backend is absent — it
fails loud (NotConfiguredError / throw) or reports honest absence
({ scored:false } / undefined + reason). ~30 modules across
@nous/training, @nous/llm, and yemaya/agents remediated and individually
test-verified. The names + typed interfaces are preserved for the real Phase 1–2
implementations. (Out of scope, logged above: the image-diffusion/SFT
distillation training simulators in @nous/training share the pattern but
belong to the SOTA ledger.)