patchwork-os 1.1.0-beta.3.canary.436 → 1.1.0-beta.4
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.
- package/dist/ta/desk/cells/structureRetest.d.ts +78 -0
- package/dist/ta/desk/cells/structureRetest.js +277 -0
- package/dist/ta/desk/cells/structureRetest.js.map +1 -0
- package/package.json +1 -1
- package/scripts/start-all.ps1 +209 -209
- package/scripts/start-orchestrator.ps1 +158 -158
- package/templates/recipes/crypto-daily-brief.yaml +805 -0
- package/templates/recipes/crypto-midday-pulse.yaml +133 -0
- package/templates/recipes/crypto-watchlist.example.json +8 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kodama-structure-retest @1d — break-and-retest structure cell.
|
|
3
|
+
*
|
|
4
|
+
* FROZEN PARAMS (pre-registered off-repo BEFORE any result was computed, at
|
|
5
|
+
* ~/.patchwork/qumo/kodama-structure-retest-spec.json; any change must bump
|
|
6
|
+
* methodVersion and reset accrual to zero, and requires a fresh spec v2):
|
|
7
|
+
*
|
|
8
|
+
* FRACTAL_N = 2 swing confirmation window (reuses src/ta/swings.ts
|
|
9
|
+
* isFractalHigh/isFractalLow — same definition as
|
|
10
|
+
* ta-cycles-1, no new swing logic invented here)
|
|
11
|
+
* BREAK_PCT = 0.005 close must clear the level by >=0.5% (close-based,
|
|
12
|
+
* filters pure wicks; a close-through is the standard
|
|
13
|
+
* textbook break definition)
|
|
14
|
+
* RETEST_WINDOW_BARS = 10 bars after the break to look for a retest touch
|
|
15
|
+
* RETEST_TOLERANCE_PCT = 0.003 retest bar's low/high must come within 0.3% of the
|
|
16
|
+
* level (tighter than the 0.5% break threshold —
|
|
17
|
+
* retest should return closer to the exact level)
|
|
18
|
+
* OUTCOME_WINDOW_BARS = 10 bars the card races before push/unscorable
|
|
19
|
+
* R_MULTIPLIER = 1.0 rRef = entry ± 1× stop-distance
|
|
20
|
+
* UNIVERSE = ["BTCUSDT", "ETHUSDT"] — the only symbols cellBacktest.ts's
|
|
21
|
+
* ALWAYS_LISTED survivorship guard currently permits; fixed
|
|
22
|
+
* BEFORE looking at any results (see spec's sample.universeJustification)
|
|
23
|
+
* METHOD_VERSION = "kodama-structure-retest-1d-v1"
|
|
24
|
+
*
|
|
25
|
+
* Hypothesis: a classic break-and-retest — price breaks a confirmed swing level,
|
|
26
|
+
* retests it, and the retest bar's own close holds the continuation side — resolves
|
|
27
|
+
* in the continuation direction at a rate greater than a matched-date random-direction
|
|
28
|
+
* null, over a fixed 10-bar forward outcome window.
|
|
29
|
+
*
|
|
30
|
+
* Fire logic (single detect() call per bar-close, walking backward from the latest
|
|
31
|
+
* closed bar to find the most recent unconsumed break+retest+hold sequence):
|
|
32
|
+
* 1. Find the most recent confirmed swing (high or low) strictly before the
|
|
33
|
+
* current bar, using detectSwings(candles, FRACTAL_N) on the visible slice.
|
|
34
|
+
* 2. Scan forward from that swing for the first bar whose CLOSE breaks the level
|
|
35
|
+
* by >= BREAK_PCT (close-based, direction depends on swing kind: a swing HIGH
|
|
36
|
+
* broken upward = bullish break; a swing LOW broken downward = bearish break).
|
|
37
|
+
* 3. Within RETEST_WINDOW_BARS bars after the break bar, find the first bar whose
|
|
38
|
+
* [low, high] comes within RETEST_TOLERANCE_PCT of the level. That is the
|
|
39
|
+
* retest bar.
|
|
40
|
+
* 4. If the retest bar's own close holds the continuation side (bullish break:
|
|
41
|
+
* close > level; bearish break: close < level) → HOLD, fire a card at that
|
|
42
|
+
* bar's close. If it closes through the wrong side → FAIL, no signal for this
|
|
43
|
+
* sequence (never re-tried).
|
|
44
|
+
* 5. Only the LATEST closed bar in the visible slice may be the fire bar (walk-
|
|
45
|
+
* forward discipline: detect() only ever asks "did the retest resolve exactly
|
|
46
|
+
* on this last bar?").
|
|
47
|
+
*
|
|
48
|
+
* Look-ahead self-test: candles beyond the fire bar are mutated; the fire decision
|
|
49
|
+
* on the slice ending at the fire bar must be unchanged. Run once at module import.
|
|
50
|
+
*/
|
|
51
|
+
import type { Candle } from "../../types.js";
|
|
52
|
+
import type { CellDetector, DetectResult } from "../accrualEmitter.js";
|
|
53
|
+
import type { CellSpec } from "../cellBacktest.js";
|
|
54
|
+
export declare const METHOD_VERSION = "kodama-structure-retest-1d-v1";
|
|
55
|
+
export declare const PERMUTATION_SEED = 777;
|
|
56
|
+
export declare const NULL_SEED = 4242;
|
|
57
|
+
export declare const FRACTAL_N = 2;
|
|
58
|
+
export declare const BREAK_PCT = 0.005;
|
|
59
|
+
export declare const RETEST_WINDOW_BARS = 10;
|
|
60
|
+
export declare const RETEST_TOLERANCE_PCT = 0.003;
|
|
61
|
+
export declare const OUTCOME_WINDOW_BARS = 10;
|
|
62
|
+
export declare const R_MULTIPLIER = 1;
|
|
63
|
+
export declare const UNIVERSE: readonly ["BTCUSDT", "ETHUSDT"];
|
|
64
|
+
/**
|
|
65
|
+
* Run on the latest CLOSED candle (candles[n-1]). Returns false if no
|
|
66
|
+
* break-and-retest-hold resolves exactly on this bar, or the card geometry
|
|
67
|
+
* if it does.
|
|
68
|
+
*
|
|
69
|
+
* @param candles Chronological 1d candles; last element = latest closed bar.
|
|
70
|
+
*/
|
|
71
|
+
export declare function detectStructureRetest(candles: Candle[]): DetectResult;
|
|
72
|
+
export declare const structureRetestDetector: CellDetector;
|
|
73
|
+
/**
|
|
74
|
+
* FAMILY_N bumps from 2 -> 3 when this cell joins the battery (per this file's
|
|
75
|
+
* own header + the pre-registered spec's familyNJustification).
|
|
76
|
+
*/
|
|
77
|
+
export declare const FAMILY_N = 3;
|
|
78
|
+
export declare const structureRetestSpec: CellSpec;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kodama-structure-retest @1d — break-and-retest structure cell.
|
|
3
|
+
*
|
|
4
|
+
* FROZEN PARAMS (pre-registered off-repo BEFORE any result was computed, at
|
|
5
|
+
* ~/.patchwork/qumo/kodama-structure-retest-spec.json; any change must bump
|
|
6
|
+
* methodVersion and reset accrual to zero, and requires a fresh spec v2):
|
|
7
|
+
*
|
|
8
|
+
* FRACTAL_N = 2 swing confirmation window (reuses src/ta/swings.ts
|
|
9
|
+
* isFractalHigh/isFractalLow — same definition as
|
|
10
|
+
* ta-cycles-1, no new swing logic invented here)
|
|
11
|
+
* BREAK_PCT = 0.005 close must clear the level by >=0.5% (close-based,
|
|
12
|
+
* filters pure wicks; a close-through is the standard
|
|
13
|
+
* textbook break definition)
|
|
14
|
+
* RETEST_WINDOW_BARS = 10 bars after the break to look for a retest touch
|
|
15
|
+
* RETEST_TOLERANCE_PCT = 0.003 retest bar's low/high must come within 0.3% of the
|
|
16
|
+
* level (tighter than the 0.5% break threshold —
|
|
17
|
+
* retest should return closer to the exact level)
|
|
18
|
+
* OUTCOME_WINDOW_BARS = 10 bars the card races before push/unscorable
|
|
19
|
+
* R_MULTIPLIER = 1.0 rRef = entry ± 1× stop-distance
|
|
20
|
+
* UNIVERSE = ["BTCUSDT", "ETHUSDT"] — the only symbols cellBacktest.ts's
|
|
21
|
+
* ALWAYS_LISTED survivorship guard currently permits; fixed
|
|
22
|
+
* BEFORE looking at any results (see spec's sample.universeJustification)
|
|
23
|
+
* METHOD_VERSION = "kodama-structure-retest-1d-v1"
|
|
24
|
+
*
|
|
25
|
+
* Hypothesis: a classic break-and-retest — price breaks a confirmed swing level,
|
|
26
|
+
* retests it, and the retest bar's own close holds the continuation side — resolves
|
|
27
|
+
* in the continuation direction at a rate greater than a matched-date random-direction
|
|
28
|
+
* null, over a fixed 10-bar forward outcome window.
|
|
29
|
+
*
|
|
30
|
+
* Fire logic (single detect() call per bar-close, walking backward from the latest
|
|
31
|
+
* closed bar to find the most recent unconsumed break+retest+hold sequence):
|
|
32
|
+
* 1. Find the most recent confirmed swing (high or low) strictly before the
|
|
33
|
+
* current bar, using detectSwings(candles, FRACTAL_N) on the visible slice.
|
|
34
|
+
* 2. Scan forward from that swing for the first bar whose CLOSE breaks the level
|
|
35
|
+
* by >= BREAK_PCT (close-based, direction depends on swing kind: a swing HIGH
|
|
36
|
+
* broken upward = bullish break; a swing LOW broken downward = bearish break).
|
|
37
|
+
* 3. Within RETEST_WINDOW_BARS bars after the break bar, find the first bar whose
|
|
38
|
+
* [low, high] comes within RETEST_TOLERANCE_PCT of the level. That is the
|
|
39
|
+
* retest bar.
|
|
40
|
+
* 4. If the retest bar's own close holds the continuation side (bullish break:
|
|
41
|
+
* close > level; bearish break: close < level) → HOLD, fire a card at that
|
|
42
|
+
* bar's close. If it closes through the wrong side → FAIL, no signal for this
|
|
43
|
+
* sequence (never re-tried).
|
|
44
|
+
* 5. Only the LATEST closed bar in the visible slice may be the fire bar (walk-
|
|
45
|
+
* forward discipline: detect() only ever asks "did the retest resolve exactly
|
|
46
|
+
* on this last bar?").
|
|
47
|
+
*
|
|
48
|
+
* Look-ahead self-test: candles beyond the fire bar are mutated; the fire decision
|
|
49
|
+
* on the slice ending at the fire bar must be unchanged. Run once at module import.
|
|
50
|
+
*/
|
|
51
|
+
import { detectSwings, isFractalHigh, isFractalLow } from "../../swings.js";
|
|
52
|
+
// ── Frozen params ─────────────────────────────────────────────────────────────
|
|
53
|
+
export const METHOD_VERSION = "kodama-structure-retest-1d-v1";
|
|
54
|
+
export const PERMUTATION_SEED = 777; // frozen — shared with cellBacktest default
|
|
55
|
+
export const NULL_SEED = 4242; // frozen — null-arm RNG seed
|
|
56
|
+
export const FRACTAL_N = 2;
|
|
57
|
+
export const BREAK_PCT = 0.005;
|
|
58
|
+
export const RETEST_WINDOW_BARS = 10;
|
|
59
|
+
export const RETEST_TOLERANCE_PCT = 0.003;
|
|
60
|
+
export const OUTCOME_WINDOW_BARS = 10;
|
|
61
|
+
export const R_MULTIPLIER = 1.0;
|
|
62
|
+
// Fixed BEFORE looking at any results — the only universe cellBacktest.ts's
|
|
63
|
+
// ALWAYS_LISTED survivorship guard currently permits. See spec's
|
|
64
|
+
// sample.universeJustification for the full rationale.
|
|
65
|
+
export const UNIVERSE = ["BTCUSDT", "ETHUSDT"];
|
|
66
|
+
// ── Detector ──────────────────────────────────────────────────────────────────
|
|
67
|
+
/**
|
|
68
|
+
* Run on the latest CLOSED candle (candles[n-1]). Returns false if no
|
|
69
|
+
* break-and-retest-hold resolves exactly on this bar, or the card geometry
|
|
70
|
+
* if it does.
|
|
71
|
+
*
|
|
72
|
+
* @param candles Chronological 1d candles; last element = latest closed bar.
|
|
73
|
+
*/
|
|
74
|
+
export function detectStructureRetest(candles) {
|
|
75
|
+
const n = candles.length;
|
|
76
|
+
if (n < FRACTAL_N * 2 + 3)
|
|
77
|
+
return false; // need room for a confirmed swing + break + retest
|
|
78
|
+
const fireIdx = n - 1; // the bar we're asking "did retest-hold resolve here?"
|
|
79
|
+
// Step 1: most recent confirmed swing strictly before fireIdx. detectSwings only
|
|
80
|
+
// returns swings confirmable within the given slice (structural no-lookahead
|
|
81
|
+
// guarantee from swings.ts), so we pass candles[0..fireIdx] (the whole visible slice)
|
|
82
|
+
// and take the LAST swing whose index is < fireIdx - well before the break.
|
|
83
|
+
const swings = detectSwings(candles, FRACTAL_N);
|
|
84
|
+
if (swings.length === 0)
|
|
85
|
+
return false;
|
|
86
|
+
// Try candidate swings from most recent backward — but only the most recent
|
|
87
|
+
// ELIGIBLE one, since retesting the same level twice from different swings
|
|
88
|
+
// would double-fire. We only accept a sequence whose retest-hold bar IS fireIdx.
|
|
89
|
+
for (let s = swings.length - 1; s >= 0; s--) {
|
|
90
|
+
const swing = swings[s];
|
|
91
|
+
const level = swing.price;
|
|
92
|
+
const isHighSwing = swing.kind === "high";
|
|
93
|
+
// Step 2: scan forward from swing.index+1 for the first break bar.
|
|
94
|
+
let breakIdx = -1;
|
|
95
|
+
let breakDirection = null;
|
|
96
|
+
for (let i = swing.index + 1; i <= fireIdx; i++) {
|
|
97
|
+
const c = candles[i];
|
|
98
|
+
if (isHighSwing && c.close > level * (1 + BREAK_PCT)) {
|
|
99
|
+
breakIdx = i;
|
|
100
|
+
breakDirection = "long"; // broke resistance upward
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (!isHighSwing && c.close < level * (1 - BREAK_PCT)) {
|
|
104
|
+
breakIdx = i;
|
|
105
|
+
breakDirection = "short"; // broke support downward
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (breakIdx === -1 || !breakDirection)
|
|
110
|
+
continue; // no break from this swing; try older swing
|
|
111
|
+
// Step 3: within RETEST_WINDOW_BARS after the break, find first retest-touch bar.
|
|
112
|
+
let retestIdx = -1;
|
|
113
|
+
const retestEnd = Math.min(breakIdx + RETEST_WINDOW_BARS, fireIdx);
|
|
114
|
+
for (let i = breakIdx + 1; i <= retestEnd; i++) {
|
|
115
|
+
const c = candles[i];
|
|
116
|
+
if (breakDirection === "long") {
|
|
117
|
+
// broken resistance now support: retest = low comes back down within tolerance
|
|
118
|
+
if (c.low <= level * (1 + RETEST_TOLERANCE_PCT)) {
|
|
119
|
+
retestIdx = i;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// broken support now resistance: retest = high comes back up within tolerance
|
|
125
|
+
if (c.high >= level * (1 - RETEST_TOLERANCE_PCT)) {
|
|
126
|
+
retestIdx = i;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (retestIdx === -1)
|
|
132
|
+
continue; // no retest within window from this swing/break; try older swing
|
|
133
|
+
// Only fire if the retest bar IS the current fire bar (walk-forward: we only
|
|
134
|
+
// ever ask about resolution happening exactly on the latest closed bar).
|
|
135
|
+
if (retestIdx !== fireIdx)
|
|
136
|
+
continue;
|
|
137
|
+
// Step 4: hold vs fail, decided by the retest bar's own close.
|
|
138
|
+
const retestBar = candles[retestIdx];
|
|
139
|
+
const holds = breakDirection === "long"
|
|
140
|
+
? retestBar.close > level
|
|
141
|
+
: retestBar.close < level;
|
|
142
|
+
if (!holds)
|
|
143
|
+
continue; // FAIL — invalidated, no signal for this sequence
|
|
144
|
+
// HOLD — fire the card.
|
|
145
|
+
if (breakDirection === "long") {
|
|
146
|
+
const stopDistance = retestBar.close - retestBar.low;
|
|
147
|
+
if (stopDistance <= 0)
|
|
148
|
+
continue;
|
|
149
|
+
return {
|
|
150
|
+
direction: "long",
|
|
151
|
+
lastClose: retestBar.close,
|
|
152
|
+
invalidation: retestBar.low,
|
|
153
|
+
rRef: retestBar.close + R_MULTIPLIER * stopDistance,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const stopDistance = retestBar.high - retestBar.close;
|
|
158
|
+
if (stopDistance <= 0)
|
|
159
|
+
continue;
|
|
160
|
+
return {
|
|
161
|
+
direction: "short",
|
|
162
|
+
lastClose: retestBar.close,
|
|
163
|
+
invalidation: retestBar.high,
|
|
164
|
+
rRef: retestBar.close - R_MULTIPLIER * stopDistance,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
// ── Look-ahead self-test (build gate, runs once at import) ────────────────────
|
|
171
|
+
/**
|
|
172
|
+
* Build a synthetic series with a clean swing-high, a break above it, and a
|
|
173
|
+
* retest that holds — all resolving exactly on the last bar. Verify the fire
|
|
174
|
+
* decision is unchanged whether or not future bars (beyond the fire bar) exist.
|
|
175
|
+
*/
|
|
176
|
+
function runLookAheadSelfTest() {
|
|
177
|
+
const BASE = 50000;
|
|
178
|
+
const LEVEL = BASE + 500; // swing high price
|
|
179
|
+
const candles = [];
|
|
180
|
+
let t = 0;
|
|
181
|
+
const push = (o, h, l, c, v = 100) => {
|
|
182
|
+
candles.push({
|
|
183
|
+
openTime: t * 86_400_000,
|
|
184
|
+
open: o,
|
|
185
|
+
high: h,
|
|
186
|
+
low: l,
|
|
187
|
+
close: c,
|
|
188
|
+
volume: v,
|
|
189
|
+
closeTime: t * 86_400_000 + 86_399_999,
|
|
190
|
+
});
|
|
191
|
+
t++;
|
|
192
|
+
};
|
|
193
|
+
// Lead-in flat bars so the swing high has FRACTAL_N bars on each side, all lower.
|
|
194
|
+
for (let i = 0; i < FRACTAL_N; i++)
|
|
195
|
+
push(BASE - 200, BASE - 100, BASE - 300, BASE - 150);
|
|
196
|
+
// The swing high bar itself.
|
|
197
|
+
const swingIdx = candles.length;
|
|
198
|
+
push(BASE, LEVEL, BASE - 100, BASE + 100);
|
|
199
|
+
// Trailing bars confirming the swing (lower highs on each side).
|
|
200
|
+
for (let i = 0; i < FRACTAL_N; i++)
|
|
201
|
+
push(BASE - 200, BASE - 100, BASE - 300, BASE - 150);
|
|
202
|
+
// A few quiet bars before the break (keeps break scan simple).
|
|
203
|
+
push(BASE - 150, BASE - 50, BASE - 250, BASE - 100);
|
|
204
|
+
// Break bar: closes above LEVEL * (1+BREAK_PCT).
|
|
205
|
+
const breakClose = LEVEL * (1 + BREAK_PCT + 0.002);
|
|
206
|
+
push(BASE, breakClose + 50, BASE - 50, breakClose);
|
|
207
|
+
// Retest bar: low comes back within tolerance of LEVEL (below LEVEL, i.e. a real
|
|
208
|
+
// touch-down), closes back above LEVEL (HOLD). low must be <= close (valid candle)
|
|
209
|
+
// and strictly below LEVEL so there's a nonzero long stop-distance.
|
|
210
|
+
const retestLow = LEVEL * (1 - RETEST_TOLERANCE_PCT + 0.0005);
|
|
211
|
+
const retestClose = LEVEL + 50;
|
|
212
|
+
push(retestClose - 20, retestClose + 30, retestLow, retestClose);
|
|
213
|
+
const fireIdx = candles.length - 1;
|
|
214
|
+
void swingIdx;
|
|
215
|
+
const baseline = detectStructureRetest(candles);
|
|
216
|
+
if (!baseline) {
|
|
217
|
+
throw new Error("kodama-structure-retest look-ahead self-test FAILED: synthetic break+retest+hold sequence did not fire — " +
|
|
218
|
+
`check BREAK_PCT (${BREAK_PCT}) / RETEST_TOLERANCE_PCT (${RETEST_TOLERANCE_PCT}) / RETEST_WINDOW_BARS (${RETEST_WINDOW_BARS})`);
|
|
219
|
+
}
|
|
220
|
+
// Append corrupted future bars (should not affect the fire decision on the slice
|
|
221
|
+
// ending at fireIdx, since detect() is called with candles.slice(0, fireIdx+1)
|
|
222
|
+
// in the real harness — but we test the raw detector directly here for the same
|
|
223
|
+
// invariant: extra trailing bars must not change the result).
|
|
224
|
+
const corrupted = candles.slice(0, fireIdx + 1);
|
|
225
|
+
for (let j = 0; j < 5; j++) {
|
|
226
|
+
corrupted.push({
|
|
227
|
+
openTime: (fireIdx + 1 + j) * 86_400_000,
|
|
228
|
+
open: BASE * 1.37,
|
|
229
|
+
high: BASE * 1.37 * 1.05,
|
|
230
|
+
low: BASE * 1.37 * 0.95,
|
|
231
|
+
close: BASE * 1.37,
|
|
232
|
+
volume: 100,
|
|
233
|
+
closeTime: (fireIdx + 1 + j) * 86_400_000 + 86_399_999,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const afterCorruption = detectStructureRetest(corrupted.slice(0, fireIdx + 1));
|
|
237
|
+
if (!afterCorruption) {
|
|
238
|
+
throw new Error("kodama-structure-retest look-ahead self-test FAILED: detector fired on baseline but not after appending future bars — this is a look-ahead leak");
|
|
239
|
+
}
|
|
240
|
+
if (afterCorruption.direction !== baseline.direction ||
|
|
241
|
+
afterCorruption.lastClose !== baseline.lastClose ||
|
|
242
|
+
afterCorruption.invalidation !== baseline.invalidation ||
|
|
243
|
+
afterCorruption.rRef !== baseline.rRef) {
|
|
244
|
+
throw new Error("kodama-structure-retest look-ahead self-test FAILED: detector result changed after appending corrupted future bars — look-ahead contamination detected");
|
|
245
|
+
}
|
|
246
|
+
// Sanity: confirm the fractal helpers agree the swing bar is indeed a confirmed high
|
|
247
|
+
// at the point it's used (defensive — catches an accidental self-test series bug).
|
|
248
|
+
if (!isFractalHigh(candles, swingIdx, FRACTAL_N) && !isFractalLow(candles, swingIdx, FRACTAL_N)) {
|
|
249
|
+
throw new Error("kodama-structure-retest look-ahead self-test FAILED: synthetic series' intended swing bar is not a confirmed fractal — test construction bug");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
runLookAheadSelfTest();
|
|
253
|
+
// ── CellDetector export ───────────────────────────────────────────────────────
|
|
254
|
+
export const structureRetestDetector = {
|
|
255
|
+
cellType: "kodama-structure-retest",
|
|
256
|
+
timeframe: "1d",
|
|
257
|
+
assets: UNIVERSE,
|
|
258
|
+
outcomeWindowBars: OUTCOME_WINDOW_BARS,
|
|
259
|
+
detect: detectStructureRetest,
|
|
260
|
+
};
|
|
261
|
+
// ── CellSpec for cellBacktest harness ─────────────────────────────────────────
|
|
262
|
+
/**
|
|
263
|
+
* FAMILY_N bumps from 2 -> 3 when this cell joins the battery (per this file's
|
|
264
|
+
* own header + the pre-registered spec's familyNJustification).
|
|
265
|
+
*/
|
|
266
|
+
export const FAMILY_N = 3; // frozen: wp-volume-climax + wp-ma-rejection + kodama-structure-retest
|
|
267
|
+
export const structureRetestSpec = {
|
|
268
|
+
cellName: "kodama-structure-retest",
|
|
269
|
+
methodVersion: METHOD_VERSION,
|
|
270
|
+
timeframe: "1d",
|
|
271
|
+
universe: UNIVERSE,
|
|
272
|
+
outcomeWindowBars: OUTCOME_WINDOW_BARS,
|
|
273
|
+
nullKind: "matched-date-dart",
|
|
274
|
+
seeds: { rng: 101, permutation: PERMUTATION_SEED, null: NULL_SEED },
|
|
275
|
+
detect: detectStructureRetest,
|
|
276
|
+
};
|
|
277
|
+
//# sourceMappingURL=structureRetest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structureRetest.js","sourceRoot":"","sources":["../../../../src/ta/desk/cells/structureRetest.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "patchwork-os",
|
|
3
|
-
"version": "1.1.0-beta.
|
|
3
|
+
"version": "1.1.0-beta.4",
|
|
4
4
|
"description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|