FORGE (Feed-Adaptive Oracle & Runtime Generator) is Echelon's automatic Theatre Factory — the feed-native supply side that turns any structured event stream into prediction market proposals without human curation. It classifies feeds across five grammar dimensions (cadence, distribution, noise, density, thresholds), selects matching Theatre templates via 13 rule-based matching rules, exports Brier-scored RLMF training certificates, and generates signed ProposalReceipts that prove a specific envelope was produced from a specific input under a specific policy and code version. Receipts are independently verifiable via the forge-verify CLI. FORGE is not one of many possible Theatre Factory inputs — it is the specific component that makes the factory automatic, covering domains where statistical structure in live data is the only reliable signal. The Uniswap factory for prediction surfaces.
- classify — 5-dimension feed grammar classifier. Orchestrates all five classifiers and returns a
FeedProfilewith cadence, distribution, noise, density, and threshold classifications. (src/classifier/feed-grammar.js:34) - classifyCadence — Cadence classifier:
event_driven/seconds/minutes/hours/multi_cadence/irregular. Uses median inter-event delta, jitter coefficient, and bimodal histogram detection. (src/classifier/cadence.js:129) - classifyDistribution — Distribution classifier:
bounded_numeric/unbounded_numeric/composite/categorical. Uses bounds, max-growth coefficient, and multimodal histogram analysis. (src/classifier/distribution.js:127) - classifyNoise — Noise classifier:
spike_driven/steady/mixed/irregular. Uses spike detection, lag-1 autocorrelation, and linear trend t-stat. (src/classifier/noise.js:255) - classifyDensity — Density classifier:
single_point/single_global_instrument/sparse_network/dense_network/multi_tier. Uses sensor count, coverage metadata, coordinate events, GeoJSON feature count, and multi-tier detection. (src/classifier/density.js:140) - classifyThresholds — Threshold classifier:
regulatory/physical/statistical/none. Matches histogram breakpoints against EPA AQI, NOAA Kp, and NOAA R regulatory tables. (src/classifier/thresholds.js:199) - selectTemplates — Rule-based Theatre template selector. Evaluates all 13 rules against a
FeedProfileand returns all fired proposals with confidence scores. Uses greedy matching for duplicate template resolution. (src/selector/template-selector.js:130) - evaluateRule — Evaluates a single condition rule against a
FeedProfileusing dot-path field access and six comparison operators (equals, in, gt, lt, gte, lte). (src/selector/template-selector.js:70) - RULES — 13 template selection rules covering three backing specs: 5 TREMOR (seismic), 5 CORONA (space weather), 3 BREATH (air quality). (
src/selector/rules.js:35) - alignFeeds — Temporal alignment of two event streams within a sliding window. For each event in stream A, finds the nearest event in stream B within ±windowMs. Returns matched pairs only. (
src/composer/compose.js:28) - detectCausalOrdering — Mean timestamp offset analysis to detect leading/lagging relationship between two aligned feed streams. Returns
leader('A'|'B'|'concurrent') andlag_ms. (src/composer/compose.js:63) - proposeComposedTheatre — Three-rule composition engine. Evaluates two classified feeds + their temporal relationship and proposes the Theatre that neither feed would generate alone. Rules:
threshold_with_arrival_predictor(bounded + arrival predictor → threshold_gate),co_bounded_divergence(two bounded + concurrent → divergence),cascade_amplifier(spike_driven + bounded → cascade). Returns null if no rule fires. (src/composer/compose.js:118) - emitEnvelope — Versioned ProposalEnvelope emitter. Annotates proposals with deterministic
proposal_id(SHA-256 dedup key),brier_type, and per-proposalusefulness_score(null when economic filter not invoked). Produces the IR contract consumed by Echelon's admission gate. (src/ir/emit.js:71) - computeUsefulness — Scores a Theatre proposal across four dimensions:
population_impact,regulatory_relevance,predictability,actionability. Returns a 0–1 composite usefulness score. (src/filter/usefulness.js:113) - buildBundle — Evidence bundle constructor: computes quality score, doubt price (uncertainty), settlement assessment, and assembles the full bundle object from a raw feed event. (
src/processor/bundles.js:49) - getTrustTier / canSettle / validateSettlement — T0–T3 oracle trust enforcement.
canSettlereturns true only for T0/T1. PurpleAir (T3) enforced as non-settling source. (src/trust/oracle-trust.js:61) - exportCertificate — RLMF training certificate export with Brier score, position history, and calibration bucket. Supports binary and multi-class scoring. (
src/rlmf/certificates.js:91) - createReplay — Deterministic replay of a recorded feed session. Loads a fixture, replays events with configurable speed, and produces reproducible pipeline output. (
src/replay/deterministic.js:84) - buildReceipt — Orchestrates receipt construction: canonicalizes raw input, computes input/output/policy hashes, assembles code identity, and optionally signs. Returns a ProposalReceipt conforming to
spec/receipt-v0.json. (src/receipt/receipt-builder.js:24) - canonicalize — JCS-subset/v0 canonical JSON serializer. Deterministic key ordering, type-safe value encoding (no
undefined,NaN,Infinity). (src/receipt/canonicalize.js) - sha256 — SHA-256 hash with
sha256:prefix for receipt fields. (src/receipt/hash.js) - signReceipt / verifySignature — Ed25519 signing and verification. Fail-closed: throws if no signing key available. Signature format:
ed25519:prefixed base64. (src/receipt/sign.js) - loadKeyring / getPublicKey — Keyring management for receipt verification. Loads
keys/forge-keyring.json. (src/receipt/keyring.js) - getCodeIdentity — Returns code identity triple
{ git_sha, package_lock_sha, node_version }for receiptcode_versionfield.package_lock_shais null (zero-dep posture). (src/receipt/code-identity.js) - computePolicyHash — Hashes the active rule set and regulatory tables to produce the receipt
policy_hash. (src/receipt/policy-hasher.js) - forge-verify — Independent replay verifier CLI. Re-runs the pipeline on original input and compares output hash against receipt. Exit codes: 0=MATCH, 1=MISMATCH, 2=ERROR. (
bin/forge-verify.js) - ForgeConstruct — Top-level construct class.
.analyze(fixturePath)runs the full pipeline (ingest → classify → select)..analyze(path, { receipt: true })adds a ProposalReceipt to the result..getCertificates()returns accumulated RLMF state (defensive copy). (src/index.js:37)
FORGE follows a linear pipeline: fixture files flow through an ingester, then a 5-dimension classifier, then a rule-based selector that emits Theatre proposals. A parallel processor layer handles evidence bundle construction and trust enforcement. Feed pairs enter the composer for composed Theatre proposals. All resolved theatres export RLMF certificates.
flowchart TD
input["Fixture / Live Feed"]
subgraph ingest["Ingester"]
generic["generic.js — any structured JSON event stream"]
end
subgraph classify["Classifier"]
grammar["feed-grammar.js orchestrates all 5"]
cadence["cadence"]
distribution["distribution"]
noise["noise"]
density["density"]
thresholds["thresholds"]
cadence --> distribution --> noise --> density --> thresholds
end
subgraph select["Selector"]
rules["13 rules × evaluateRule"]
end
subgraph compose["Composer"]
align["alignFeeds"]
causal["detectCausalOrdering"]
composed["proposeComposedTheatre"]
align --> causal --> composed
end
subgraph emit["IR Emitter"]
envelope["emitEnvelope → ProposalEnvelope"]
end
subgraph receipt_layer["Receipt Layer"]
direction LR
canon["canonicalize"]
build_r["buildReceipt"]
sign_r["signReceipt"]
canon --> build_r --> sign_r
end
subgraph process["Processor"]
bundle["buildBundle"]
quality["computeQuality"]
doubt["computeDoubtPrice"]
settle["assignEvidenceClass"]
bundle --> quality --> doubt --> settle
end
subgraph trust["Trust / Filter"]
tier["getTrustTier · canSettle"]
useful["computeUsefulness"]
end
subgraph runtime["ForgeRuntime"]
instantiate["instantiate → theatres"]
lifecycle["ingestBundle → settle → expire"]
end
subgraph rlmf["RLMF"]
cert["exportCertificate"]
brier["brierScoreBinary · brierScoreMultiClass"]
end
verify["forge-verify CLI"]
input --> ingest
ingest -- "events[]" --> classify
classify -- "FeedProfile" --> select
classify -- "FeedProfile (×2)" --> compose
select -- "Proposal[]" --> emit
compose -- "Proposal" --> emit
emit -- "ProposalEnvelope" --> receipt_layer
emit -- "receipt: false" --> runtime
receipt_layer -- "ProposalReceipt" --> verify
trust -. "settlement gate" .-> process
runtime --> process
process --> rlmf
style receipt_layer fill:#1a1a2e,stroke:#e94560,color:#fff
style verify fill:#1a1a2e,stroke:#e94560,color:#fff
style emit fill:#0f3460,stroke:#16213e,color:#fff
style trust fill:#533483,stroke:#2b2d42,color:#fff
Directory structure:
./src
./src/index.js
./src/ingester
./src/ingester/generic.js
./src/classifier
./src/classifier/feed-grammar.js
./src/classifier/cadence.js
./src/classifier/distribution.js
./src/classifier/noise.js
./src/classifier/density.js
./src/classifier/thresholds.js
./src/classifier/data
./src/classifier/data/regulatory-epa-aqi.json
./src/classifier/data/regulatory-noaa-kp.json
./src/classifier/data/regulatory-noaa-r.json
./src/selector
./src/selector/rules.js
./src/selector/template-selector.js
./src/theatres
./src/theatres/threshold-gate.js
./src/theatres/cascade.js
./src/theatres/divergence.js
./src/theatres/regime-shift.js
./src/theatres/anomaly.js
./src/theatres/persistence.js
./src/processor
./src/processor/bundles.js
./src/processor/quality.js
./src/processor/uncertainty.js
./src/processor/settlement.js
./src/trust
./src/trust/oracle-trust.js
./src/trust/adversarial.js
./src/rlmf
./src/rlmf/certificates.js
./src/filter
./src/filter/usefulness.js
./src/composer
./src/composer/compose.js
./src/replay
./src/replay/deterministic.js
./src/ir
./src/ir/emit.js
./src/receipt
./src/receipt/canonicalize.js
./src/receipt/code-identity.js
./src/receipt/hash.js
./src/receipt/keyring.js
./src/receipt/policy-hasher.js
./src/receipt/receipt-builder.js
./src/receipt/sign.js
./src/runtime
./src/runtime/lifecycle.js
./src/adapter
./src/adapter/usgs-live.js
./src/adapter/swpc-live.js
./spec
./bin
./bin/forge-verify.js
./spec/construct.json
./spec/construct.yaml
./spec/proposal-ir.json
./spec/receipt-v0.json
./spec/STABILITY.md
./test
./test/unit
./test/convergence
| Export | Type | Description |
|---|---|---|
ForgeConstruct |
Class | Main construct. .analyze(fixturePath) → full pipeline. .getCertificates() → RLMF state |
classify |
Function | events[] + options → FeedProfile (5-dimension grammar) |
classifyCadence |
Function | events[] → cadence classification |
classifyDistribution |
Function | events[] → distribution classification |
classifyNoise |
Function | events[] → noise classification |
classifyDensity |
Function | events[] → density classification |
classifyThresholds |
Function | events[] → threshold classification |
selectTemplates |
Function | FeedProfile → Proposal[] |
evaluateRule |
Function | FeedProfile + Rule → boolean |
RULES |
Constant | 13 template selection rules (TREMOR + CORONA + BREATH) |
alignFeeds |
Function | eventsA[] + eventsB[] + windowMs → aligned pairs |
detectCausalOrdering |
Function | pairs[] → { leader, lag_ms } |
proposeComposedTheatre |
Function | feedProfileA + feedProfileB + alignedPairs + causalOrder → Proposal|null |
buildBundle |
Function | rawEvent + config → evidence bundle |
computeQuality |
Function | rawEvent → quality score |
computeDoubtPrice |
Function | rawEvent → uncertainty model |
assignEvidenceClass / canSettleByClass |
Functions | Bundle → evidence class + settlement gate |
getTrustTier |
Function | sourceId → 'T0'|'T1'|'T2'|'T3'|'unknown' |
canSettle |
Function | tier → boolean (true only for T0/T1) |
validateSettlement |
Function | sourceId → { allowed, tier, reason? } |
checkAdversarial |
Function | bundle → adversarial detection result |
checkChannelConsistency |
Function | bundle → channel consistency result |
ECHELON_PROVENANCE_MAP |
Frozen Constant | T0–T3 → provenance + confidence mapping (src/trust/oracle-trust.js) |
exportCertificate |
Function | theatre + config → RLMF certificate |
brierScoreBinary |
Function | outcome + probability → Brier score |
brierScoreMultiClass |
Function | outcome_bucket + distribution → Brier score |
computeUsefulness |
Function | proposal + feedProfile → usefulness score (0–1) |
emitEnvelope |
Function | feed_id + feed_profile + proposals + options → ProposalEnvelope (IR contract). With receipt: true, returns { envelope, receipt } |
buildReceipt |
Function | rawInput + envelope + options → ProposalReceipt (spec/receipt-v0.json) |
signReceipt |
Function | canonicalPayload + privateKeyPem → { signature, key_id } (ed25519) |
verifySignature |
Function | canonicalPayload + signature + publicKeyPem → boolean |
canonicalize |
Function | any JS value → deterministic canonical JSON string (JCS-subset/v0) |
loadKeyring / getPublicKey |
Functions | Keyring I/O for receipt verification |
forge-verify |
CLI | node bin/forge-verify.js receipt.json --input input.json → exit 0 (MATCH) / 1 (MISMATCH) / 2 (ERROR) |
ForgeRuntime |
Class | Theatre lifecycle orchestrator. .instantiate(proposals) → theatre IDs. .ingestBundle() → process evidence. .getCertificates() → RLMF state |
createReplay |
Function | fixturePath + options → deterministic replay session |
ingest / ingestFile |
Functions | Raw data / file path → events[] |
USGSLiveAdapter |
Class | Live USGS seismic feed adapter |
classifyUSGSFeed |
Function | feedType → full pipeline on live USGS data |
| Template | ID | Resolution | Brier Type | Canonical Use |
|---|---|---|---|---|
| Threshold Gate | threshold_gate |
binary | binary | Will metric exceed threshold within window? |
| Cascade | cascade |
multi_bucket (5) | multi_class | How many events follow trigger within window? |
| Divergence | divergence |
binary | binary | Will source A and B diverge beyond threshold? |
| Regime Shift | regime_shift |
binary | binary | Will metric transition from state A to B? |
| Anomaly | anomaly |
binary | binary | Will metric deviate beyond σ from baseline? |
| Persistence | persistence |
binary | binary | Will condition persist for N consecutive intervals? |
| Tier | Name | Can Settle | Brier Discount | Canonical Examples |
|---|---|---|---|---|
| T0 | settlement_authority | Yes | 0% | epa_aqs, usgs_reviewed, gfz_kp |
| T1 | official_source | Yes | 10% | airnow, usgs_automatic, swpc_goes |
| T2 | corroboration | No | — | openaq, emsc |
| T3 | signal | Never | — | purpleair, thingspeak |
Critical invariant: PurpleAir (T3) may never settle a theatre. Enforced at bundle processing time via canSettle() — not at proposal time.
| Module | Files | Purpose |
|---|---|---|
src/ingester/ |
1 | Generic JSON event stream ingester |
src/classifier/ |
6 + data/ | 5-dimension feed grammar (cadence, distribution, noise, density, thresholds + grammar orchestration). Regulatory tables: EPA AQI, NOAA Kp, NOAA R |
src/selector/ |
2 | Rule-based Theatre template selection. 13 rules across 3 backing specs (TREMOR, CORONA, BREATH) |
src/theatres/ |
6 | Theatre template definitions (threshold_gate, cascade, divergence, regime_shift, persistence, anomaly) |
src/processor/ |
4 | Evidence bundle pipeline (quality scoring, doubt pricing, settlement assessment, bundle orchestration) |
src/trust/ |
2 | Oracle trust enforcement (T0–T3 model) + adversarial detection (channel consistency, coordinate drift, peer divergence) |
src/rlmf/ |
1 | RLMF certificate export (Brier scoring for binary and multi-class, calibration bucket) |
src/filter/ |
1 | Usefulness scoring across four dimensions: population_impact, regulatory_relevance, predictability, actionability |
src/composer/ |
1 | Feed composition: temporal alignment (sliding window), causal ordering (mean offset analysis) |
src/replay/ |
1 | Deterministic replay of recorded feed sessions |
src/ir/ |
1 | Proposal IR envelope emitter — the Echelon integration boundary. Receipt generation wired here |
src/receipt/ |
7 | ProposalReceipt pipeline: canonicalization (JCS-subset/v0), SHA-256 hashing, policy hashing, code identity, receipt builder, ed25519 signing/verification, keyring management |
src/runtime/ |
1 | ForgeRuntime — theatre lifecycle orchestrator (instantiate, ingest, expire, resolve) |
src/adapter/ |
2 | Live feed adapters (USGS seismic, SWPC space weather) |
bin/ |
1 | forge-verify — independent replay verifier CLI for ProposalReceipts |
spec/ |
5 | Construct spec, Proposal IR schema, Receipt v0 schema (receipt-v0.json), stability policy |
test/unit/ |
26 | Unit test suite — 735 tests (node:test, zero dependencies) |
test/integration/ |
1 | Receipt pipeline E2E tests — round-trip verify for all 3 backing specs |
test/convergence/ |
3 spec + 5 support | Convergence loop: 3 backing specs × raw + anonymized modes (TREMOR, CORONA, BREATH) |
- Trust Level: L1 — Local
- 735 unit tests (
node --test test/unit/*.spec.js), 750 total with convergence + integration - Zero external dependencies (Node.js 20+ built-in test runner)
- Regulatory tables: EPA AQI (6 breakpoints), NOAA Kp (9 levels), NOAA R (5 scales)
node --test test/unit/*.spec.js
# ℹ pass 735
# ℹ fail 0Naming: FORGE — Feed-Adaptive Oracle & Runtime Generator. Construct names in the Echelon framework describe function, not aspiration.
Principles: The feed is the signal. The market is the measurement. FORGE reads structure from data streams, not semantics — it does not know what a seismic event "means", only that it is spike_driven, unbounded_numeric, and sparse_network. From that grammar, the right Theatre emerges.
Domain metaphor: The Uniswap factory pattern applied to prediction surfaces. Point at any live data feed with a computable ground truth and a meaningful binary or multi-class question, and FORGE finds the Theatre geometry. Domain expertise is encoded once in the rule set; the grammar engine applies it to every new feed automatically.
Convergence loop: FORGE was built against a gradient-based scoring function (TotalScore = TemplateScore + 0.5 × GrammarScore, max 20.5) across three backing specs (TREMOR, CORONA, BREATH). The code exists because the loop converged — not because it was designed top-down.
# No install needed — zero dependencies, Node.js 20+ only
node --test test/unit/*.spec.js # Run unit tests (735 tests)
node --test test/convergence/*.spec.js # Run convergence testsimport { ForgeConstruct } from './src/index.js';
const forge = new ForgeConstruct();
const result = await forge.analyze('fixtures/usgs-m4.5-day.json');
console.log(result.proposals);
// [
// { template: 'threshold_gate', params: { threshold: 5.0, window_hours: 24, ... }, confidence: 0.90 },
// { template: 'cascade', params: { trigger_threshold: 6.0, bucket_count: 5, ... }, confidence: 0.85 },
// ...
// ]
console.log(result.feed_profile.cadence.classification); // 'event_driven'
console.log(result.feed_profile.noise.classification); // 'spike_driven'// Feed composition (Loop 5 — composer)
import { alignFeeds, detectCausalOrdering } from './src/index.js';
const pairs = alignFeeds(aqiEvents, windEvents, 300_000); // ±5 min window
const causal = detectCausalOrdering(pairs);
// { leader: 'B', lag_ms: 3600000 } → wind leads AQI by ~1h