create-tradejs 3.1.22 → 3.1.23-beta.239

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +19 -3
  2. package/dist/index.js +36 -5
  3. package/dist/skill-bundle/.codex/skills/ai-train-local-research/SKILL.md +596 -0
  4. package/dist/skill-bundle/.codex/skills/ai-train-local-research/references/gate-ablation.md +324 -0
  5. package/dist/skill-bundle/.codex/skills/ai-train-local-research/references/reporting.md +227 -0
  6. package/dist/skill-bundle/.codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs +5082 -0
  7. package/dist/skill-bundle/.codex/skills/ai-train-local-research/scripts/ai-gate-ablation.test.mjs +1170 -0
  8. package/dist/skill-bundle/.codex/skills/backtest-config-redis/SKILL.md +17 -0
  9. package/dist/skill-bundle/.codex/skills/backtest-config-redis/scripts/get_backtest_config.sh +21 -0
  10. package/dist/skill-bundle/.codex/skills/runtime-parity-mismatch-analysis/SKILL.md +146 -0
  11. package/dist/skill-bundle/.codex/skills/save-strategy-config-from-backtest/SKILL.md +58 -0
  12. package/dist/skill-bundle/.codex/skills/save-strategy-config-from-backtest/agents/openai.yaml +4 -0
  13. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/SKILL.md +334 -0
  14. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/references/research-notes.md +247 -0
  15. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/backtest-run-metrics.mjs +647 -0
  16. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/backtest-run-metrics.test.mjs +321 -0
  17. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/fast-ai-export-metrics.mjs +744 -0
  18. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/fast-ai-export-metrics.test.mjs +553 -0
  19. package/dist/skill-bundle/.codex/skills/strategy-backtest-research/scripts/research-notes-check.mjs +125 -0
  20. package/dist/skill-bundle/.codex/skills/strategy-improvement-research/SKILL.md +18 -1
  21. package/dist/skill-bundle/.codex/skills/strategy-release/SKILL.md +22 -0
  22. package/dist/skill-bundle/.codex/skills/strategy-release/agents/openai.yaml +4 -0
  23. package/dist/skill-bundle/.codex/skills/strategy-release/references/diagnose-live.md +126 -0
  24. package/dist/skill-bundle/.codex/skills/strategy-release/references/direction-policy.md +141 -0
  25. package/dist/skill-bundle/.codex/skills/strategy-release/references/directional-parameter-split.md +93 -0
  26. package/dist/skill-bundle/.codex/skills/strategy-release/references/evidence-limitations.md +76 -0
  27. package/dist/skill-bundle/.codex/skills/strategy-release/references/evidence-retention.md +157 -0
  28. package/dist/skill-bundle/.codex/skills/strategy-release/references/historical-hypothesis-audit.md +163 -0
  29. package/dist/skill-bundle/.codex/skills/strategy-release/references/professional-research-loop.md +198 -0
  30. package/dist/skill-bundle/.codex/skills/strategy-release/references/release-workflow.md +755 -0
  31. package/dist/skill-bundle/.codex/skills/strategy-release/references/research-objective.md +255 -0
  32. package/dist/skill-bundle/.codex/skills/strategy-release/references/verdict-contract.md +200 -0
  33. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/direction-policy-checkpoint.mjs +137 -0
  34. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/direction-policy-checkpoint.test.mjs +85 -0
  35. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/directional-parameter-checkpoint.mjs +149 -0
  36. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/directional-parameter-checkpoint.test.mjs +120 -0
  37. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/release-progress-checkpoint.mjs +621 -0
  38. package/dist/skill-bundle/.codex/skills/strategy-release/scripts/release-progress-checkpoint.test.mjs +349 -0
  39. package/dist/skill-bundle/.codex/tradejs-skill-bundle.json +44 -3
  40. package/package.json +1 -1
