Skip to content

DEM-PRODUCER-HTF (reactor): real higher-timeframe bias; structure passes its 0.40 cap - #91

Merged
Gio2050 merged 4 commits into
mainfrom
dem/htf-reactor
Aug 26, 2026
Merged

Gio2050 merged 4 commits into
mainfrom
dem/htf-reactor

Conversation

@Gio2050

@Gio2050 Gio2050 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Wave 3 of 4 — DEM-PRODUCER-HTF, step 3 of 3. Merge after afi-core dem/htf-core and afi-config dem/htf-config.

The capability the technical lane lacked

The adapter now reads the registered composition value and fetches the signal window plus both higher-timeframe windows concurrently (Promise.all — this lane is the pipeline's entry node, so serial round-trips would delay every downstream wave and eat into TradingView's 3-second cancel). Each HTF window runs the same EMA20/EMA50 trend law; a window below the 50-candle floor emits no sub-block — a declared producer absence, never a guessed bias. A malformed registered value refuses rather than guessing.

The gate's headline: structure passes its former 0.40 cap

golden weekly / daily structure analystScore.direction
BTC (cpj-blofin-perp-long.*, tv-long.*) long / long 0.4 → 0.8 neutral → long
ETH (cpj-coinbase-spot-sell.*, tv-short.*) short / long 0.4 neutral → unknown
SOL (*-neutral.*) neutral / neutral unmoved neutral

The aligned-HTF +0.4 structure term fires for the first time in this system's history: structure reaches 0.8, beyond its former 0.40 cap, and spans {0.15, 0.4, 0.8} over the corpus. The ETH pair exercises a genuine higher-timeframe conflict, so the "unknown" verdict — the branch DIR-GOV reserved — is now reachable, resolved, and pinned by a golden.

DIR-GOV D-DIR-3 — the dedicated negative test the gate requires

test/pipeline/htfProducer.test.ts:

  1. varying facts.direction over long/short/neutral leaves the entire technical payload byte-identical;
  2. the bias facts contradict the submitted side where the market does (submitted SHORT on a symbol whose HTF windows trend up, and vice versa);
  3. a comment-stripped source scan proves no producer or projection file reads the submitted direction — with the scan proven to bite on a real read, proven not to fire on a comment naming the rule, and the lawful record-stamping reader shown to be outside the scanned set.

Also proven: the registered timeframes actually drive the fetches; concurrency (in-flight peak of 3); kernel-floor absence; malformed-config refusal.

Test-only fixture change, stated plainly

The deterministic test feed gains a per-symbol drift applied only to timeframes ≥ 1d, so the corpus exercises aligned, conflicting and neutral HTF. Sub-daily timeframes are byte-untouched — every golden's own-timeframe series, indicators and pattern facts are unchanged, and the differ confirms it.

785/785 green; typecheck green; all four compiled-build proofs green against a real replica set; every moved golden path itemized with an explicit byte-EQUAL list.

🤖 Generated with Claude Code

Gio2050 and others added 4 commits August 25, 2026 17:48
…act; goldens regenerated once, itemized

