Add bounded six-hour adaptive probation

This commit is contained in:
Theodore Song
2026-08-22 03:02:35 -04:00
parent e3086ed5fb
commit dcede02676
9 changed files with 161 additions and 38 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
- run: node scripts/run-autonomous-cycle.mjs - run: node scripts/run-autonomous-cycle.mjs
env: env:
ARENA_URL: https://polymarket-site-eta.vercel.app ARENA_URL: https://polymarket-site-eta.vercel.app
EXPECTED_BUILD: "118" EXPECTED_BUILD: "119"
RUNTIME_BRANCH: runtime-state RUNTIME_BRANCH: runtime-state
RUNTIME_STATE_PATH: runtime/state.json RUNTIME_STATE_PATH: runtime/state.json
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+16 -11
View File
@@ -20,7 +20,7 @@ market snapshots. During an outage, cycles continue locally; cached entries are
allowed for 90 minutes, older snapshots become mark-only, and all cached data allowed for 90 minutes, older snapshots become mark-only, and all cached data
expires after 24 hours. expires after 24 hours.
Build 118 targets five-minute slots with a serialized, self-chained GitHub Actions runtime. Build 119 targets five-minute slots with a serialized, self-chained GitHub Actions runtime.
It continues from the previous agent snapshot and runs the next due paper cycle It continues from the previous agent snapshot and runs the next due paper cycle
even when no browser is open. After each successful cycle, one repo-scoped even when no browser is open. After each successful cycle, one repo-scoped
workflow dispatch waits for the next five-minute boundary; one concurrency group workflow dispatch waits for the next five-minute boundary; one concurrency group
@@ -55,7 +55,7 @@ Polymarket event key. Related Ethereum or Bitcoin contracts cannot create
several simultaneous copies of one move, and outcomes from the same underlying several simultaneous copies of one move, and outcomes from the same underlying
three-hour shock window count as one learner event. three-hour shock window count as one learner event.
Each Build 118 cycle also scans the 1,000 most-active Polymarket events for Each Build 119 cycle also scans the 1,000 most-active Polymarket events for
complete negative-risk bundles and logically nested threshold or deadline complete negative-risk bundles and logically nested threshold or deadline
pairs. Gamma's market-specific fee flag replaces the old blanket 0.5-cent fee pairs. Gamma's market-specific fee flag replaces the old blanket 0.5-cent fee
reserve for markets declared fee-free. The closest 60 structures are then reserve for markets declared fee-free. The closest 60 structures are then
@@ -74,7 +74,7 @@ The Suggestions view stores scan, depth, fee, actionable, and closest
executable-margin counts so an empty lane is evidence rather than an ambiguous executable-margin counts so an empty lane is evidence rather than an ambiguous
failure. failure.
Build 118 retains the directional learner's exact-fee policy, which replaced the blanket half-cent cost with Build 119 retains the directional learner's exact-fee policy, which replaced the blanket half-cent cost with
the market's Gamma fee schedule at both the entry and future checkpoint, plus a the market's Gamma fee schedule at both the entry and future checkpoint, plus a
separate half-cent round-trip slippage allowance. Fee-free markets pay only the separate half-cent round-trip slippage allowance. Fee-free markets pay only the
slippage allowance; an unavailable fee schedule gets a conservative four-cent slippage allowance; an unavailable fee schedule gets a conservative four-cent
@@ -85,12 +85,17 @@ available at reduced weight. The exact-fee replay covered the top 1,000
active markets and 208 independent events: broad trends, reversals, and active markets and 208 independent events: broad trends, reversals, and
favorite trends all had 90% upper bounds below zero at 12 hours. A separate favorite trends all had 90% upper bounds below zero at 12 hours. A separate
3,000-recently-closed-market study tested 297 one-decision-per-event settlement 3,000-recently-closed-market study tested 297 one-decision-per-event settlement
rules and found zero robust positive rule. Strategy 62 retains online rules and found zero robust positive rule. Strategy 63 retains online
directional evidence under fee policy 2 and keeps those lanes observation-only directional evidence under fee policy 2. A separate probation gate can now use
until current independent 24-hour and 72-hour cohorts pass the existing capital after at least 12 current-policy independent events produce a net-of-cost
promotion gate. six-hour lower confidence bound above 1% for every required cohort feature. It
uses at most 0.5% of equity per position, 1% per-agent total capital, one new
position per agent cycle, and one owner per Polymarket event across all agents.
Every probation position exits at the matching six-hour executable bid and keeps
the 18% stop policy active. Normal directional sizing remains locked until the
same cohort independently passes both the 24-hour and 72-hour promotion gates.
Build 118 retains Build 100's retirement of the old 3-6 day resolution-window Build 119 retains Build 100's retirement of the old 3-6 day resolution-window
capital permission. That audit clustered confidence by event but still averaged capital permission. That audit clustered confidence by event but still averaged
several correlated contracts inside each event, while production could choose several correlated contracts inside each event, while production could choose
only one. The corrected replay chooses the highest-volume eligible contract per event and only one. The corrected replay chooses the highest-volume eligible contract per event and
@@ -210,9 +215,9 @@ evidence proves an edge.
Run `npm run evaluate:sports-favorites` for the retired pregame favorite audit. Run `npm run evaluate:sports-favorites` for the retired pregame favorite audit.
Its 12-hour, 60%-75% cohort had positive point estimates but did not establish a Its 12-hour, 60%-75% cohort had positive point estimates but did not establish a
reliable confidence bound, so Build 118 no longer allocates capital to that rule. reliable confidence bound, so Build 119 no longer allocates capital to that rule.
Strategy 62 instead uses the exact-fee settlement calibration's three-day Sports Strategy 63 also uses the exact-fee settlement calibration's three-day Sports
NO cohort as a bounded paper exploration lane. The corrected 5,000-market run NO cohort as a bounded paper exploration lane. The corrected 5,000-market run
groups every prop with the same dated contest slug, anchors the decision to the groups every prop with the same dated contest slug, anchors the decision to the
published game start, and keeps only the highest-priced eligible NO contract per published game start, and keeps only the highest-priced eligible NO contract per
@@ -338,7 +343,7 @@ Strategy 54 gives previously opened Politics trend positions that 72-hour observ
ordinary signal exits. Stops, profit locks, settlement handling, and risk-budget ordinary signal exits. Stops, profit locks, settlement handling, and risk-budget
reductions remain immediate. reductions remain immediate.
Strategy 62 retains exact Gamma entry and exit taker fees plus a half-cent Strategy 63 retains exact Gamma entry and exit taker fees plus a half-cent
slippage allowance when grading each live walk-forward signal. Confidence uses the largest independent matching bucket, slippage allowance when grading each live walk-forward signal. Confidence uses the largest independent matching bucket,
not the sum of five overlapping feature buckets, and evidence from older engine not the sum of five overlapping feature buckets, and evidence from older engine
versions is down-weighted. This prevents a handful of duplicated observations versions is down-weighted. This prevents a handful of duplicated observations
+1
View File
@@ -285,6 +285,7 @@ export function compactSuggestion(s) {
momentum_strength: s.momentum_strength, signal_strength: s.signal_strength, signal_confidence: s.signal_confidence, momentum_strength: s.momentum_strength, signal_strength: s.signal_strength, signal_confidence: s.signal_confidence,
signal_type: s.signal_type, trade_ready: s.trade_ready, entry_candidate: s.entry_candidate, signal_type: s.signal_type, trade_ready: s.trade_ready, entry_candidate: s.entry_candidate,
audited_observation_only: s.audited_observation_only, adaptive_promotion: s.adaptive_promotion, audited_observation_only: s.audited_observation_only, adaptive_promotion: s.adaptive_promotion,
adaptive_probation: s.adaptive_probation, probation_exit_hours: s.probation_exit_hours,
promoted_for_agents: s.promoted_for_agents, promoted_for_agents: s.promoted_for_agents,
watch_only: s.watch_only, jump_risk: s.jump_risk, requires_live: s.requires_live, watch_only: s.watch_only, jump_risk: s.jump_risk, requires_live: s.requires_live,
bundle_id: s.bundle_id, bundle_side: s.bundle_side, bundle_logic: s.bundle_logic, bundle_cost_per_unit: s.bundle_cost_per_unit, bundle_id: s.bundle_id, bundle_side: s.bundle_side, bundle_logic: s.bundle_logic, bundle_cost_per_unit: s.bundle_cost_per_unit,
+119 -22
View File
@@ -341,7 +341,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
<nav class="topnav"> <nav class="topnav">
<div class="brand"> <div class="brand">
<div class="logo">🏆</div> <div class="logo">🏆</div>
<div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 62 · verified-capacity bundles · build 118</div></div> <div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 63 · six-hour probation · build 119</div></div>
</div> </div>
<div class="tabs" id="tabs"> <div class="tabs" id="tabs">
<button class="tab" data-tab="overview">Overview</button> <button class="tab" data-tab="overview">Overview</button>
@@ -363,7 +363,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
<div class="personal-banner" id="personalBanner"> <div class="personal-banner" id="personalBanner">
<b>Personal research mode.</b> This copy is for your own analysis, paper tracking, and manual trade research only. It does not pool money, onboard investors, custody funds, bypass eligibility rules, or place orders without your manual approval. <b>Personal research mode.</b> This copy is for your own analysis, paper tracking, and manual trade research only. It does not pool money, onboard investors, custody funds, bypass eligibility rules, or place orders without your manual approval.
</div> </div>
<div class="live-build-banner"><b>Build 118 active:</b> The public paper agents target five-minute slots with one serialized, self-chained GitHub Actions successor after every successful cycle and cron as recovery. The server preserves oldest-first pending evidence, exact fee schedules, agent promotion scopes, and bundle execution diagnostics from the already-bounded runtime snapshot, so cloud restarts and offline cycles do not silently lose learning context. Each fresh cloud browser reconstructs a bounded offline cache from the shared suggestions and open positions, allowing 90-minute cached entries and 24-hour mark-only continuity without persisting private account data; live-depth bundles still require a live connection. Each live cycle scans the 500 most-active eligible markets and 1,000 most-active events. Complete bundles are repriced across every ask level to the largest equal-leg quantity that remains profitable, depth-covered, fee-verified, and below $400, then portfolio sizing applies the agent's tighter cash and 4% caps. Strategy 62 also keeps the bounded sports-contest NO exploration lane under forward promotion or suspension. Intact guaranteed bundles are conservatively held at cost in portfolio accounting, while modeled profit remains unbooked until settlement. Phones and computers display the same read-only autonomous state. Profits are not guaranteed.</div> <div class="live-build-banner"><b>Build 119 active:</b> Strategy 63 adds a six-hour adaptive probation lane so independently positive current-policy cohorts can begin bounded paper trading on the same day instead of waiting for the full multi-day gate. Probation requires at least 12 independent events and a net-of-cost lower confidence bound above 1% for every required feature, uses at most 0.5% per position and 1% per-agent total capital, deduplicates events across agents, and exits at the matching six-hour executable price. Full directional sizing still requires positive 24-hour and 72-hour evidence, while one mature negative cohort can veto risk. The public agents continue serialized five-minute cycles, restart-safe offline execution from fresh cached state, the bounded sports-contest NO exploration lane, and depth-and-fee-verified complete bundles. Phones and computers display the same read-only autonomous state. Profits are not guaranteed.</div>
<!-- ============ OVERVIEW ============ --> <!-- ============ OVERVIEW ============ -->
<section class="tabpanel" data-tab="overview"> <section class="tabpanel" data-tab="overview">
@@ -745,7 +745,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
</section> </section>
<footer> <footer>
Build 118 · Adaptive strategy 62 · Serialized self-chained five-minute slots with cron recovery · Oldest-first bounded learning transport · Restart-safe offline runtime · Exact-fee directional learning · Verified-capacity complete bundles · Conservative intact-bundle accounting · Contest-deduplicated sports exploration · Corrected one-decision-per-event settlement audit · Autonomous runtime 2 · Offline runtime 3 · Maker research 3 · Agent learning 3 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice · Build 119 · Adaptive strategy 63 · Six-hour bounded probation with matched executable exits · Serialized self-chained five-minute slots with cron recovery · Oldest-first bounded learning transport · Restart-safe offline runtime · Exact-fee directional learning · Verified-capacity complete bundles · Conservative intact-bundle accounting · Contest-deduplicated sports exploration · Corrected one-decision-per-event settlement audit · Autonomous runtime 2 · Offline runtime 3 · Maker research 3 · Agent learning 3 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice ·
<a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a> <a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a>
</footer> </footer>
</div> </div>
@@ -774,17 +774,17 @@ const POLITICS_TREND_MIN_HOLD_HOURS = 72;
const EXIT_CONFIRM_HOURS = 6; const EXIT_CONFIRM_HOURS = 6;
const AGENTS_KEY = "pma_agents_v2"; const AGENTS_KEY = "pma_agents_v2";
const SUG_KEY = "pma_suggestions_v5"; const SUG_KEY = "pma_suggestions_v5";
const BUILD_VERSION = 118; const BUILD_VERSION = 119;
const AGENT_LEARNING_VERSION = 3; const AGENT_LEARNING_VERSION = 3;
const SUGGESTION_ENGINE_VERSION = 62; const SUGGESTION_ENGINE_VERSION = 63;
const MAKER_STRATEGY_VERSION = 3; const MAKER_STRATEGY_VERSION = 3;
const SHOCK_FADE_STRATEGY_VERSION = 4; const SHOCK_FADE_STRATEGY_VERSION = 4;
const RESOLUTION_WEEK_NO_STRATEGY_VERSION = 3; const RESOLUTION_WEEK_NO_STRATEGY_VERSION = 3;
const SPORTS_CONTEST_NO_STRATEGY_VERSION = 1; const SPORTS_CONTEST_NO_STRATEGY_VERSION = 1;
const PREVIOUS_STRATEGY_VERSION = 61; const PREVIOUS_STRATEGY_VERSION = 62;
const DIRECTIONAL_SIGNAL_POLICY_VERSION = 2; const DIRECTIONAL_SIGNAL_POLICY_VERSION = 2;
const DIRECTIONAL_SIGNAL_COMPATIBLE_STRATEGY_MIN = 51; const DIRECTIONAL_SIGNAL_COMPATIBLE_STRATEGY_MIN = 51;
const DIRECTIONAL_SIGNAL_COMPATIBLE_STRATEGY_MAX = 62; const DIRECTIONAL_SIGNAL_COMPATIBLE_STRATEGY_MAX = 63;
const LEGACY_BUILD_STRATEGY_LINEAGE = Object.freeze({40:40,41:40}); const LEGACY_BUILD_STRATEGY_LINEAGE = Object.freeze({40:40,41:40});
function normalizedStrategyVersion(value){ function normalizedStrategyVersion(value){
const version=Number(value||0); const version=Number(value||0);
@@ -939,6 +939,12 @@ const PRICE_REQUEST_TIMEOUT_MS = 4000;
const SIGNAL_EARLY_RISK_HORIZONS = Object.freeze([6]); const SIGNAL_EARLY_RISK_HORIZONS = Object.freeze([6]);
const SIGNAL_PROMOTION_HORIZONS = Object.freeze([24,72]); const SIGNAL_PROMOTION_HORIZONS = Object.freeze([24,72]);
const SIGNAL_EVAL_HORIZONS = Object.freeze([...SIGNAL_EARLY_RISK_HORIZONS,...SIGNAL_PROMOTION_HORIZONS]); const SIGNAL_EVAL_HORIZONS = Object.freeze([...SIGNAL_EARLY_RISK_HORIZONS,...SIGNAL_PROMOTION_HORIZONS]);
const DIRECTIONAL_PROBATION_HORIZON_HOURS = 6;
const DIRECTIONAL_PROBATION_MIN_EVENTS = 12;
const DIRECTIONAL_PROBATION_MIN_LOWER_BOUND = 0.01;
const DIRECTIONAL_PROBATION_POSITION_PCT = 0.005;
const DIRECTIONAL_PROBATION_TOTAL_CAPITAL_PCT = 0.01;
const DIRECTIONAL_PROBATION_MAX_NEW_PER_AGENT_CYCLE = 1;
const SIGNAL_EVAL_TOLERANCE_HOURS = 6; const SIGNAL_EVAL_TOLERANCE_HOURS = 6;
const SIGNAL_EVAL_HOURS = SIGNAL_EVAL_HORIZONS[0]; const SIGNAL_EVAL_HOURS = SIGNAL_EVAL_HORIZONS[0];
const SIGNAL_LEDGER_PENDING_LIMIT = 600; const SIGNAL_LEDGER_PENDING_LIMIT = 600;
@@ -1965,7 +1971,8 @@ function compactSuggestionForSync(s){
spread:s.spread,price_change_1h:s.price_change_1h,price_change_1d:s.price_change_1d,price_change_1w:s.price_change_1w,momentum_strength:s.momentum_strength, spread:s.spread,price_change_1h:s.price_change_1h,price_change_1d:s.price_change_1d,price_change_1w:s.price_change_1w,momentum_strength:s.momentum_strength,
signal_strength:s.signal_strength,signal_confidence:s.signal_confidence,signal_type:s.signal_type, signal_strength:s.signal_strength,signal_confidence:s.signal_confidence,signal_type:s.signal_type,
trade_ready:s.trade_ready,entry_candidate:s.entry_candidate,audited_observation_only:s.audited_observation_only, trade_ready:s.trade_ready,entry_candidate:s.entry_candidate,audited_observation_only:s.audited_observation_only,
adaptive_promotion:s.adaptive_promotion,promoted_for_agents:s.promoted_for_agents,watch_only:s.watch_only,jump_risk:s.jump_risk, adaptive_promotion:s.adaptive_promotion,adaptive_probation:s.adaptive_probation,
probation_exit_hours:s.probation_exit_hours,promoted_for_agents:s.promoted_for_agents,watch_only:s.watch_only,jump_risk:s.jump_risk,
requires_live:s.requires_live,bundle_id:s.bundle_id,bundle_side:s.bundle_side,bundle_logic:s.bundle_logic,bundle_cost_per_unit:s.bundle_cost_per_unit, requires_live:s.requires_live,bundle_id:s.bundle_id,bundle_side:s.bundle_side,bundle_logic:s.bundle_logic,bundle_cost_per_unit:s.bundle_cost_per_unit,
bundle_payout_per_unit:s.bundle_payout_per_unit,bundle_net_profit_per_unit:s.bundle_net_profit_per_unit,bundle_legs:s.bundle_legs, bundle_payout_per_unit:s.bundle_payout_per_unit,bundle_net_profit_per_unit:s.bundle_net_profit_per_unit,bundle_legs:s.bundle_legs,
depth_verified:s.depth_verified,fees_verified:s.fees_verified,fee_model:s.fee_model,execution_model:s.execution_model, depth_verified:s.depth_verified,fees_verified:s.fees_verified,fee_model:s.fee_model,execution_model:s.execution_model,
@@ -3102,16 +3109,31 @@ function historicalPromotionMet(historical,calibrationModel){
return Number(row&&row.weight||0)>=8&&Number(row&&row.current_weight||0)>=5&&Number(row&&row.lower_bound||0)>0.003; return Number(row&&row.weight||0)>=8&&Number(row&&row.current_weight||0)>=5&&Number(row&&row.lower_bound||0)>0.003;
})); }));
} }
function historicalProbationMet(historical,calibrationModel){
const buckets=calibrationModel&&calibrationModel.buckets||{};
if(!historical.requiresPromotion)return false;
return historical.requiredPromotionFeatures.every(key=>{
const row=buckets[`${key}|horizon:${DIRECTIONAL_PROBATION_HORIZON_HOURS}`];
return Number(row&&row.weight||0)>=DIRECTIONAL_PROBATION_MIN_EVENTS
&&Number(row&&row.current_weight||0)>=DIRECTIONAL_PROBATION_MIN_EVENTS
&&Number(row&&row.lower_bound||0)>DIRECTIONAL_PROBATION_MIN_LOWER_BOUND;
});
}
function applyAdaptiveMarketPromotion(s,calibrationModel){ function applyAdaptiveMarketPromotion(s,calibrationModel){
if(!s||s.trade_ready||!s.entry_candidate)return s; if(!s||s.trade_ready||!s.entry_candidate)return s;
const historical=historicalOpportunityPrior(s); const historical=historicalOpportunityPrior(s);
if(historical.hardBlocked||!historical.requiresPromotion||!historicalPromotionMet(historical,calibrationModel))return s; if(historical.hardBlocked||!historical.requiresPromotion)return s;
return Object.assign({},s,{trade_ready:true,watch_only:false,audited_observation_only:false,adaptive_promotion:true, if(historicalPromotionMet(historical,calibrationModel))return Object.assign({},s,{trade_ready:true,watch_only:false,audited_observation_only:false,adaptive_promotion:true,
rationale:`Adaptive promotion: this ${s.signal_type||"signal"} remained observation-only until its recent independent cohorts accumulated enough positive net-of-cost evidence. ${s.rationale||""}`}); adaptive_probation:false,probation_exit_hours:null,
rationale:`Adaptive promotion: this ${s.signal_type||"signal"} remained observation-only until its recent independent cohorts accumulated enough positive net-of-cost evidence at both full promotion horizons. ${s.rationale||""}`});
if(!historicalProbationMet(historical,calibrationModel))return s;
return Object.assign({},s,{trade_ready:true,watch_only:false,audited_observation_only:false,adaptive_promotion:false,
adaptive_probation:true,probation_exit_hours:DIRECTIONAL_PROBATION_HORIZON_HOURS,
rationale:`Six-hour adaptive probation: at least ${DIRECTIONAL_PROBATION_MIN_EVENTS} independent current-policy events cleared a ${(DIRECTIONAL_PROBATION_MIN_LOWER_BOUND*100).toFixed(1)}% lower confidence bound after costs for every required cohort feature. Paper size is capped at ${(DIRECTIONAL_PROBATION_POSITION_PCT*100).toFixed(1)}% with a matching executable ${DIRECTIONAL_PROBATION_HORIZON_HOURS}-hour exit; normal sizing still requires positive 24-hour and 72-hour evidence. ${s.rationale||""}`});
} }
function directionalObservationBase(s){ function directionalObservationBase(s){
if(!s||!["trend","reversal"].includes(s.signal_type||""))return s; if(!s||!["trend","reversal"].includes(s.signal_type||""))return s;
return Object.assign({},s,{trade_ready:false,watch_only:true,adaptive_promotion:false}); return Object.assign({},s,{trade_ready:false,watch_only:true,adaptive_promotion:false,adaptive_probation:false,probation_exit_hours:null});
} }
function prepareSuggestionForAgent(s,cfg,calibrationModel){ function prepareSuggestionForAgent(s,cfg,calibrationModel){
const base=directionalObservationBase(s); const base=directionalObservationBase(s);
@@ -3144,6 +3166,7 @@ function learnedOpportunity(cfg,p,s,profile=null,calibration=null){
const calibrationModel=calibration||{samples:0,buckets:{}},market=calibratedOpportunity(s,calibrationModel); const calibrationModel=calibration||{samples:0,buckets:{}},market=calibratedOpportunity(s,calibrationModel);
const historical=historicalOpportunityPrior(s); const historical=historicalOpportunityPrior(s);
const historicalProofMet=historicalPromotionMet(historical,calibrationModel); const historicalProofMet=historicalPromotionMet(historical,calibrationModel);
const probationProofMet=Boolean(s&&s.adaptive_probation)&&historicalProbationMet(historical,calibrationModel);
const positiveRows=rows.filter(r=>Number(r.weight||0)>=6&&Number(r.lower_bound||0)>0.005); const positiveRows=rows.filter(r=>Number(r.weight||0)>=6&&Number(r.lower_bound||0)>0.005);
const negativeRows=rows.filter(r=>Number(r.weight||0)>=6&&Number(r.upper_bound||0)<-0.01); const negativeRows=rows.filter(r=>Number(r.weight||0)>=6&&Number(r.upper_bound||0)<-0.01);
const personalPromoted=positiveRows.length>=2&&negativeRows.length===0; const personalPromoted=positiveRows.length>=2&&negativeRows.length===0;
@@ -3152,7 +3175,7 @@ function learnedOpportunity(cfg,p,s,profile=null,calibration=null){
:(personalBlocked?negativeRows.reduce((sum,r)=>sum+Number(r.upper_bound||0),0)/negativeRows.length:score*0.10); :(personalBlocked?negativeRows.reduce((sum,r)=>sum+Number(r.upper_bound||0),0)/negativeRows.length:score*0.10);
let blockedBy=null,blocked=false; let blockedBy=null,blocked=false;
if(historical.hardBlocked){blockedBy="historical";blocked=true;} if(historical.hardBlocked){blockedBy="historical";blocked=true;}
else if(historical.requiresPromotion&&!historicalProofMet){blockedBy="historical";blocked=true;} else if(historical.requiresPromotion&&!historicalProofMet&&!probationProofMet){blockedBy="historical";blocked=true;}
else if(historical.blocked&&!historical.requiresPromotion&&!exploration){blockedBy="historical";blocked=true;} else if(historical.blocked&&!historical.requiresPromotion&&!exploration){blockedBy="historical";blocked=true;}
else if(personalBlocked&&!exploration){blockedBy="personal";blocked=true;} else if(personalBlocked&&!exploration){blockedBy="personal";blocked=true;}
else if(!market.allowed&&!exploration){blockedBy="walk-forward";blocked=true;} else if(!market.allowed&&!exploration){blockedBy="walk-forward";blocked=true;}
@@ -3160,6 +3183,7 @@ function learnedOpportunity(cfg,p,s,profile=null,calibration=null){
personal_state:personalPromoted?"promoted":(personalBlocked?"demoted":"observing"),market_state:market.state, personal_state:personalPromoted?"promoted":(personalBlocked?"demoted":"observing"),market_state:market.state,
historical_score:historical.score,historical_confidence:historical.confidence,historical_features:historical.features, historical_score:historical.score,historical_confidence:historical.confidence,historical_features:historical.features,
historical_requires_promotion:Boolean(historical.requiresPromotion),historical_proof_met:Boolean(historicalProofMet), historical_requires_promotion:Boolean(historical.requiresPromotion),historical_proof_met:Boolean(historicalProofMet),
probation_proof_met:Boolean(probationProofMet),
multiplier:+clamp((1+personalEvidence*2.4)*market.multiplier*historical.multiplier,0.65,1.30).toFixed(3), multiplier:+clamp((1+personalEvidence*2.4)*market.multiplier*historical.multiplier,0.65,1.30).toFixed(3),
exploration,allowed:!blocked,blocked_by:blocked?blockedBy:null,features}; exploration,allowed:!blocked,blocked_by:blocked?blockedBy:null,features};
} }
@@ -3453,6 +3477,20 @@ function markToMarket(p,priceMap,cfg=null,{policyExits=false,executeTrades=true}
pos.peak_price=+Math.max(Number(pos.peak_price||pos.entry_price||price),price).toFixed(4); pos.peak_price=+Math.max(Number(pos.peak_price||pos.entry_price||price),price).toFixed(4);
if(executeTrades)delete pos.price_status;else pos.price_status="cached-mark-only"; if(executeTrades)delete pos.price_status;else pos.price_status="cached-mark-only";
if(!executeTrades){stillOpen.push(pos);continue;} if(!executeTrades){stillOpen.push(pos);continue;}
if(pos.adaptive_probation){
if(marketIsSettled(fresh)){closePosition(p,pos,"Adaptive probation market settled before its timed exit","CLOSE");continue;}
for(const stopTier of triggeredStopLosses(pos))scaleStopLossPosition(p,pos,stopTier);
if(pos._closedByStop){delete pos._closedByStop;continue;}
for(const gainTier of triggeredGainStops(pos))takeProfitPosition(p,pos,gainTier);
const targetHours=Math.max(1,Number(pos.probation_exit_hours||DIRECTIONAL_PROBATION_HORIZON_HOURS));
if(hoursSince(pos.opened_at)<targetHours){stillOpen.push(pos);continue;}
const executableExit=shockFadeExecutableExit(fresh,pos.side);
if(executableExit>0&&executableExit<1){
pos.current_price=+executableExit.toFixed(4);pos.value=+(pos.shares*executableExit).toFixed(2);pos.unrealized_pnl=+(pos.value-pos.cost).toFixed(2);
closePosition(p,pos,`Fixed ${targetHours}h adaptive-probation exit at executable book price`,"EXIT");continue;
}
pos.price_status="awaiting-probation-executable-exit";stillOpen.push(pos);continue;
}
if(pos.signal_type==="resolution-week-no-pilot"){ if(pos.signal_type==="resolution-week-no-pilot"){
if(marketIsSettled(fresh)){closePosition(p,pos,"Resolution-window contract settled","CLOSE");continue;} if(marketIsSettled(fresh)){closePosition(p,pos,"Resolution-window contract settled","CLOSE");continue;}
if(marketIsSuspended(fresh))pos.price_status="orders-paused-awaiting-settlement"; if(marketIsSuspended(fresh))pos.price_status="orders-paused-awaiting-settlement";
@@ -4017,7 +4055,7 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
const pilotProfile=d.sportsFavoritePilot||sportsFavoritePilotProfile(p); const pilotProfile=d.sportsFavoritePilot||sportsFavoritePilotProfile(p);
const shockProfile=d.shockFadePilot||shockFadePilotProfile(p); const shockProfile=d.shockFadePilot||shockFadePilotProfile(p);
const resolutionProfile=d.resolutionWeekNoPilot||resolutionWeekNoPilotProfile(p); const resolutionProfile=d.resolutionWeekNoPilot||resolutionWeekNoPilotProfile(p);
const heldEventKeys=new Set([...(p.positions||[]),...(p.closed||[]).filter(pos=>["sports-contest-no-pilot","shock-fade-pilot","resolution-week-no-pilot"].includes(pos.signal_type)), const heldEventKeys=new Set([...(p.positions||[]),...(p.closed||[]).filter(pos=>pos.adaptive_probation||["sports-contest-no-pilot","shock-fade-pilot","resolution-week-no-pilot"].includes(pos.signal_type)),
...(p.sports_favorite_outcomes||[]).filter(pos=>Number(pos.sports_contest_strategy_version||0)===SPORTS_CONTEST_NO_STRATEGY_VERSION),...(p.shock_fade_outcomes||[])] ...(p.sports_favorite_outcomes||[]).filter(pos=>Number(pos.sports_contest_strategy_version||0)===SPORTS_CONTEST_NO_STRATEGY_VERSION),...(p.shock_fade_outcomes||[])]
.map(pos=>String(pos.event_key||"")).filter(Boolean)); .map(pos=>String(pos.event_key||"")).filter(Boolean));
const heldShockClaims=new Set([ const heldShockClaims=new Set([
@@ -4092,6 +4130,15 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
if(focus!=="All"&&focus&&s.category!==focus)return reject("focus"); if(focus!=="All"&&focus&&s.category!==focus)return reject("focus");
return true; return true;
} }
if(s.adaptive_probation){
const eventKey=String(s.event_key||s.event||s.market_id||"");
if(!eventKey||heldEventKeys.has(eventKey))return reject("event_overlap");
if(Number(s.conviction||0)<d.minConv)return reject("confidence");
if(hasPosition(p,s.market_id))return reject("already_held");
if(hasRecentStop(p,s.market_id))return reject("cooldown");
if(focus!=="All"&&focus&&s.category!==focus)return reject("focus");
return true;
}
if(s.side!=="YES"&&s.side!=="NO")return reject("direction"); if(s.side!=="YES"&&s.side!=="NO")return reject("direction");
if((cfg.aggressive?s.conviction:s.peer_conviction)<d.minConv||s.conviction<58)return reject("confidence"); if((cfg.aggressive?s.conviction:s.peer_conviction)<d.minConv||s.conviction<58)return reject("confidence");
if(s.entry_price<0.08||s.entry_price>0.92)return reject("price"); if(s.entry_price<0.08||s.entry_price>0.92)return reject("price");
@@ -4109,7 +4156,7 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
return true; return true;
}) })
.sort((a,b)=>((b.peer_conviction*b.learning_multiplier)-(a.peer_conviction*a.learning_multiplier))||((b.peer_boost||0)-(a.peer_boost||0))); .sort((a,b)=>((b.peer_conviction*b.learning_multiplier)-(a.peer_conviction*a.learning_multiplier))||((b.peer_boost||0)-(a.peer_boost||0)));
let opened=0,openedIds=[],openedSports=0,openedShock=0,openedResolutionWeek=0; let opened=0,openedIds=[],openedSports=0,openedShock=0,openedResolutionWeek=0,openedProbation=0;
let cycleBudgetRemaining=eqBefore*(cfg.aggressive?0.14:0.10); let cycleBudgetRemaining=eqBefore*(cfg.aggressive?0.14:0.10);
for(const s of cands){ for(const s of cands){
if(opened>=d.maxNew)break; if(opened>=d.maxNew)break;
@@ -4117,6 +4164,7 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
if(s.signal_type==="sports-contest-no-pilot"&&openedSports>=SPORTS_FAVORITE_MAX_NEW_PER_CYCLE)continue; if(s.signal_type==="sports-contest-no-pilot"&&openedSports>=SPORTS_FAVORITE_MAX_NEW_PER_CYCLE)continue;
if(s.signal_type==="shock-fade-pilot"&&openedShock>=SHOCK_FADE_MAX_NEW_PER_AGENT_CYCLE)continue; if(s.signal_type==="shock-fade-pilot"&&openedShock>=SHOCK_FADE_MAX_NEW_PER_AGENT_CYCLE)continue;
if(s.signal_type==="resolution-week-no-pilot"&&openedResolutionWeek>=RESOLUTION_WEEK_NO_MAX_NEW_PER_AGENT_CYCLE)continue; if(s.signal_type==="resolution-week-no-pilot"&&openedResolutionWeek>=RESOLUTION_WEEK_NO_MAX_NEW_PER_AGENT_CYCLE)continue;
if(s.adaptive_probation&&openedProbation>=DIRECTIONAL_PROBATION_MAX_NEW_PER_AGENT_CYCLE)continue;
const eq=equity(p); const eq=equity(p);
const positionValue=(p.positions||[]).reduce((sum,pos)=>sum+Number(pos.value||pos.shares*pos.current_price||0),0); const positionValue=(p.positions||[]).reduce((sum,pos)=>sum+Number(pos.value||pos.shares*pos.current_price||0),0);
const exposureGap=Math.max(0,eq*targetExposure-positionValue); const exposureGap=Math.max(0,eq*targetExposure-positionValue);
@@ -4133,14 +4181,17 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
if(["sports-contest-no-pilot","resolution-week-no-pilot"].includes(s.signal_type)&&heldEventKeys.has(String(s.event_key||s.event||s.market_id||"")))continue; if(["sports-contest-no-pilot","resolution-week-no-pilot"].includes(s.signal_type)&&heldEventKeys.has(String(s.event_key||s.event||s.market_id||"")))continue;
if(s.signal_type==="shock-fade-pilot"&&shockFadeClaimKeys(s).some(key=>heldShockClaims.has(key)))continue; if(s.signal_type==="shock-fade-pilot"&&shockFadeClaimKeys(s).some(key=>heldShockClaims.has(key)))continue;
let frac; let frac;
if(s.signal_type==="sports-contest-no-pilot"){frac=Math.min(d.maxFrac,Number(pilotProfile.position_pct||0));} if(s.adaptive_probation){frac=Math.min(d.maxFrac,DIRECTIONAL_PROBATION_POSITION_PCT);}
else if(s.signal_type==="sports-contest-no-pilot"){frac=Math.min(d.maxFrac,Number(pilotProfile.position_pct||0));}
else if(s.signal_type==="shock-fade-pilot"){frac=Math.min(d.maxFrac,Number(shockProfile.position_pct||0));} else if(s.signal_type==="shock-fade-pilot"){frac=Math.min(d.maxFrac,Number(shockProfile.position_pct||0));}
else if(s.signal_type==="resolution-week-no-pilot"){frac=Math.min(d.maxFrac,Number(resolutionProfile.position_pct||0));} else if(s.signal_type==="resolution-week-no-pilot"){frac=Math.min(d.maxFrac,Number(resolutionProfile.position_pct||0));}
else if(cfg.flat){frac=d.maxFrac;} else if(cfg.flat){frac=d.maxFrac;}
else{const base=(s.peer_conviction/100)*Math.min(1,effectiveEntryEdge(s)/EDGE_SCALE);frac=Math.min(d.maxFrac,cfg.kelly*base);} else{const base=(s.peer_conviction/100)*Math.min(1,effectiveEntryEdge(s)/EDGE_SCALE);frac=Math.min(d.maxFrac,cfg.kelly*base);}
if(s.peer_boost<0)frac*=0.82; if(!s.adaptive_probation){
frac*=peerEvidenceSizeMultiplier(s); if(s.peer_boost<0)frac*=0.82;
frac*=Number(s.learning_multiplier||1); frac*=peerEvidenceSizeMultiplier(s);
frac*=Number(s.learning_multiplier||1);
}
let stake=Math.min(eq*frac,investable); let stake=Math.min(eq*frac,investable);
const riskBudgetPct=tradeLossBudgetPct(cfg,s); const riskBudgetPct=tradeLossBudgetPct(cfg,s);
stake=boundedStakeForRisk(eq,stake,cfg,s); stake=boundedStakeForRisk(eq,stake,cfg,s);
@@ -4156,6 +4207,10 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
const pilotValue=(p.positions||[]).filter(pos=>pos.signal_type==="resolution-week-no-pilot").reduce((sum,pos)=>sum+Number(pos.value||0),0); const pilotValue=(p.positions||[]).filter(pos=>pos.signal_type==="resolution-week-no-pilot").reduce((sum,pos)=>sum+Number(pos.value||0),0);
stake=Math.min(stake,Math.max(0,eq*RESOLUTION_WEEK_NO_TOTAL_CAPITAL_PCT-pilotValue)); stake=Math.min(stake,Math.max(0,eq*RESOLUTION_WEEK_NO_TOTAL_CAPITAL_PCT-pilotValue));
} }
if(s.adaptive_probation){
const probationValue=(p.positions||[]).filter(pos=>pos.adaptive_probation).reduce((sum,pos)=>sum+Number(pos.value||0),0);
stake=Math.min(stake,Math.max(0,eq*DIRECTIONAL_PROBATION_TOTAL_CAPITAL_PCT-probationValue));
}
const categoryValue=(p.positions||[]).filter(pos=>(pos.category||"Other")===(s.category||"Other")).reduce((sum,pos)=>sum+Number(pos.value||0),0); const categoryValue=(p.positions||[]).filter(pos=>(pos.category||"Other")===(s.category||"Other")).reduce((sum,pos)=>sum+Number(pos.value||0),0);
stake=Math.min(stake,Math.max(0,eq*categoryCap-categoryValue)); stake=Math.min(stake,Math.max(0,eq*categoryCap-categoryValue));
if(stake<50)continue; if(stake<50)continue;
@@ -4178,16 +4233,20 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
target_horizon_days:s.target_horizon_days, target_horizon_days:s.target_horizon_days,
sports_contest_strategy_version:s.sports_contest_strategy_version, sports_contest_strategy_version:s.sports_contest_strategy_version,
shock_move_1h:s.shock_move_1h,shock_prior_move_1h:s.shock_prior_move_1h,shock_move_3h:s.shock_move_3h,shock_strategy_version:s.shock_strategy_version, shock_move_1h:s.shock_move_1h,shock_prior_move_1h:s.shock_prior_move_1h,shock_move_3h:s.shock_move_3h,shock_strategy_version:s.shock_strategy_version,
target_exit_at:s.signal_type==="shock-fade-pilot"?new Date(new Date(cycleIso()).getTime()+SHOCK_FADE_EXIT_HOURS*3600000).toISOString():(s.signal_type==="resolution-week-no-pilot"?s.end_date:null), target_exit_at:s.signal_type==="shock-fade-pilot"?new Date(new Date(cycleIso()).getTime()+SHOCK_FADE_EXIT_HOURS*3600000).toISOString()
:(s.adaptive_probation?new Date(new Date(cycleIso()).getTime()+Number(s.probation_exit_hours||DIRECTIONAL_PROBATION_HORIZON_HOURS)*3600000).toISOString():(s.signal_type==="resolution-week-no-pilot"?s.end_date:null)),
resolution_week_strategy_version:s.resolution_week_strategy_version, resolution_week_strategy_version:s.resolution_week_strategy_version,
learning_score:s.learning_score,learning_confidence:s.learning_confidence,market_learning_score:s.market_learning_score,market_learning_confidence:s.market_learning_confidence, learning_score:s.learning_score,learning_confidence:s.learning_confidence,market_learning_score:s.market_learning_score,market_learning_confidence:s.market_learning_confidence,
learning_state:s.learning_state,market_learning_state:s.market_learning_state, learning_state:s.learning_state,market_learning_state:s.market_learning_state,
historical_prior_score:s.historical_prior_score,historical_prior_confidence:s.historical_prior_confidence,historical_prior_features:s.historical_prior_features, historical_prior_score:s.historical_prior_score,historical_prior_confidence:s.historical_prior_confidence,historical_prior_features:s.historical_prior_features,
historical_requires_promotion:Boolean(s.historical_requires_promotion), historical_requires_promotion:Boolean(s.historical_requires_promotion),
adaptive_probation:Boolean(s.adaptive_probation),probation_exit_hours:s.adaptive_probation?Number(s.probation_exit_hours||DIRECTIONAL_PROBATION_HORIZON_HOURS):null,
learning_multiplier:s.learning_multiplier,learning_exploration:s.learning_exploration, learning_multiplier:s.learning_multiplier,learning_exploration:s.learning_exploration,
risk_budget_pct:+(riskBudgetPct*100).toFixed(2), risk_budget_pct:+(riskBudgetPct*100).toFixed(2),
peak_price:+entry.toFixed(4),gain_stops:{},stop_losses:{}}); peak_price:+entry.toFixed(4),gain_stops:{},stop_losses:{}});
const openDetail=s.signal_type==="sports-contest-no-pilot" const openDetail=s.adaptive_probation
?`${decision?decision.mode+" mode — ":""}Six-hour adaptive probation bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ modeled ${pct(entry)} for ${fmtUSD(cost)} · capped at ${(DIRECTIONAL_PROBATION_POSITION_PCT*100).toFixed(1)}% · one decision for event ${s.event_key||s.market_id} · fixed executable exit in ${Number(s.probation_exit_hours||DIRECTIONAL_PROBATION_HORIZON_HOURS)}h · full sizing still locked behind 24h and 72h proof`
:s.signal_type==="sports-contest-no-pilot"
?`${decision?decision.mode+" mode — ":""}Bounded sports-contest exploration bought ${shares} NO '${s.question.slice(0,40)}' @ modeled ${pct(entry)} for ${fmtUSD(cost)} (${pct(Number(s.market_price||entry))} midpoint + ${((entry-Number(s.market_price||entry))*100).toFixed(2)}c exact-fee execution cost) · one position for contest ${s.event_key||s.market_id} · learner state ${pilotProfile.state} · ${(Number(s.hours_to_start)||0).toFixed(1)}h before start` ?`${decision?decision.mode+" mode — ":""}Bounded sports-contest exploration bought ${shares} NO '${s.question.slice(0,40)}' @ modeled ${pct(entry)} for ${fmtUSD(cost)} (${pct(Number(s.market_price||entry))} midpoint + ${((entry-Number(s.market_price||entry))*100).toFixed(2)}c exact-fee execution cost) · one position for contest ${s.event_key||s.market_id} · learner state ${pilotProfile.state} · ${(Number(s.hours_to_start)||0).toFixed(1)}h before start`
:s.signal_type==="shock-fade-pilot" :s.signal_type==="shock-fade-pilot"
?`${decision?decision.mode+" mode — ":""}${shockProfile.promoted?"Forward-promoted":"Forward-qualified"} ${SHOCK_FADE_EXIT_HOURS}-hour shock fade bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ executable modeled ${pct(entry)} for ${fmtUSD(cost)} after a ${(Number(s.shock_move_3h||0)*100).toFixed(2)}-point move · learner state ${shockProfile.state} · fixed executable exit target in ${SHOCK_FADE_EXIT_HOURS}h` ?`${decision?decision.mode+" mode — ":""}${shockProfile.promoted?"Forward-promoted":"Forward-qualified"} ${SHOCK_FADE_EXIT_HOURS}-hour shock fade bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ executable modeled ${pct(entry)} for ${fmtUSD(cost)} after a ${(Number(s.shock_move_3h||0)*100).toFixed(2)}-point move · learner state ${shockProfile.state} · fixed executable exit target in ${SHOCK_FADE_EXIT_HOURS}h`
@@ -4197,6 +4256,7 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
p.history.push({date:logDay(),action:"OPEN",question:s.question,side:s.side,detail:openDetail}); p.history.push({date:logDay(),action:"OPEN",question:s.question,side:s.side,detail:openDetail});
if(s.signal_type==="sports-contest-no-pilot"){heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));openedSports++;} if(s.signal_type==="sports-contest-no-pilot"){heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));openedSports++;}
if(s.signal_type==="resolution-week-no-pilot"){heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));openedResolutionWeek++;} if(s.signal_type==="resolution-week-no-pilot"){heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));openedResolutionWeek++;}
if(s.adaptive_probation){heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));openedProbation++;}
if(s.signal_type==="shock-fade-pilot")shockFadeClaimKeys(s).forEach(key=>heldShockClaims.add(key)); if(s.signal_type==="shock-fade-pilot")shockFadeClaimKeys(s).forEach(key=>heldShockClaims.add(key));
if(s.signal_type==="shock-fade-pilot")openedShock++; if(s.signal_type==="shock-fade-pilot")openedShock++;
opened++;openedIds.push(String(s.market_id)); opened++;openedIds.push(String(s.market_id));
@@ -4428,6 +4488,9 @@ async function runDailyCycle(){
const claimedMarkets=new Set(); const claimedMarkets=new Set();
const claimedShockEvents=currentShockClaimKeys(st); const claimedShockEvents=currentShockClaimKeys(st);
const claimedResolutionWeekEvents=currentResolutionWeekEventKeys(st); const claimedResolutionWeekEvents=currentResolutionWeekEventKeys(st);
const claimedProbationEvents=new Set(AGENTS.flatMap(agent=>[
...(st.agents[agent.id].positions||[]),...(st.agents[agent.id].closed||[]),
]).filter(row=>row.adaptive_probation).map(row=>String(row.event_key||row.market_id)));
const globalMakerMarkets=new Set(AGENTS.flatMap(agent=>[ const globalMakerMarkets=new Set(AGENTS.flatMap(agent=>[
...(st.agents[agent.id].maker_quotes||[]).map(quote=>String(quote.market_id)), ...(st.agents[agent.id].maker_quotes||[]).map(quote=>String(quote.market_id)),
...(st.agents[agent.id].positions||[]).filter(pos=>pos.signal_type==="maker-pair").map(pos=>String(pos.market_id)), ...(st.agents[agent.id].positions||[]).filter(pos=>pos.signal_type==="maker-pair").map(pos=>String(pos.market_id)),
@@ -4450,7 +4513,11 @@ async function runDailyCycle(){
||!shockFadeClaimKeys(s).some(key=>claimedShockEvents.has(key))); ||!shockFadeClaimKeys(s).some(key=>claimedShockEvents.has(key)));
agentCycleSuggestions=agentCycleSuggestions.filter(s=>s.signal_type!=="resolution-week-no-pilot" agentCycleSuggestions=agentCycleSuggestions.filter(s=>s.signal_type!=="resolution-week-no-pilot"
||!claimedResolutionWeekEvents.has(String(s.event_key||s.market_id))); ||!claimedResolutionWeekEvents.has(String(s.event_key||s.market_id)));
agentCycleSuggestions=agentCycleSuggestions.filter(s=>!s.adaptive_probation
||!claimedProbationEvents.has(String(s.event_key||s.market_id)));
openPositions(p,cfg,rankSuggestionsForAgent(cfg,agentCycleSuggestions),focus,decision,occupied,peerMarketStats(st,cfg.id)).forEach(id=>claimedMarkets.add(id)); openPositions(p,cfg,rankSuggestionsForAgent(cfg,agentCycleSuggestions),focus,decision,occupied,peerMarketStats(st,cfg.id)).forEach(id=>claimedMarkets.add(id));
(p.positions||[]).filter(row=>row.adaptive_probation)
.forEach(row=>claimedProbationEvents.add(String(row.event_key||row.market_id)));
(p.positions||[]).filter(row=>row.signal_type==="resolution-week-no-pilot" (p.positions||[]).filter(row=>row.signal_type==="resolution-week-no-pilot"
&&Number(row.resolution_week_strategy_version||0)===RESOLUTION_WEEK_NO_STRATEGY_VERSION) &&Number(row.resolution_week_strategy_version||0)===RESOLUTION_WEEK_NO_STRATEGY_VERSION)
.forEach(row=>claimedResolutionWeekEvents.add(String(row.event_key||row.market_id))); .forEach(row=>claimedResolutionWeekEvents.add(String(row.event_key||row.market_id)));
@@ -4696,7 +4763,7 @@ function decisionSummary(p){
const currentText=hasCurrentCounts?`${ml.current_samples||0} observations / ${ml.current_events} events`:`${ml.current_samples||0} observations; independent-event count unavailable`; const currentText=hasCurrentCounts?`${ml.current_samples||0} observations / ${ml.current_events} events`:`${ml.current_samples||0} observations; independent-event count unavailable`;
const learningScope=ml.agent_id?`${agentById(ml.agent_id).name}'s eligible strategy universe`:"the shared research universe"; const learningScope=ml.agent_id?`${agentById(ml.agent_id).name}'s eligible strategy universe`:"the shared research universe";
const queueAudit=Number.isFinite(ml.pending_global)?` Queue audit: ${ml.pending_legacy||0} legacy shared + ${ml.pending_agent_scoped||0} tagged for this agent; ${ml.pending_scoped||0} strategy-tagged and ${ml.pending_unassigned||0} unassigned across ${ml.pending_global||0} global pending records.`:""; const queueAudit=Number.isFinite(ml.pending_global)?` Queue audit: ${ml.pending_legacy||0} legacy shared + ${ml.pending_agent_scoped||0} tagged for this agent; ${ml.pending_scoped||0} strategy-tagged and ${ml.pending_unassigned||0} unassigned across ${ml.pending_global||0} global pending records.`:"";
calibration=` Walk-forward calibration for ${learningScope}: ${ml.samples||0} net-of-cost checkpoint observations ${countText}, graded at ${SIGNAL_EARLY_RISK_HORIZONS.join("h, ")}h for early loss vetoes and ${SIGNAL_PROMOTION_HORIZONS.join("h and ")}h for promotion (${currentText} under directional signal policy ${ml.policy_version||DIRECTIONAL_SIGNAL_POLICY_VERSION}), ${ml.pending||0} awaiting a future checkpoint${ml.expired_ungraded?`, ${ml.expired_ungraded} expired checkpoints`:""}.${queueAudit} ${ml.promoted_buckets||0} horizon-specific feature cohorts promoted and ${ml.demoted_buckets||0} demoted. Promotion requires positive compatible-policy evidence at both promotion horizons across independent events; one mature negative cohort at any checkpoint can veto risk. Each agent studies a broader strategy-specific research universe before the stricter capital-entry gate is applied, while unlabeled legacy evidence remains readable. Sports pilots and priced bundles stay outside directional calibration. Missed windows expire rather than borrowing a later price. New observations prioritize under-sampled signal/side/category cohorts and independent events before repeats. Correlated outcome markets in one event count as one effective outcome. Historical prior: every directional trend and reversal remains observation-only until its exact recent cohorts independently promote; settlement-jump barriers stay excluded.`; calibration=` Walk-forward calibration for ${learningScope}: ${ml.samples||0} net-of-cost checkpoint observations ${countText}, graded at ${SIGNAL_EARLY_RISK_HORIZONS.join("h, ")}h for early loss vetoes and bounded same-horizon probation, then ${SIGNAL_PROMOTION_HORIZONS.join("h and ")}h for full promotion (${currentText} under directional signal policy ${ml.policy_version||DIRECTIONAL_SIGNAL_POLICY_VERSION}), ${ml.pending||0} awaiting a future checkpoint${ml.expired_ungraded?`, ${ml.expired_ungraded} expired checkpoints`:""}.${queueAudit} ${ml.promoted_buckets||0} horizon-specific feature cohorts promoted and ${ml.demoted_buckets||0} demoted. Six-hour probation requires ${DIRECTIONAL_PROBATION_MIN_EVENTS} independent current-policy events and a lower confidence bound above ${(DIRECTIONAL_PROBATION_MIN_LOWER_BOUND*100).toFixed(1)}% for every required feature, then uses at most ${(DIRECTIONAL_PROBATION_POSITION_PCT*100).toFixed(1)}% paper size with a matching timed executable exit. Full promotion still requires positive compatible-policy evidence at both promotion horizons; one mature negative cohort at any checkpoint can veto risk. Each agent studies a broader strategy-specific research universe before the stricter capital-entry gate is applied, while unlabeled legacy evidence remains readable. Sports pilots and priced bundles stay outside directional calibration. Missed windows expire rather than borrowing a later price. New observations prioritize under-sampled signal/side/category cohorts and independent events before repeats. Correlated outcome markets in one event count as one effective outcome. Historical prior: every directional trend and reversal remains observation-only until its exact recent cohorts independently qualify; settlement-jump barriers stay excluded.`;
} }
const makerStats=d.makerProfile&&d.makerProfile.global; const makerStats=d.makerProfile&&d.makerProfile.global;
const maker=d.makerQuotes!=null?` Maker research: ${d.makerShadowActive||0} zero-capital lock-or-exit observations active; ${d.makerFills||0} verified touches and ${d.makerShadowCompleted||0} outcomes completed this cycle.${makerStats?` Event-clustered ledger: ${makerStats.attempts} attempts / ${makerStats.events} events, ${makerStats.locked} locked pairs, ${makerStats.adverse} immediate adverse exits, ${makerStats.unfilled} unfilled, and ${fmtUSD(makerStats.shadow_pnl)} simulated shadow net.`:""} Capital is disabled because neither the 6,048-rule chronological maker audit nor the reward stress test produced a validated holdout winner. Hypothetical rewards are excluded.`:""; const maker=d.makerQuotes!=null?` Maker research: ${d.makerShadowActive||0} zero-capital lock-or-exit observations active; ${d.makerFills||0} verified touches and ${d.makerShadowCompleted||0} outcomes completed this cycle.${makerStats?` Event-clustered ledger: ${makerStats.attempts} attempts / ${makerStats.events} events, ${makerStats.locked} locked pairs, ${makerStats.adverse} immediate adverse exits, ${makerStats.unfilled} unfilled, and ${fmtUSD(makerStats.shadow_pnl)} simulated shadow net.`:""} Capital is disabled because neither the 6,048-rule chronological maker audit nor the reward stress test produced a validated holdout winner. Hypothetical rewards are excluded.`:"";
@@ -6385,6 +6452,10 @@ window.PMA_ENGINE_DIAGNOSTICS=Object.freeze({
makerCompetitionSource:"shared public CLOB order-book audit",makerResearchSharedAcrossAgents:true,makerMarketsPartitionedAcrossAgents:true, makerCompetitionSource:"shared public CLOB order-book audit",makerResearchSharedAcrossAgents:true,makerMarketsPartitionedAcrossAgents:true,
makerHistoryRequestsBatched:true,makerPromotionCohorts:["category","spread","reward-yield"],makerRewardPayoutMinimum:1, makerHistoryRequestsBatched:true,makerPromotionCohorts:["category","spread","reward-yield"],makerRewardPayoutMinimum:1,
emotionCanIncreaseSize:false,dualPromotionPeerBoostPct:5,currentStrategyOnlyCapitalAdaptation:true, emotionCanIncreaseSize:false,dualPromotionPeerBoostPct:5,currentStrategyOnlyCapitalAdaptation:true,
directionalProbation:{horizonHours:DIRECTIONAL_PROBATION_HORIZON_HOURS,minIndependentEvents:DIRECTIONAL_PROBATION_MIN_EVENTS,
minimumLowerBoundPct:DIRECTIONAL_PROBATION_MIN_LOWER_BOUND*100,positionPct:DIRECTIONAL_PROBATION_POSITION_PCT*100,
totalCapitalPct:DIRECTIONAL_PROBATION_TOTAL_CAPITAL_PCT*100,maxNewPerAgentCycle:DIRECTIONAL_PROBATION_MAX_NEW_PER_AGENT_CYCLE,
eventDeduplicatedAcrossAgents:true,fullSizingStillRequiresHorizons:SIGNAL_PROMOTION_HORIZONS},
favoriteTrendReplayHardBlock:true, favoriteTrendReplayHardBlock:true,
sportsFavoritePilot:{name:"sports-contest-NO-exploration",strategyVersion:SPORTS_CONTEST_NO_STRATEGY_VERSION,entryBand:[SPORTS_FAVORITE_MIN_ENTRY,SPORTS_FAVORITE_MAX_ENTRY],targetLeadHours:SPORTS_FAVORITE_TARGET_LEAD_HOURS, sportsFavoritePilot:{name:"sports-contest-NO-exploration",strategyVersion:SPORTS_CONTEST_NO_STRATEGY_VERSION,entryBand:[SPORTS_FAVORITE_MIN_ENTRY,SPORTS_FAVORITE_MAX_ENTRY],targetLeadHours:SPORTS_FAVORITE_TARGET_LEAD_HOURS,
leadToleranceHours:SPORTS_FAVORITE_LEAD_TOLERANCE_HOURS,pilotPositionPct:SPORTS_FAVORITE_PILOT_POSITION_PCT*100, leadToleranceHours:SPORTS_FAVORITE_LEAD_TOLERANCE_HOURS,pilotPositionPct:SPORTS_FAVORITE_PILOT_POSITION_PCT*100,
@@ -6774,6 +6845,20 @@ function runEngineSelfTest(){
const stablePositiveProfile=calibrationFromReturns(Array(24).fill(0.12)); const stablePositiveProfile=calibrationFromReturns(Array(24).fill(0.12));
const stablePositiveCalibration=calibratedOpportunity(calibrationCandidate,stablePositiveProfile); const stablePositiveCalibration=calibratedOpportunity(calibrationCandidate,stablePositiveProfile);
const promotedTrendSuggestion=applyAdaptiveMarketPromotion(Object.assign({},trend,{entry_candidate:true}),stablePositiveProfile); const promotedTrendSuggestion=applyAdaptiveMarketPromotion(Object.assign({},trend,{entry_candidate:true}),stablePositiveProfile);
const probationProfile=calibrationFromReturns(Array(24).fill(0.12),calibrationCandidate,[DIRECTIONAL_PROBATION_HORIZON_HOURS]);
const probationCandidate=Object.assign({},trend,{market_id:"probation-market",event_key:"probation-event",entry_candidate:true,
quality:"confirmed",signal_type:"trend",signal_strength:0.80,signal_confidence:0.80,evidence_score:0.80,
net_edge:0.04,entry_price:0.42,market_price:0.42,conviction:82,days_to_resolution:45});
const probationSuggestion=applyAdaptiveMarketPromotion(probationCandidate,probationProfile);
const probationOpportunity=learnedOpportunity(agentById("diversifier"),defaultPortfolio(),probationSuggestion,null,probationProfile);
const probationDecision={minConv:0,maxNew:1,maxFrac:0.05,reserve:0.10,targetExposure:0.60,
learning:buildAdaptiveProfile(defaultPortfolio()),marketLearning:probationProfile};
const openProbationBook=()=>{const book=defaultPortfolio();openPositions(book,agentById("diversifier"),[probationSuggestion],"All",probationDecision,new Set(),{});return book;};
const probationOpenBook=openProbationBook(),probationCompacted=compactSuggestionForSync(probationSuggestion);
const earlyProbationBook=openProbationBook();earlyProbationBook.positions[0].opened_at=hoursAgo(5);
markToMarket(earlyProbationBook,{"probation-market":market({id:"probation-market",yes_price:0.46,no_price:0.54,best_bid:0.455,best_ask:0.465})},agentById("diversifier"),{policyExits:true,executeTrades:true});
const timedProbationBook=openProbationBook();timedProbationBook.positions[0].opened_at=hoursAgo(7);
markToMarket(timedProbationBook,{"probation-market":market({id:"probation-market",yes_price:0.46,no_price:0.54,best_bid:0.455,best_ask:0.465})},agentById("diversifier"),{policyExits:true,executeTrades:true});
const favoriteTrendCandidate=Object.assign({},trend,{market_id:"favorite-trend-replay-block",entry_candidate:true,entry_price:0.62, const favoriteTrendCandidate=Object.assign({},trend,{market_id:"favorite-trend-replay-block",entry_candidate:true,entry_price:0.62,
category:"Politics",side:"YES",signal_type:"trend",quality:"confirmed"}); category:"Politics",side:"YES",signal_type:"trend",quality:"confirmed"});
const blockedFavoriteTrendPromotion=applyAdaptiveMarketPromotion(favoriteTrendCandidate,stablePositiveProfile); const blockedFavoriteTrendPromotion=applyAdaptiveMarketPromotion(favoriteTrendCandidate,stablePositiveProfile);
@@ -7235,6 +7320,18 @@ function runEngineSelfTest(){
&&!oldCountReport.includes("across 0 event clusters"), &&!oldCountReport.includes("across 0 event clusters"),
broadTrendStartsObservationOnly:!trend.trade_ready&&trend.entry_candidate&&trend.audited_observation_only, broadTrendStartsObservationOnly:!trend.trade_ready&&trend.entry_candidate&&trend.audited_observation_only,
recentProofCanUnlockTrend:promotedTrendSuggestion.trade_ready&&promotedTrendSuggestion.adaptive_promotion, recentProofCanUnlockTrend:promotedTrendSuggestion.trade_ready&&promotedTrendSuggestion.adaptive_promotion,
sixHourEvidenceStartsBoundedProbation:probationSuggestion.trade_ready&&probationSuggestion.adaptive_probation
&&!probationSuggestion.adaptive_promotion&&probationSuggestion.probation_exit_hours===DIRECTIONAL_PROBATION_HORIZON_HOURS
&&probationOpportunity.allowed&&probationOpportunity.probation_proof_met,
probationUsesHalfPercentPaperCap:probationOpenBook.positions.length===1&&probationOpenBook.positions[0].adaptive_probation
&&probationOpenBook.positions[0].cost<=STARTING_BALANCE*DIRECTIONAL_PROBATION_POSITION_PCT+0.01,
probationMetadataSurvivesOfflineCompaction:probationCompacted.adaptive_probation===true
&&probationCompacted.probation_exit_hours===DIRECTIONAL_PROBATION_HORIZON_HOURS,
probationWaitsForMatchingHorizon:earlyProbationBook.positions.length===1&&earlyProbationBook.closed.length===0,
probationExitsAtExecutableSixHourPrice:timedProbationBook.positions.length===0&&timedProbationBook.closed.length===1
&&timedProbationBook.closed[0].close_reason.includes("adaptive-probation exit"),
sixHourEvidenceCannotGrantFullPromotion:!probationSuggestion.adaptive_promotion
&&calibratedOpportunity(probationCandidate,probationProfile).state==="observing",
replayLosingFavoriteTrendCannotPromote:!blockedFavoriteTrendPromotion.trade_ready replayLosingFavoriteTrendCannotPromote:!blockedFavoriteTrendPromotion.trade_ready
&&!blockedFavoriteTrendOpportunity.allowed&&blockedFavoriteTrendOpportunity.blocked_by==="historical", &&!blockedFavoriteTrendOpportunity.allowed&&blockedFavoriteTrendOpportunity.blocked_by==="historical",
observationsRecordStrategyEligibility:Array.isArray(observationLedgerState.signal_ledger.pending[0].eligible_agent_ids) observationsRecordStrategyEligibility:Array.isArray(observationLedgerState.signal_ledger.pending[0].eligible_agent_ids)
+1 -1
View File
@@ -131,7 +131,7 @@ async function main() {
const branch = process.env.RUNTIME_BRANCH || "runtime-state"; const branch = process.env.RUNTIME_BRANCH || "runtime-state";
const pathname = process.env.RUNTIME_STATE_PATH || "runtime/state.json"; const pathname = process.env.RUNTIME_STATE_PATH || "runtime/state.json";
const arenaUrl = (process.env.ARENA_URL || "https://polymarket-site-eta.vercel.app").replace(/\/$/, ""); const arenaUrl = (process.env.ARENA_URL || "https://polymarket-site-eta.vercel.app").replace(/\/$/, "");
const expectedBuild = Number(required("EXPECTED_BUILD", "118")); const expectedBuild = Number(required("EXPECTED_BUILD", "119"));
await ensureRuntimeBranch(repository, branch); await ensureRuntimeBranch(repository, branch);
const prior = await readRuntimeFile(repository, branch, pathname); const prior = await readRuntimeFile(repository, branch, pathname);
if (prior.snapshot) validateRuntimeSnapshot(prior.snapshot, 0, { allowIncomplete: true }); if (prior.snapshot) validateRuntimeSnapshot(prior.snapshot, 0, { allowIncomplete: true });
+9 -2
View File
@@ -10,7 +10,7 @@ const resolutionAudit = JSON.parse(fs.readFileSync(new URL("../research/resoluti
const sportsContestAudit = JSON.parse(fs.readFileSync(new URL("../research/sports-contest-no-exploration-audit.json", import.meta.url), "utf8")); const sportsContestAudit = JSON.parse(fs.readFileSync(new URL("../research/sports-contest-no-exploration-audit.json", import.meta.url), "utf8"));
const build = Number(index.match(/const BUILD_VERSION = (\d+);/)?.[1]); const build = Number(index.match(/const BUILD_VERSION = (\d+);/)?.[1]);
assert.equal(build, 118); assert.equal(build, 119);
assert.deepEqual([...ALLOWED_RUNTIME_KEYS].sort(), ["pma_agents_v2", "pma_suggestions_v5"]); assert.deepEqual([...ALLOWED_RUNTIME_KEYS].sort(), ["pma_agents_v2", "pma_suggestions_v5"]);
assert.match(index, /function collectPublicRuntimeItems\(\)/); assert.match(index, /function collectPublicRuntimeItems\(\)/);
assert.match(index, /const PUBLIC_RUNTIME_KEYS=Object\.freeze\(\[AGENTS_KEY,SUG_KEY\]\)/); assert.match(index, /const PUBLIC_RUNTIME_KEYS=Object\.freeze\(\[AGENTS_KEY,SUG_KEY\]\)/);
@@ -30,6 +30,13 @@ assert.match(index, /reservedCount=Math\.min\(PUBLIC_SIGNAL_OUTCOME_RESERVE,outc
assert.match(index, /return fitPublicRuntimeSnapshot\(snapshot\)/); assert.match(index, /return fitPublicRuntimeSnapshot\(snapshot\)/);
assert.match(index, /publicCompactionPreservesForwardGrading:/); assert.match(index, /publicCompactionPreservesForwardGrading:/);
assert.match(index, /publicCompactionPreservesAgentCalibration:/); assert.match(index, /publicCompactionPreservesAgentCalibration:/);
assert.match(index, /const DIRECTIONAL_PROBATION_HORIZON_HOURS = 6;/);
assert.match(index, /const DIRECTIONAL_PROBATION_MIN_EVENTS = 12;/);
assert.match(index, /sixHourEvidenceStartsBoundedProbation:/);
assert.match(index, /probationMetadataSurvivesOfflineCompaction:/);
assert.match(index, /probationExitsAtExecutableSixHourPrice:/);
assert.match(index, /claimedProbationEvents/);
assert.match(api, /adaptive_probation: s\.adaptive_probation, probation_exit_hours: s\.probation_exit_hours/);
assert.match(index, /function buildRuntimeFallbackMarketCache\(stored,state\)/); assert.match(index, /function buildRuntimeFallbackMarketCache\(stored,state\)/);
assert.match(index, /buildRuntimeFallbackMarketCache\(stored,st\)/); assert.match(index, /buildRuntimeFallbackMarketCache\(stored,st\)/);
assert.match(index, /window\.PMA_AUTOMATION=Object\.freeze/); assert.match(index, /window\.PMA_AUTOMATION=Object\.freeze/);
@@ -44,7 +51,7 @@ assert.match(api, /Buffer\.from\(file\.content/);
assert.match(api, /searchParams\.set\("runtime", `\$\{Date\.now\(\)\}/); assert.match(api, /searchParams\.set\("runtime", `\$\{Date\.now\(\)\}/);
assert.match(workflow, /cron: "2,7,12,17,22,27,32,37,42,47,52,57 \* \* \* \*"/); assert.match(workflow, /cron: "2,7,12,17,22,27,32,37,42,47,52,57 \* \* \* \*"/);
assert.match(workflow, /contents: write/); assert.match(workflow, /contents: write/);
assert.match(workflow, /EXPECTED_BUILD: "118"/); assert.match(workflow, /EXPECTED_BUILD: "119"/);
assert.match(workflow, /actions: write/); assert.match(workflow, /actions: write/);
assert.match(workflow, /cancel-in-progress: false/); assert.match(workflow, /cancel-in-progress: false/);
assert.match(workflow, /next=\$\(\( \(now \/ 300 \+ 1\) \* 300 \+ 15 \)\)/); assert.match(workflow, /next=\$\(\( \(now \/ 300 \+ 1\) \* 300 \+ 15 \)\)/);
+3
View File
@@ -17,5 +17,8 @@ assert.match(worker, /"\/cycle-worker\.js"/);
assert.match(cycleWorker, /const INTERVAL_MS = 60000;/); assert.match(cycleWorker, /const INTERVAL_MS = 60000;/);
assert.match(index, /requires_live:true/); assert.match(index, /requires_live:true/);
assert.match(index, /runMode==="live"\|\|!next\.requires_live/); assert.match(index, /runMode==="live"\|\|!next\.requires_live/);
assert.match(index, /adaptive_probation:s\.adaptive_probation/);
assert.match(index, /probation_exit_hours:s\.probation_exit_hours/);
assert.match(index, /awaiting-probation-executable-exit/);
console.log(`offline runtime verified for Build ${build}`); console.log(`offline runtime verified for Build ${build}`);
+10
View File
@@ -9,6 +9,7 @@ assert.equal(normalizeDatabaseUrl("DATABASE_URL=postgresql://user:pass@example.t
"postgresql://user:pass@example.test/db"); "postgresql://user:pass@example.test/db");
assert.equal(cycleVersion("2026-08-21T20|v59"), 59); assert.equal(cycleVersion("2026-08-21T20|v59"), 59);
assert.equal(cycleVersion("2026-08-21T20:05|s62"), 62); assert.equal(cycleVersion("2026-08-21T20:05|s62"), 62);
assert.equal(cycleVersion("2026-08-21T20:05|s63"), 63);
assert.equal(cycleVersion("2026-08-21T20:05"), 0); assert.equal(cycleVersion("2026-08-21T20:05"), 0);
const originalDatabaseUrl = process.env.DATABASE_URL; const originalDatabaseUrl = process.env.DATABASE_URL;
@@ -62,6 +63,15 @@ assert.equal(compactedShock.shock_move_3h, 0.12);
assert.equal(compactedShock.shock_strategy_version, 3); assert.equal(compactedShock.shock_strategy_version, 3);
assert.equal(compactedShock.pilot_prior.modeled_cost_cents, 2); assert.equal(compactedShock.pilot_prior.modeled_cost_cents, 2);
const compactedProbation = compactSuggestion({
market_id: "probation:1", event_key: "event:probation", side: "YES", signal_type: "trend",
trade_ready: true, entry_candidate: true, adaptive_probation: true, probation_exit_hours: 6,
promoted_for_agents: ["momentum"], fee_schedule: { rate: 0.04, exponent: 1, takerOnly: true },
});
assert.equal(compactedProbation.adaptive_probation, true);
assert.equal(compactedProbation.probation_exit_hours, 6);
assert.deepEqual(compactedProbation.promoted_for_agents, ["momentum"]);
const compactedState = compactAgentState({ const compactedState = compactAgentState({
agents: { reversal: { agents: { reversal: {
positions: [], closed: [], history: [], snapshots: [], positions: [], closed: [], history: [], snapshots: [],
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = "polymarket-arena-build-118"; const CACHE_NAME = "polymarket-arena-build-119";
const APP_SHELL = ["/", "/index.html", "/personal.html", "/cycle-worker.js"]; const APP_SHELL = ["/", "/index.html", "/personal.html", "/cycle-worker.js"];
self.addEventListener("install", event => { self.addEventListener("install", event => {