@@ -0,0 +1,596 @@
1
+ ---
2
+ name: ai-train-local-research
3
+ description: Execute deterministic AI-gate research for a frozen TradeJS core/export with ai-train, ai-pocket-search, and the reusable gate-ablation tool. Use strategy-improvement-research instead to choose or retune core candidates and orchestrate the full improvement lineage.
4
+ ---
5
+
6
+ # AI Train Local Research
7
+
8
+ Run these commands with `PROJECT_CWD` pointing to `TradeJS-Project`, which owns
9
+ `data/`, `notes/`, `.env`, and `tradejs.config.ts`. Set
10
+ `TRADEJS_SOURCE_REPOSITORY_ROOT` to the exact framework or standalone strategy
11
+ Git checkout whose build and lineage are under study. When that source is a
12
+ standalone strategy, also set `TRADEJS_FRAMEWORK_REPOSITORY_ROOT` to the exact
13
+ framework checkout that provides the built `@tradejs/node` and `@tradejs/cli`
14
+ research runtime. Never infer either source root from `PROJECT_CWD`.
15
+
16
+ This is a gate-stage specialist. It does not select core hypothesis families,
17
+ run multi-round core tuning, or replace the raw-core verdict. Use
18
+ `$strategy-improvement-research` for the complete lineage; invoke this skill
19
+ only after the core/export identity is frozen.
20
+
21
+ Use this skill when the user asks to:
22
+
23
+ - run `ai-train` for a strategy
24
+ - run `ai-pocket-search` over AI export files
25
+ - research or tune a local deterministic AI gate
26
+ - analyze `latest N` or `skip K`
27
+ - do the replay without OpenRouter
28
+ - inspect qN+ approval streams, drawdown, winrate, profit factor, or cadence
29
+ - check time stability, symbol concentration, or direction-specific pockets
30
+ - compare current results with previous TrendLine / ReverseTrendLine style investigations
31
+ - break down false positives / false negatives
32
+ - save each conclusion in a new
33
+ `$PROJECT_CWD/notes/<Strategy>/YYYY-MM-DD-<short-kebab-slug>.md` research record
34
+ - tune approval cadence toward roughly 2-3 approved trades per day when possible, with ~1 approved trade per day as the practical lower bound for narrow high-quality pockets; if a gate approves more, look for filters that lower approvals and raise winrate
35
+
36
+ ## Reusable Research Tooling
37
+
38
+ When AI-gate work follows a raw-core experiment, first read the verified
39
+ `data/research/core/<researchId>/spec.json`, `result.json`, and normalized
40
+ `trades.jsonl` produced by `yarn research:core`. Treat that bundle as the
41
+ immutable source for raw-core ALL/LONG/SHORT economics, selected config lineage,
42
+ and causal setup attribution. Do not rerun core selection inside gate tooling or
43
+ rewrite its target/aggregate verdict. The gate study is a new hypothesis stage:
44
+ evaluate LONG and SHORT approved streams separately, preserve the core bundle
45
+ research ID/config SHA/export lineage in the gate note, and make any
46
+ direction-aware gate explicit. A weak raw-core side may be filtered by a later
47
+ gate only after its own timestamp-grouped validation; never hide or retroactively
48
+ disable it in the core result.
49
+
50
+ Use `scripts/ai-gate-ablation.mjs` for custom deterministic gate filters,
51
+ exclusions, recovery additions, gate replacements, feature inventory, and
52
+ baseline-vs-candidate tables. Read `references/gate-ablation.md` for its
53
+ expression grammar and report contract.
54
+
55
+ Mandatory rule:
56
+
57
+ - Do not create `/tmp` parsers, heredoc ESM replays, or strategy-specific
58
+ one-off scripts for work covered by this tool.
59
+ - If a recurring analysis is missing, extend the permanent script, add or update
60
+ `scripts/ai-gate-ablation.test.mjs`, and document the behavior in the
61
+ reference. Run `node --test scripts/ai-gate-ablation.test.mjs` from the skill
62
+ directory.
63
+ - Build changed strategy/node/CLI packages before running the tool because it
64
+ reconstructs current gate context from `dist`.
65
+ - Keep `yarn ai-train --localOnly --json -n 0` as the authoritative baseline;
66
+ do not interpret variants until baseline qN+ support, PnL, PF, max drawdown,
67
+ strict loss, and loss streak match.
68
+
69
+ ## Mandatory reporting contract
70
+
71
+ Before returning AI-gate metrics in chat or writing a dated notes entry, read
72
+ `references/reporting.md` and follow its section order, metric names, windows,
73
+ rounding, and `n/a` rules exactly. Use the full contract unless the user
74
+ explicitly asks for one narrow metric. Do not improvise a shorter alternative
75
+ or silently omit unavailable metrics.
76
+
77
+ For every approved-stream summary, calculate `PnL/trade` as total approved PnL
78
+ divided by completed approved trades. Never substitute the backtest CLI progress
79
+ `avg`, which is PnL per completed test/symbol. Use `n/a` when `N = 0`.
80
+
81
+ ## AI Gate Pocket Hygiene
82
+
83
+ Do not move a discovered pocket into a deterministic AI gate just because it
84
+ improves aggregate backtest PnL. Treat every candidate rule as overfit until it
85
+ survives the checks below.
86
+
87
+ Hard rule:
88
+
89
+ - Do not use data-availability or sample-count fields as approval evidence.
90
+ Examples include derivatives `points`, `rows`, `latestIndex`, source array
91
+ `.length`, coverage counts, shard counts, or "how much context was loaded".
92
+ These may be used only as data-quality guards that block or mark data as
93
+ missing/stale; they must not promote quality or unlock approval pockets.
94
+ - Event counts that are genuine market structure features, such as trendline
95
+ touches, zone `hitCount`, bars since a detected setup, or pivot counts, are
96
+ allowed only when they measure the setup itself and are causal at signal time.
97
+ Do not confuse them with "number of rows available in the dataset".
98
+ - Do not reject `baseContext.derivatives.intervals` as an AI-gate input only
99
+ because the historical export has partial coverage. In TradeJS exports these
100
+ target derivative interval fields may be unavailable for older history and
101
+ cannot always be backfilled to a longer period, but they are causal live
102
+ market-state fields when present and may be used for deterministic AI-gate
103
+ approval after validation. Treat missing/stale interval data as a quality
104
+ guard, not as approval evidence.
105
+ - Treat independent decision timestamps or documented market episodes as the
106
+ support unit for gate selection. Rows and symbols sharing one timestamp are
107
+ correlated fan-out, not independent observations.
108
+ - Keep every timestamp group wholly inside one partition. Never split rows from
109
+ the same timestamp across train, tuning, validation, or test.
110
+ - Treat any partition used to rank, select, or refine a pocket as tuning data.
111
+ Production readiness requires a later untouched chronological test.
112
+
113
+ Before implementing a pocket:
114
+
115
+ - Audit existing gate conditions before proposing new ones. Inventory current
116
+ approval, downgrade, recovery, and block pockets in the strategy adapter /
117
+ guardrails, including constants, high-precision thresholds, env-sensitive
118
+ fields, and data-count fields.
119
+ - Revalidate old pockets under the same export, live env assumptions, and metric
120
+ table used for any new candidate. Do not assume existing gate rules are still
121
+ valid after data provider, context, lookback, interval, target/reference, or
122
+ adapter changes.
123
+ - For each existing pocket, classify it as `keep`, `round`, `replace`,
124
+ `disable`, or `needs-more-data`, and explain why.
125
+ - Require time-ordered validation, not only full-sample or train metrics.
126
+ - Require at least `25` independent approved events in train and `25` in the
127
+ untouched test, with support across at least two folds or calendar months.
128
+ If support is lower, classify the pocket as `needs-more-data` and
129
+ `research-only` / passive-only regardless of row count or aggregate PnL.
130
+ - Check stability by direction, month/quarter, and symbol. Avoid rules where the
131
+ result depends on one short period, one side, or a few symbols.
132
+ - Record each pocket field's scope as `target`, `benchmark`, or `global`.
133
+ Benchmark/global approval pockets require a fan-out stress test plus either a
134
+ target-specific discriminator or an enforced portfolio throttle.
135
+ - Treat a new export as revalidation only for independent timestamps after the
136
+ prior selection cutoff. Overlapping historical rows are not new evidence.
137
+ - Compare q4+ and q5+ streams before and after the rule. A pocket that improves
138
+ total PnL but worsens drawdown, loss streak, or losing months usually should
139
+ not become live approval logic.
140
+ - Run an ablation: show the baseline gate, the new pocket alone, and the final
141
+ gate with the pocket included.
142
+ - Run threshold sensitivity around each numeric cutoff. Test adjacent rounded
143
+ values and a small band around the discovered value; prefer rules that remain
144
+ useful after rounding.
145
+
146
+ Threshold implementation rules:
147
+
148
+ - Do not paste high-precision search cutoffs directly into gate code unless
149
+ there is a strong documented reason. Values like `0.416874`, `-0.00904779`,
150
+ `4.6069`, or `-0.5906` should be treated as search artifacts first.
151
+ - Convert discovered thresholds to coarser, defensible boundaries before
152
+ implementation, then rerun replay metrics. Examples: use human-scale values
153
+ such as `0.42`, `-0.01`, `4.7`, `-0.6`, or a clearly named domain threshold
154
+ instead of copying the exact optimizer boundary.
155
+ - Round approval thresholds in the stricter direction by default so rounding
156
+ does not silently expand the approved set. For `>=` approval cutoffs, round
157
+ upward; for `<=` approval cutoffs, round downward. If a relaxed rounded value
158
+ is desired, validate it explicitly as a separate candidate.
159
+ - If rounding materially changes cadence, PF, drawdown, or month stability, do
160
+ not implement the pocket until a stable rounded threshold is found.
161
+ - Name constants by their market meaning and validation scope, not by the search
162
+ output. Good names mention the feature, direction, and intent, for example
163
+ `SHORT_BREADTH_SHOCK_MARKET_RETURN_MAX`.
164
+
165
+ Documentation requirement for any new AI-gate pocket:
166
+
167
+ - Report the exact export/merge id and shard count.
168
+ - Report train, tuning, and untouched-test metrics; independent-event support;
169
+ direction and month/quarter splits; symbol and event concentration; PF;
170
+ drawdown; and max loss streak.
171
+ - Report trades and events per day, active-day ratio, trades per event, p95/max
172
+ batch size, and the largest event's shares of approved count and PnL.
173
+ - Report capacity stress at the real production cap or, when unknown, at
174
+ capacities `1`, `3`, and `5`, including rejected overflow. Calculate
175
+ simultaneous stop-risk only from the historical effective `MAX_LOSS_VALUE`
176
+ used by the backtest that produced the export. Prefer an immutable resolved
177
+ config snapshot or archived backtest checkpoint referenced by
178
+ `backtestRunId`/`backtestTestKey`. Do not substitute the current named Redis
179
+ config, a current strategy default, or a production value unless lineage
180
+ proves it matches the export. When the historical value cannot be recovered,
181
+ report stop-risk as `unknown`/`n/a`.
182
+ - State the raw discovered threshold and the rounded implemented threshold.
183
+ - State whether the rounded rule was rerun and whether it stayed stable.
184
+ - If the rule uses a context field whose semantics can change with env settings
185
+ such as lookback, interval list, target/reference mode, or data provider, call
186
+ that out explicitly and avoid using the field for approval unless the rule is
187
+ validated under the intended live env.
188
+
189
+ Documentation requirement for existing AI-gate pockets:
190
+
191
+ - Include an "Existing Gate Audit" section in the report or notes whenever gate
192
+ tuning is requested.
193
+ - List each existing pocket or threshold group with file/line references where
194
+ practical.
195
+ - For every old high-precision threshold, state whether it should stay exact,
196
+ be rounded and rerun, or be removed.
197
+ - For every old data-count or env-sensitive condition, state whether it is only
198
+ a data-quality guard or whether it currently affects approval. If it affects
199
+ approval, recommend replacing it with market-state features unless validation
200
+ proves it is stable under the intended live env.
201
+ - If old rules are not revalidated, mark the final recommendation as incomplete
202
+ and do not present new pockets as production-ready.
203
+
204
+ Suggested old-gate audit commands:
205
+
206
+ ```bash
207
+ rg -n "pocket|calibrated|q4|q5|recovery|approvalAllowedNow|deterministicQuality|hardBlockReasons|softBlockReasons|[0-9]+\\.[0-9]{3,}|\\.points|\\.length" packages/strategies/src/<Strategy>
208
+ rg -n "DERIVATIVES_CONTEXT|targetContext|targetDerived|referenceContexts|points|rows|lookback|intervals" packages/strategies/src/<Strategy> packages/core/src packages/node/src
209
+ ```
210
+
211
+ Mandatory validation sections for gate work:
212
+
213
+ - **Live-env parity**: record the intended live env and compare it with the
214
+ export/replay assumptions. Include at least `AI_MODE`, `MIN_AI_QUALITY`,
215
+ interval/timeframe, strategy config name, derivatives lookback/intervals/
216
+ target mode, CMC windows, and any provider/context toggles that can affect
217
+ gate fields. If parity is unknown, mark the recommendation as not ready for
218
+ production.
219
+ - **Feature provenance**: for every field used by an old or new pocket, list
220
+ the source path, whether it is causal at signal time, whether it is
221
+ market-state, setup-event-count, or data-availability, whether its scope is
222
+ target/benchmark/global, and whether it depends on
223
+ lookback/window/cache/provider settings.
224
+ - **Walk-forward validation**: when the export spans enough history, validate
225
+ across multiple chronological folds or at least month/quarter buckets. Prefer
226
+ pockets that survive changing market regimes over pockets that win only in a
227
+ single terminal validation split.
228
+ - **Acceptance gates**: define minimum validation support, maximum symbol
229
+ and event concentration, acceptable losing months, max loss streak,
230
+ PF/drawdown improvement, and cadence/capacity bounds before recommending
231
+ implementation. Require `>=25` independent events in both train and untouched
232
+ test; no symbol or timestamp may provide more than one third of approved count
233
+ or PnL; no batch may exceed the declared live capacity; no new losing-month
234
+ cluster or worse loss streak is allowed. A miss is unconditionally
235
+ `research-only` / passive-only until new evidence resolves it.
236
+ - **Negative control**: for suspiciously strong or highly specific pockets, run
237
+ a sanity check such as shuffled labels/profits or a nearby nonsense feature.
238
+ A pocket that still looks good under a negative control is overfit or the
239
+ script is wrong.
240
+ - **Boundary tests**: require unit tests for implemented gate changes at the
241
+ threshold boundary, just above/below it, with missing/null fields, and with
242
+ rounded thresholds rather than raw optimizer cutoffs.
243
+ - **Passive rollout**: add new or changed gate logic in observation mode first.
244
+ Log old decision, new decision, reason deltas, and per-timestamp fan-out. Do
245
+ not present or enforce a candidate that fails independent-event support or
246
+ capacity gates as historically production-ready. The sole exception is an
247
+ operator-directed prospective test explicitly authorized through
248
+ `$strategy-forward-start` for one checksum-reproducible candidate at
249
+ `MAX_LOSS_VALUE=1`; keep its classification `research-only`, retain contrary
250
+ evidence, and let that skill enforce the immutable target, package, runtime,
251
+ and rollback boundaries.
252
+ - **Old-gate cleanup**: when an old pocket is replaced or disabled, remove dead
253
+ constants/prompt fields/tests, update notes, and explain the migration path.
254
+
255
+ ## Workflow
256
+
257
+ 1. Confirm the latest merged dataset exists.
258
+
259
+ Use the shard-aware permanent discovery command:
260
+
261
+ ```bash
262
+ node .codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs --list --strategy <Strategy>
263
+ ```
264
+
265
+ Important shard-aware rule:
266
+
267
+ - merged exports may now be split into `-part1 ... -partN` files
268
+ - treat all files with the same `strategy token + merge id` as one logical export
269
+ - do not assume the latest export is a single `...-merged-<ts>.jsonl` file
270
+ - `yarn ai-train` already groups matching part files automatically when:
271
+ - no explicit `--file` is given and it selects the latest merge id
272
+ - or `--file` points to any one shard like `...-part1.jsonl`
273
+ - `yarn ai-pocket-search` follows the same shard grouping convention and treats a `--file ...-part1.jsonl` argument as the whole merge group
274
+ - when reporting the export used, list the merge id and shard count, not only the first shard path
275
+
276
+ 2. If the user wants config analysis, read the real Redis config instead of guessing from defaults.
277
+
278
+ Use:
279
+
280
+ ```bash
281
+ docker exec inv-redis redis-cli JSON.GET users:root:backtests:configs:<Strategy>:ai
282
+ ```
283
+
284
+ 3. Decide replay mode.
285
+
286
+ - If the user explicitly says `without OpenRouter`, use `--localOnly`.
287
+ - If the goal is deterministic gate research, also prefer `--localOnly`.
288
+ - If the user explicitly wants model behavior, run normal `ai-train` with the default GPT-5 Mini model unless they name another model.
289
+ - Interpret replay mode against runtime `AI_MODE` explicitly:
290
+ - `yarn ai-train --localOnly` matches `AI_MODE=gate` behavior for approval logic, because both use the local deterministic strategy AI gate and the same `MIN_AI_QUALITY` threshold.
291
+ - normal `yarn ai-train` is the closer proxy for `AI_MODE=llm`, because approval depends on provider/model output instead of only the local deterministic gate.
292
+ - do not describe `--localOnly` findings as expected `AI_MODE=llm` production behavior.
293
+
294
+ 4. Run the replay.
295
+
296
+ Examples:
297
+
298
+ ```bash
299
+ yarn ai-train --strategy TrendLine -n 500 --localOnly
300
+ yarn ai-train --strategy ReverseTrendLine -n 500 --localOnly
301
+ yarn ai-train --strategy VolumeDivergence -n 500 --localOnly
302
+ yarn ai-train --strategy TrendLine -n 0 --localOnly --terminalWindows=180,90,30,7 --output data/ai/output/trendline-ai-train.json
303
+ yarn ai-pocket-search --strategy TrendLine -n 0 --maxDepth 2 --minSupport 25
304
+ ```
305
+
306
+ ### Freshness and terminal-window gate
307
+
308
+ For any current/live cadence conclusion, run all selected rows so one execution
309
+ produces the full result and terminal summaries:
310
+
311
+ ```bash
312
+ yarn ai-train --strategy <Strategy> -n 0 --localOnly --terminalWindows=180,90,30,7
313
+ ```
314
+
315
+ Terminal windows are anchored to the maximum dataset timestamp. Whenever a
316
+ period comparison table is shown, it must include the full export plus `180d`,
317
+ `90d`, `30d`, and `7d`, including windows with zero approvals. Use
318
+ `--terminalWindows=180,90,30,11,7` when the production comparison additionally
319
+ uses an 11-day window. Do not run the provider repeatedly for these windows;
320
+ the command derives them from the same evaluated rows. If the export is shorter
321
+ than 180 days, keep the `180d` row and mark it as incomplete/overlapping the
322
+ available full export rather than silently omitting it.
323
+
324
+ Before stating expected production cadence:
325
+
326
+ - record dataset min/max timestamps and `dataLagDays`
327
+ - require the export to overlap the production window under discussion
328
+ - report full history and every terminal window, including zero approvals
329
+ - period tables must always show rows for the full export, `180d`, `90d`,
330
+ `30d`, and `7d`
331
+ - when comparing a new candidate/gate with a baseline or previous result, show
332
+ terminal-window metrics as a comparison table for every row (`full`, `180d`,
333
+ `90d`, `30d`, `7d`) rather than only the candidate values. Include baseline
334
+ and candidate N, WR, PF, PnL, Max DD, max loss streak, losing months, and
335
+ trades/day
336
+ - for the same terminal rows, include events/day, active-day ratio, unique
337
+ events, trades/event, p95/max batch, and largest-event count/PnL shares
338
+ - use terminal `approvedPerCalendarDay`, not the full-history average, as the
339
+ current cadence evidence
340
+ - record git SHA, dirty state, gate fingerprint, config-id fingerprint, and
341
+ context fingerprint from the report
342
+ - compare runtime only when gate/config/context lineage and `MIN_AI_QUALITY`
343
+ match; otherwise label it a different experiment
344
+ - inspect terminal top reject reasons before changing a threshold
345
+ - if the export tail is stale, report current live cadence as unknown and build
346
+ a fresh export
347
+
348
+ Context semantics rule:
349
+
350
+ - top-level derivatives fields are BTC benchmark context
351
+ - `targetContext` / `targetDerived` are target-symbol context
352
+ - when `DERIVATIVES_CONTEXT_TARGET_ENABLED=false`, target fields must be absent;
353
+ downloaded target rows or membership in extra reference symbols may expose the
354
+ symbol only through `referenceContexts`
355
+ - do not rename benchmark evidence as target evidence in reports
356
+ - do not switch an existing gate from benchmark to target behavior without a
357
+ new export, terminal validation, and updated notes
358
+
359
+ After any gate-code change, rerun the command and create a new research file at
360
+ `notes/<Strategy>/YYYY-MM-DD-<short-kebab-slug>.md`. Never append the run to an
361
+ older research file. Metrics from an older gate fingerprint are historical
362
+ context only.
363
+
364
+ Shard-aware examples:
365
+
366
+ ```bash
367
+ yarn ai-train --strategy TrendShift --localOnly --json -n 0
368
+ yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0
369
+ yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0 --dumpEvaluations /tmp/trendshift-evals.jsonl
370
+ yarn ai-train --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl --localOnly --json -n 0 --dumpEvaluations /tmp/trendshift-evals.jsonl --dumpFeatures gateFeatures
371
+ yarn ai-pocket-search --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl -n 0 --maxDepth 2 --minSupport 25
372
+ yarn ai-pocket-search --strategy TrendShift --file data/ai/export/ai-dataset-trendshift-merged-1779459438806-part1.jsonl -n 0 --scope approved --maxDepth 2 --minSupport 5
373
+ ```
374
+
375
+ Interpretation:
376
+
377
+ - both commands above should evaluate the full shard group for that merge id, not only `part1`
378
+ - if a partial replay is genuinely needed, use native `ai-train` selection
379
+ options rather than assuming one shard equals one isolated window
380
+ - `yarn ai-train --localOnly --json` is the baseline source of truth for current deterministic gate metrics
381
+ - Release evidence with an explicit one-side gate must pass
382
+ `--directionPolicy long_only|short_only`. This flag is evidence metadata, not
383
+ a filter: `ai-train` rejects the report unless the actual evaluated gate has
384
+ zero approved rows for the suppressed direction in full and terminal
385
+ windows. Use `both` (default) or `direction_aware` for policies that retain
386
+ both approved sides.
387
+ - `yarn ai-pocket-search` is the default pocket discovery tool for future AI-gate rules. It reconstructs current strategy AI payloads, excludes outcome/current gate-output fields by default, shows progress bars, deduplicates equivalent row-selection pockets, and writes a Markdown report under `data/ai/output`.
388
+ - `ai-pocket-search` uses a time-ordered row holdout by default
389
+ (`--validationSplit 0.25`) and ranks candidates on that holdout. Treat it as
390
+ tuning evidence, not an untouched test. For direction-specific discovery use
391
+ `--direction LONG` or `--direction SHORT`. For release research, reserve a
392
+ timestamp-grouped tail with `--testSplit ... --sealTest`; the report retains
393
+ only its timestamp/count bounds and excludes its rows from current-gate and
394
+ pocket economics. Open it once later with a frozen `ai-gate-ablation.mjs`
395
+ spec. Plain `--testSplit` still prints test metrics and is therefore an opened
396
+ historical test, not sealed release evidence. Use `--validationSplit 0` only
397
+ for legacy full-sample exploration.
398
+ - `ai-pocket-search` uses `--coverageMode auto` by default. It keeps the
399
+ full-history search for non-provider features and runs separate CMC and
400
+ Coinalyze cohorts over rows where that context is usable. Each cohort gets
401
+ its own timestamp-grouped train/tuning/test split, and every reported cohort
402
+ pocket must contain a predicate from that provider family. Use
403
+ `--coverageMode full` only when intentionally reproducing the legacy single
404
+ full-period search.
405
+ - `ai-pocket-search` uses `--cadenceMode auto` by default. For a sparse train
406
+ partition it scales discovery-only `minSupport` / `minEvents` down from the
407
+ legacy 20 / 10 defaults using the number of independent timestamp events.
408
+ A train partition below 200 events uses
409
+ `minSupport=clamp(ceil(events*0.1),3,20)` and
410
+ `minEvents=clamp(ceil(minSupport*0.5),3,10)`; the default maximum event share
411
+ relaxes only as far as one third. Each provider coverage cohort gets its own
412
+ thresholds. Explicit
413
+ `--minSupport`, `--minEvents`, `--minValidationSupport`,
414
+ `--minValidationEvents`, and `--maxEventCountShare` values always win. Use
415
+ `--cadenceMode fixed` to reproduce the legacy fixed thresholds.
416
+ - Adaptive thresholds make low-cadence hypothesis discovery possible; they do
417
+ not lower the production evidence bar. Every pocket is marked
418
+ `research-only` when it has fewer than 25 independent train events, fewer
419
+ than 25 matching events in the untouched test, or no untouched test at all.
420
+ `production-candidate` means only that these sample-size prerequisites were
421
+ met, not that the pocket is automatically safe to ship.
422
+ - Coverage flags, coverage start/end, and cohort sizes are data-quality
423
+ metadata only. They select the research cohort and appear in the report, but
424
+ they are never eligible pocket predicates. Missing or stale provider context
425
+ must not be flattened into fallback market states such as derivatives
426
+ `pressure=neutral`.
427
+ - use `--includeGateContext` only for auditing existing gate output fields, not for discovering new future approval rules
428
+ - use `--scope approved` with a smaller `--minSupport` to find sub-pockets inside the current qN+ approved stream; use `--scope all` or `--scope candidates` to look for expansion candidates
429
+ - when doing offline pocket research, prefer `--dumpEvaluations` for the evaluated rows
430
+ - when the research needs signal-time gate inputs such as CMC, MTF, ATR bucket, benchmark conflict, participation, execution, or strategy-specific `*GateFeatures`, add `--dumpFeatures gateFeatures`; this writes the current `baseContext.gateFeatures` and strategy gate features into each dump row
431
+ - when broader context is needed, use `--dumpFeatures baseContext`; it writes compact current base-context sections (`regime`, `structure`, `participation`, `relative`, `derivatives`, `mtf`, `gateFeatures`) without the bulky `raw` section
432
+ - join/compare extra fields from the original dataset only when they are not available through `--dumpFeatures`, and treat those joined fields as explanatory features rather than current gate truth after adapter changes
433
+ - use `scripts/ai-gate-ablation.mjs` for custom rule ablations and verify its
434
+ baseline against `yarn ai-train --localOnly --json` for the same export/window
435
+
436
+ 5. Read these sections first:
437
+
438
+ - `OUTCOME`
439
+ - `BY DIRECTION`
440
+ - `DETERMINISTIC FLOW`
441
+ - `QUALITY BREAKDOWN`
442
+
443
+ 6. Always show quality-cadence metrics for the main approved bucket.
444
+
445
+ Default naming convention:
446
+
447
+ - `qN+` means the effective `MIN_AI_QUALITY=N` approved stream, so it includes every approval with quality `>= N`.
448
+ - Examples:
449
+ - `q3+` includes `q3`, `q4`, `q5`
450
+ - `q4+` includes `q4`, `q5`
451
+ - `q5+` includes only `q5`
452
+ - Do not default to plain `q1` / `q2` / `q3` / `q4` / `q5` wording unless the user explicitly asks for the isolated subset.
453
+
454
+ For the default `q4+` approved stream, report:
455
+
456
+ - `winrate` / `precision_approved`
457
+ - `profit_factor`
458
+ - `max_drawdown`
459
+ - `max_drawdown_pct_of_gross_profit`
460
+ - `max_drawdown_pct_of_total_profit`
461
+ - `max_consecutive_losses` / `max loss streak`
462
+ - losing approved months count, and list the losing months when the count is non-zero
463
+ - `avg_profit_approved_per_day`
464
+ - `avg_profit_approved_per_month`
465
+ - `avg_approved_trades_per_day`
466
+ - `avg_approved_trades_per_week`
467
+ - unique approved event timestamps
468
+ - approved events per day and active-day ratio
469
+ - trades per event, p95/max approved batch size
470
+ - largest-event shares of approved count and PnL
471
+
472
+ Use the same period logic as `packages/cli/src/lib/aiTrainMetrics.ts`: `(max timestamp - min timestamp) / 1 day`, with a minimum of `1` day. If useful, also mention the full-window normalization separately, but the required table is for the default approved stream named in `qN+` notation. If `q5+` or another threshold is important for the strategy, include it too. If the user explicitly asks for isolated `q1` / `q2` / `q3` / `q4` / `q5`, report those separately and label them clearly.
473
+
474
+ 7. For deeper FP/FN and gate-ablation analysis, use the permanent tool.
475
+
476
+ ```bash
477
+ node .codex/skills/ai-train-local-research/scripts/ai-gate-ablation.mjs \
478
+ --file data/ai/export/ai-dataset-<token>-merged-<ts>-part1.jsonl \
479
+ --variant 'name::filter::additionalIndicators.baseContext.<path> <= <value>' \
480
+ --featurePattern '<field-regex>' \
481
+ --output data/ai/output/<strategy>-gate-ablation.md
482
+ ```
483
+
484
+ - It streams shards in part order, rebuilds the current payload after plugin
485
+ registration, and keeps outcome labels separate from decision features.
486
+ - Use repeated `--variant` arguments or a JSON `--spec` to compare hypotheses
487
+ in one pass.
488
+ - Use `filter`, `exclude`, `add@quality`, or `replace@quality` according to the
489
+ ablation semantics documented in `references/gate-ablation.md`.
490
+ - Do not use `--includeGateContext` for discovery; it is audit-only.
491
+ - If its baseline differs materially from `ai-train`, stop and fix the permanent
492
+ tool before interpreting hypotheses.
493
+
494
+ 8. For strategy AI investigations, always look for these questions:
495
+
496
+ - Is the strategy core firing earlier than the adapter wants?
497
+ - Is a stricter threshold such as `q5+` actually better than the broader default stream such as `q4+`?
498
+ - Is one direction much worse than the other?
499
+ - Is one direction responsible for most drawdown?
500
+ - Are the best pockets counter-trend or aligned?
501
+ - Is there a field mismatch between `core.ts` and `adapters/ai.ts`?
502
+ - Is the backtest config exploring the detector or only TP/SL?
503
+
504
+ 9. For gate tuning, validate candidate rules beyond aggregate profit.
505
+
506
+ Minimum checks:
507
+
508
+ - audit existing gate pockets and thresholds before adding new ones
509
+ - revalidate existing approval/recovery/downgrade/block rules on the same export
510
+ and env assumptions used for the proposed change
511
+ - classify old pockets as `keep`, `round`, `replace`, `disable`, or
512
+ `needs-more-data`
513
+ - include live-env parity and feature provenance tables in the analysis
514
+ - run walk-forward or month/quarter stability checks when history allows it
515
+ - define acceptance gates before treating a pocket as production-ready
516
+ - use a negative control for unusually strong or highly specific pockets
517
+ - reject approval rules based on data-count or availability fields such as
518
+ derivatives `points`, row counts, `.length`, coverage counts, or loaded-window
519
+ size; use those only as missing/stale-data guards
520
+ - reject high-precision pocket thresholds until they have been rounded to a
521
+ defensible value and replayed again
522
+ - run sensitivity checks around each proposed numeric threshold
523
+ - report train and validation support separately when using `ai-pocket-search`
524
+ or a custom split, but label any partition used for selection as tuning
525
+ - group partitions by timestamp and report independent-event support separately
526
+ for train, tuning, and untouched test
527
+ - report event clustering and capacity stress for every terminal window
528
+ - require a target-specific discriminator or portfolio throttle for
529
+ benchmark/global pockets that can approve many symbols on one timestamp
530
+ - include an ablation table: baseline, pocket-only when applicable, and final
531
+ gate
532
+ - require boundary tests and a passive-rollout plan for implemented gate changes
533
+ - clean up old disabled pockets instead of leaving dead constants or prompt
534
+ fields behind
535
+ - compare q4+ and q5+ separately
536
+ - report winrate as a percentage
537
+ - report max drawdown both as an absolute value and as percentages of gross profit and total profit
538
+ - report Sharpe, Sortino, and Calmar for the approved stream when available,
539
+ and include a one-sentence conclusion: whether the candidate improved
540
+ risk-adjusted quality, merely reduced trades, or worsened tail risk
541
+ - always report max consecutive losses / max loss streak for the approved stream
542
+ - always report losing approved months count for the approved stream; when non-zero, include the month ids and monthly approved PnL
543
+ - split by direction
544
+ - split by quarter or month when the export spans enough time
545
+ - check symbol concentration; avoid rules where most profit comes from only a few symbols
546
+ - prefer candidate pockets that improve profit factor or drawdown without destroying cadence
547
+ - for live-style approval gates, usually aim for about 2-3 approved trades per day, but accept narrow high-quality pockets down to ~1 approved trade per day when profit factor/drawdown materially improve; if a strategy approves substantially more, assume there is likely room to lower approvals and raise winrate with additional filters
548
+ - treat tiny added slices as unstable even when aggregate profit improves
549
+ - if the candidate depends on env-sensitive context construction, such as
550
+ derivatives lookback, interval selection, target/reference mode, or CMC window
551
+ availability, validate it under the intended live env before recommending code
552
+ changes
553
+
554
+ Risk-adjusted metric convention:
555
+
556
+ - `sharpe_ratio` and `sortino_ratio` in TradeJS AI-gate research are computed
557
+ from approved trade PnL, annualized by approved-trade cadence over the
558
+ evaluated period. Treat them as PnL-stream quality metrics, not capital-return
559
+ ratios.
560
+ - `calmar_ratio` is annualized approved PnL divided by approved max drawdown.
561
+ - When comparing gates, prefer candidates where Sharpe/Sortino/Calmar improve
562
+ together with PF/maxDD. If only Sharpe improves because many trades were
563
+ removed while 30d/7d tail risk remains, state that explicitly.
564
+
565
+ ## Notes format
566
+
567
+ Read both `references/reporting.md` and
568
+ `../strategy-backtest-research/references/research-notes.md` before writing a
569
+ note. The shared contract controls storage, one-research-per-file boundaries,
570
+ frontmatter, resolved config, and the machine-readable metric snapshot. The AI
571
+ reporting contract controls tables, metric names, validation, threshold,
572
+ rollout, and cleanup sections.
573
+
574
+ Every new AI-gate study must:
575
+
576
+ - create one new file under `notes/<Strategy>/`, never update a rolling log;
577
+ - keep that file local-only and ignored by Git; never stage, commit, or
578
+ force-add anything under `notes/`;
579
+ - embed the complete `ai-train --localOnly --json` result and structured
580
+ ablation/partition summaries needed to rebuild every displayed metric;
581
+ - embed the secret-free resolved backtest/runtime/context configuration instead
582
+ of only naming a Redis key or current config;
583
+ - list export/output paths and SHA-256 values as disposable artifact inventory,
584
+ not as the only metric evidence;
585
+ - downgrade `reproduction` from `complete` when any displayed metric or lineage
586
+ cannot be recovered from the note after export deletion.
587
+
588
+ ## Current repo conventions
589
+
590
+ - Prefer `GPT-5 Mini` by default for non-local AI replay unless the user names another model.
591
+ - When the strategy already has deterministic adapter fields like:
592
+ - `approvalAllowedNow`
593
+ - `deterministicQuality`
594
+ - `structuralHardBlockReasons`
595
+ local replay is the preferred research mode.
596
+ - If these fields are missing, add them before trusting `--localOnly`.