DEM-GOV §9 DEM-PRODUCER-PLAN (owner-authorized 2026-08-25; afi-governance
#55; §9 determinations D-2/D-4/D-5 in #56). Merge AFTER afi-core dem/plan-core
and afi-config dem/plan-config.

Source:
- uss/cpjMapper.ts: the submitted plan survives as uss.plan (afi.trade-plan.v1,
  decimal strings, validated against the governed contract) or is refused at
  ingest (typed error → 422 trade_plan_invalid). TV/MarkitTick untouched.
- enrichment/tradePlanVerification.ts (NEW): the D-DEM-5(6) law — every
  submitted level within [L − W, H + W] of the fetched window; plan geometry
  from prices only (D-DIR-3 by construction); R:R to the nearest target,
  4 dp; refusal = TradePlanVerificationError (NodeConfigurationError).
- providers/adapters/technicalLocalAdapter.ts: the producer — verifies the
  plan against ITS fetched candles and emits technical.plan (declared
  absences: no plan → no block; no stop/target → no R:R).
- pipeline/nodes/laneView.ts: viewTechnical projects plan verbatim.
- server.ts: 422 trade_plan_unverifiable (unwrapping NodeExecutionError.cause),
  422 trade_plan_invalid; both persisted:false.
- types/TradePlan.ts (NEW), types/UssLenses.ts, uss/ussValidator.ts: types.

Registries/pins: the three fixture trees mirror afi-config (mapping 1.1.0,
config, three implementationVersion moves, registration hash 5cb9b7a4…);
registryLoader/officialArtifactPins pins rotated (pluginSetHash 36f911f4…).

Goldens: the two plan-bearing CPJ fixtures re-authored inside the demo
envelope (old levels were unverifiable by the law this slot lands); 12
goldens regenerated ONCE; every moved path itemized in INTENTIONAL_DIFFS.md
(risk 0.9 → {0.5 via the provider's rr 1.4286 | 0.2 via the declared floor};
executionSummaryHash flips executed → degraded on the two goldens where the
floor is the first fired default; identity-hash class on all 12).
test/oracle/support/goldenDiff.mjs (NEW): the committed per-path differ.

Tests: verification KATs (band, geometry, absences, error class), carrier
(decimal strings, refusals), producer (role split, D-DIR-3 negative test,
refusal, kernel floor, envelope-covers-fixtures), error-table rows for both
422s (no record), seam suites re-oracled to the composition reference with
the mapping resolved by mappingRef from the fixture registry, golden
scorerInput captured at the rubric call. 756/756; typecheck; compiled-build
proofs (unavailable 503; Mongo persistence 10/10; oracle equivalence 7/7;
SIGTERM) green locally.

No scoring-law value moves. Sealed records untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n law

An adversarial review of the branch (7 lenses, findings independently
verified) found five real defects in the D-DEM-5(6) law. All five fixed here;
no golden byte moves (every fix is refusal-side or message-side).

- MAJOR: an entry RANGE was verified only at its conservative bound, so a
  range containing (or on the wrong side of) its own stop was ACCEPTED and an
  R:R emitted from one end. The stop must now clear the FAR bound as well:
  long -> stop < entryLow, short -> stop > entryHigh. Three refusal KATs (long
  straddle, short straddle, far bound EQUALS the stop) + the accept-side edge.
- MINOR: the inclusive band edge was false on non-integer windows (binary
  float: 1.1 - 0.2 = 0.9000000000000001 refused an entry of exactly "0.9").
  Relative tolerance (1e-12) at both edges + bounded-precision numbers in the
  refusal message; a non-integer-window KAT pins both edges.
- MINOR: a non-array takeProfits (or a non-object levels) threw a bare
  TypeError, escaping the 422 unwrap. Both refuse properly now, with KATs.
- MINOR: "half-up to 4 decimals" was not what Math.round(v*1e4)/1e4 does at
  binary ties. The law is documented as what it is (deterministic binary
  quantisation) and the unfavourable tie (0.00015 -> 0.0001) is pinned.
- MINOR: missing edge KATs added: empty takeProfits array (no-target case),
  degenerate entry range (min === max), exotic numeric strings, an
  overflow-to-Infinity decimal string, malformed candles; the hedged
  short-geometry regex is tightened to its exact message.

756 -> 764 tests, all green; typecheck green; goldens byte-unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DEM-GOV §9 DEM-PRODUCER-CANDLE (owner-authorized 2026-08-25; afi-governance
#55; determinations D-2/D-3 in #56) — the act D5-GOV D-D5-1 reserved. Merge
AFTER afi-core dem/candle-core and afi-config dem/candle-config, which merge
after the whole PLAN wave.

Source:
- enrichment/candleStructure.ts (NEW): the two producers as pure functions over
  the window the lane already fetches. brokeEmaWithBody = the latest bar's body
  closed on the counter-trend side of EMA20 (bullish: close < ema20; bearish:
  close > ema20; range: the body crossed EMA20 this bar) — colour-free, one law
  per side. Heikin-Ashi flat-back = the recurrence over the whole window, seed
  (o+c)/2, epsilon 0 (bullish: an up HA bar with low >= haOpen; bearish: a down
  HA bar with high <= haOpen), confirmed iff its side agrees with the lane's own
  EMA trend law. Both read the lane's computed trendBias, never a submitted
  direction (DIR-GOV D-DIR-3).
- enrichment/technicalIndicators.ts: emits the three facts with the bundle.
- pipeline/nodes/laneView.ts: viewTechnical projects them; the imported stub
  constant and its pin are DELETED.
- types/UssLenses.ts: lens payload widened.

Registries/pins: three fixture trees mirror afi-config (mapping 1.2.0, config,
three implementationVersion moves); the two pin tests rotated.

Goldens (regenerated ONCE, itemized in INTENTIONAL_DIFFS.md): the SOL 15m seed
(tv-neutral) computes brokeEmaWithBody TRUE, so structure 0.4 -> 0.15 and risk
0.2 -> 0.0 there; the other ten are unmoved in scored values. THE GATE IS MET:
structure is non-constant over the fixture corpus ({0.4, 0.15}) and so is risk
({0.5, 0.2, 0.0}). haFlatBackConfirmed is false on all twelve BY CONSTRUCTION
(every demo seed is a range regime) — recorded honestly; its branches are proven
by KATs, not by the corpus.

Tests: candleStructure.test.ts (12 KATs: every brokeEma branch incl. the
green-body-below and straddle cases, both flat-back sides, the exact-equality
no-wick edge, the doji, seed-independence at the 50-bar floor, both producers
together); fiveLaneAdapters' stub assertions rewritten to computed-fact
assertions (and that the stub export is GONE); guardrail fixture views carry
the required facts; the seam test's bare-technical probe updated (the candle
binds are required, so a bare namespace now refuses).

764/764; typecheck green. No scoring-law value moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ses its 0.40 cap

DEM-GOV §9 DEM-PRODUCER-HTF (owner-authorized 2026-08-25; afi-governance #55;
determinations D-1/D-2 in #56) — the mission DIR-GOV D-DIR-3's scope-guard
reserved. Merge AFTER afi-core dem/htf-core and afi-config dem/htf-config.

Source:
- providers/adapters/technicalLocalAdapter.ts: reads the REGISTERED composition
  value (nodeOverrides.technical.config.htf, boot-validated against the closed
  paramsSchema) and fetches the signal window + both HTF windows CONCURRENTLY
  (Promise.all — this lane is the entry node, so serial round-trips delay every
  downstream wave). Each HTF window runs the SAME EMA trend law; a window below
  the 50-candle floor emits no sub-block (declared absence). A malformed
  registered value refuses (NodeConfigurationError), never guesses.
- pipeline/nodes/laneView.ts + types/UssLenses.ts: technical.htf projected.
- test/support/deterministicPriceFeedAdapter.ts (TEST ONLY): a deterministic
  per-symbol drift for timeframes >= 1d, so the fixture corpus exercises
  aligned, conflicting and neutral HTF. Sub-daily timeframes byte-untouched.

Goldens (regenerated ONCE, itemized in INTENTIONAL_DIFFS.md): THE GATE IS MET —
the aligned-HTF +0.4 structure term fires for the first time, so structure
reaches 0.8 on the four BTC goldens, BEYOND its former 0.40 cap, and spans
{0.15, 0.4, 0.8} over the corpus. The ETH pair exercises a real higher-timeframe
CONFLICT (weekly bearish, daily bullish): the analyst's verdict is "unknown" —
the branch DIR-GOV reserved, now reachable, resolved in afi-core, and pinned by
a golden. inputHash/manifestHash byte-equal everywhere.

Tests: htfProducer.test.ts — the producer (registered timeframes actually drive
the fetches; concurrency proven by an in-flight peak of 3; kernel-floor absence;
malformed-config refusal) and THE DIR-GOV D-DIR-3 NEGATIVE TEST the gate
requires: varying facts.direction over long/short/neutral leaves the entire
technical payload byte-identical, the bias facts contradict the submitted side
where the market does, and a comment-stripped source scan proves no producer or
projection file reads the submitted direction (with the scan proven to bite, and
the lawful record-stamping reader shown to be outside the scanned set).

785/785; typecheck green; all four compiled-build proofs green against a real
replica set (503-unavailable, 10 persistence, 7 oracle-equivalence, SIGTERM).
No scoring-law value moves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kilo-code-bot

kilo-code-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

Kilo Code Review could not run — your account is out of credits.

Add credits or switch to a free model to enable reviews on this change.

@Gio2050
Gio2050 merged commit 377f7e5 into main Aug 26, 2026
3 of 5 checks passed
@Gio2050
Gio2050 deleted the dem/htf-reactor branch August 26, 2026 04:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant