Loading...
Loading...
Regulator-grade feature attribution for any LSTM/Transformer signal — single-entry PageRank ranks the top-K features that drove the prediction (ADR-126 Phase 6, ADR-123 single-entry PR)
npx skill4agent add ruvnet/ruflo trader-explaintrading-analysisSignedAttributionArtifactmcp__ruflo-sublinear__page-rank-entrysigned-attribution.mjstrading-signalsmcp__claude-flow__memory_retrieve({
key: "SIGNAL_ID",
namespace: "trading-signals"
})modelIdpredictionnpx neural-trader --predict --signal "$SIGNAL_ID" --explain --json{
features: Array<{ name: string; contribution: number }>;
// for Transformers, also includes per-head attention co-occurrence:
attention?: Array<{ head: string; cooccur: Array<[number, number, number]> }>;
}--explainneural-tradercontribution_i = |input_i - μ_i| / σ_iattribution_method: "input-zscore-fallback"__signal_output____signal_output__contribution_icooccur__signal_output__mcp__ruflo-sublinear__page-rank-entrymcp__ruflo-sublinear__page-rank-entry({
nodes: GRAPH_NODES,
edges: GRAPH_EDGES,
sourceIndex: 0,
damping: 0.85,
maxIterations: 100,
tolerance: 1e-8,
seed: 42
})localSingleEntryPageRankplugins/ruflo-neural-trader/src/signed-attribution.mjsAttributionFeature[]topKFeatures(graph, scores, k=10, excludeIndex=0)SignedAttributionArtifact{
signalId: SIGNAL_ID,
modelId: SIGNAL.modelId,
features: TOP_K_FEATURES, // from step 5
graphMetadata: {
nodeCount: GRAPH.nodes.length,
edgeCount: COUNT_EDGES,
pageRankIterations: PR_RESULT.iterations,
seed: SEED // load-bearing for reproducibility
},
generatedAt: NEW_DATE_ISO
}RUFLO_WITNESS_KEY_PATH{ "privateKey": "<hex>" }verification/witness-key.jsonsignAttributionArtifact(body, privateKeyHex)plugins/ruflo-neural-trader/src/signed-attribution.mjs"[WARN] ruflo-neural-trader: no witness signing key found — storing attribution artifact in UNSIGNED degraded mode. Regulator filings will reject UNSIGNED artifacts."trading-analysismcp__claude-flow__memory_store({
key: "attribution-SIGNAL_ID-TIMESTAMP",
namespace: "trading-analysis",
value: JSON.stringify(signedArtifact)
})trading-analysis## Feature attribution for signal `SIGNAL_ID` (model: MODEL_ID)
| Rank | Feature | Score |
|------|---------|-------|
| 1 | NAME | 0.42 |
| 2 | NAME | 0.18 |
| … | … | … |
- PageRank iterations: N
- Graph: nodeCount nodes, edgeCount edges
- Seed: 42 (reproducible — same seed → same ordering)
- Path: mcp | local
- Signature: ed25519:abcd… (or UNSIGNED — degraded warning above)import { verifyAttributionArtifact } from 'plugins/ruflo-neural-trader/src/signed-attribution.mjs';
const ok = await verifyAttributionArtifact(artifact, trustedPublicKey);
if (!ok) {
// [ERROR] attribution verification failed — refuse to publish.
// Pin to trustedPublicKey from project config; do NOT trust the
// artifact.witnessPublicKey field (CWE-347 / #1922 — attacker-controllable).
return;
}trader-explain <signalId>--explainsignalId--seedscripts/smoke-neural-trader-feature-attribution.mjsgraphMetadata.seed--explainplugins/ruflo-neural-trader/src/signed-attribution.tsplugins/ruflo-neural-trader/src/signed-attribution.mjsscripts/smoke-neural-trader-feature-attribution.mjs