Protect adaptive evidence in runtime snapshots

This commit is contained in:
Theodore Song
2026-08-22 04:42:05 -04:00
parent ffd3acb7d9
commit 4d4a4b6d4d
6 changed files with 104 additions and 44 deletions
@@ -1,4 +1,4 @@
name: Release Build 119 after Vercel quota reset name: Release Build 120 after Vercel quota reset
on: on:
schedule: schedule:
@@ -9,7 +9,7 @@ permissions:
contents: write contents: write
concurrency: concurrency:
group: release-build-119 group: release-build-120
cancel-in-progress: false cancel-in-progress: false
jobs: jobs:
@@ -25,36 +25,36 @@ jobs:
env: env:
ARENA_URL: https://polymarket-site-eta.vercel.app ARENA_URL: https://polymarket-site-eta.vercel.app
run: | run: |
if curl --fail --silent --show-error "${ARENA_URL}/?build_119_preflight=${GITHUB_RUN_ID}" | grep -q 'const BUILD_VERSION = 119;'; then if curl --fail --silent --show-error "${ARENA_URL}/?build_120_preflight=${GITHUB_RUN_ID}" | grep -q 'const BUILD_VERSION = 120;'; then
echo "Build 119 is already live." echo "Build 120 is already live."
exit 0 exit 0
fi fi
printf 'Build 119 deployment retry from run %s at %s\n' "$GITHUB_RUN_ID" "$(date -u +%FT%TZ)" > .build-119-release-trigger printf 'Build 120 deployment retry from run %s at %s\n' "$GITHUB_RUN_ID" "$(date -u +%FT%TZ)" > .build-120-release-trigger
git config user.name "github-actions[bot]" git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .build-119-release-trigger git add .build-120-release-trigger
git commit -m "Retry Build 119 production deployment" git commit -m "Retry Build 120 production deployment"
git push origin HEAD:main git push origin HEAD:main
- name: Wait for Build 119 in production - name: Wait for Build 120 in production
env: env:
ARENA_URL: https://polymarket-site-eta.vercel.app ARENA_URL: https://polymarket-site-eta.vercel.app
run: | run: |
for attempt in $(seq 1 40); do for attempt in $(seq 1 40); do
if curl --fail --silent --show-error "${ARENA_URL}/?build_119_wait=${GITHUB_RUN_ID}-${attempt}" | grep -q 'const BUILD_VERSION = 119;'; then if curl --fail --silent --show-error "${ARENA_URL}/?build_120_wait=${GITHUB_RUN_ID}-${attempt}" | grep -q 'const BUILD_VERSION = 120;'; then
echo "Build 119 is live." echo "Build 120 is live."
exit 0 exit 0
fi fi
sleep 30 sleep 30
done done
echo "Build 119 did not become live; Build 118 remains the autonomous runtime target." echo "Build 120 did not become live; Build 118 remains the autonomous runtime target."
exit 1 exit 1
- name: Activate the Build 119 autonomous runner - name: Activate the Build 120 autonomous runner
run: | run: |
git pull --ff-only origin main git pull --ff-only origin main
perl -0pi -e 's/EXPECTED_BUILD: "118"/EXPECTED_BUILD: "119"/' .github/workflows/autonomous-cycle.yml perl -0pi -e 's/EXPECTED_BUILD: "118"/EXPECTED_BUILD: "120"/' .github/workflows/autonomous-cycle.yml
perl -0pi -e 's/assert\.match\(workflow, \/EXPECTED_BUILD: "118"\/\);/assert.match(workflow, \/EXPECTED_BUILD: "119"\/);/' scripts/test-autonomous-runtime.mjs perl -0pi -e 's/assert\.match\(workflow, \/EXPECTED_BUILD: "118"\/\);/assert.match(workflow, \/EXPECTED_BUILD: "120"\/);/' scripts/test-autonomous-runtime.mjs
rm -f .build-119-release-trigger rm -f .build-120-release-trigger
git rm .github/workflows/release-build-119.yml git rm .github/workflows/release-build-120.yml
git add .github/workflows/autonomous-cycle.yml scripts/test-autonomous-runtime.mjs git add .github/workflows/autonomous-cycle.yml scripts/test-autonomous-runtime.mjs
git commit -m "Activate Build 119 autonomous cycles" git commit -m "Activate Build 120 autonomous cycles"
git push origin HEAD:main git push origin HEAD:main
+14 -9
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 119 targets five-minute slots with a serialized, self-chained GitHub Actions runtime. Build 120 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
@@ -32,10 +32,15 @@ contains only `pma_agents_v2` and `pma_suggestions_v5`, with suggestions capped
300 to keep cross-device loads small. The API preserves oldest-first pending 300 to keep cross-device loads small. The API preserves oldest-first pending
observations plus fee schedules, agent promotion scopes, and verified bundle observations plus fee schedules, agent promotion scopes, and verified bundle
capacity from the bounded runtime instead of applying its older lossy compactor. capacity from the bounded runtime instead of applying its older lossy compactor.
Public maker outcomes retain only calibration fields and action logs are bounded Public maker outcomes retain only calibration fields, action logs are bounded
to 80 entries per agent. If the 875 KB transport budget is reached, up to 96 of to 48 entries per agent, and chart snapshots are evenly sampled once their
the newest completed directional outcomes are reserved before the oldest 96-point public limit is reached so older dates remain represented. Repetitive
still-pending observations consume the remaining evidence space. watch-only explanations are normalized without changing signal fields. If the
875 KB transport budget is reached, the compactor first protects 75 KB for
learning, reserves up to 144 of the newest completed directional outcomes, and
then gives the remaining evidence space to the oldest still-pending
observations. Only after display history reaches its documented floor can the
public suggestion list fall from 300 to its 240-item emergency floor.
Paper accounts, passwords, email settings, Paper accounts, passwords, email settings,
investment allocations, chat history, wallet information, and live-money investment allocations, chat history, wallet information, and live-money
settings are explicitly excluded. While that fallback is active, ordinary settings are explicitly excluded. While that fallback is active, ordinary
@@ -55,7 +60,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 119 cycle also scans the 1,000 most-active Polymarket events for Each Build 120 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 +79,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 119 retains the directional learner's exact-fee policy, which replaced the blanket half-cent cost with Build 120 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
@@ -95,7 +100,7 @@ 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 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. same cohort independently passes both the 24-hour and 72-hour promotion gates.
Build 119 retains Build 100's retirement of the old 3-6 day resolution-window Build 120 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
@@ -215,7 +220,7 @@ 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 119 no longer allocates capital to that rule. reliable confidence bound, so Build 120 no longer allocates capital to that rule.
Strategy 63 also 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
+61 -13
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 63 · six-hour probation · build 119</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 · durable evidence · build 120</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 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> <div class="live-build-banner"><b>Build 120 active:</b> Strategy 63 protects a dedicated evidence budget in every cloud snapshot, so pending observations and net-of-cost outcomes survive runner restarts instead of being displaced by repeated display text. Independently positive six-hour cohorts can enter bounded probation after at least 12 events and a lower confidence bound above 1%, using at most 0.5% per position and 1% per-agent total capital with a matching executable exit. Full directional sizing still requires positive 24-hour and 72-hour evidence, while one mature negative cohort can veto risk. Chart snapshots retain bounded time coverage, the public agents continue serialized five-minute cycles and restart-safe offline operation, and intact complete bundles remain depth-and-fee verified. 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 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 · Build 120 · Adaptive strategy 63 · Evidence-first bounded snapshots · 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,7 +774,7 @@ 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 = 119; const BUILD_VERSION = 120;
const AGENT_LEARNING_VERSION = 3; const AGENT_LEARNING_VERSION = 3;
const SUGGESTION_ENGINE_VERSION = 63; const SUGGESTION_ENGINE_VERSION = 63;
const MAKER_STRATEGY_VERSION = 3; const MAKER_STRATEGY_VERSION = 3;
@@ -809,7 +809,7 @@ const CATEGORIES = ["All","Politics","Sports","Crypto","Economy","Pop Culture","
const SYNC_KEYS=[AGENTS_KEY,SUG_KEY,FOCUS_KEY,VIEW_KEY,PF_SORT_KEY,CHART_RANGE_KEY,INVEST_KEY,PAPER_KEY,LIVE_KEY,EMAIL_ALERT_KEY]; const SYNC_KEYS=[AGENTS_KEY,SUG_KEY,FOCUS_KEY,VIEW_KEY,PF_SORT_KEY,CHART_RANGE_KEY,INVEST_KEY,PAPER_KEY,LIVE_KEY,EMAIL_ALERT_KEY];
const PUBLIC_RUNTIME_KEYS=Object.freeze([AGENTS_KEY,SUG_KEY]); const PUBLIC_RUNTIME_KEYS=Object.freeze([AGENTS_KEY,SUG_KEY]);
const SYNC_LIMITS={closed:80,history:160,snapshots:240,suggestions:900,paperHistory:120,paperSnapshots:120,audit:120}; const SYNC_LIMITS={closed:80,history:160,snapshots:240,suggestions:900,paperHistory:120,paperSnapshots:120,audit:120};
const PUBLIC_RUNTIME_LIMITS=Object.freeze({...SYNC_LIMITS,history:80,suggestions:300}); const PUBLIC_RUNTIME_LIMITS=Object.freeze({...SYNC_LIMITS,history:48,snapshots:96,suggestions:300});
const CAT_COLORS = {Politics:"#fb7185",Sports:"#34d399",Crypto:"#fbbf24",Economy:"#7c8cff", const CAT_COLORS = {Politics:"#fb7185",Sports:"#34d399",Crypto:"#fbbf24",Economy:"#7c8cff",
"Pop Culture":"#c77dff",Other:"#94a1bb",All:"#7c8cff"}; "Pop Culture":"#c77dff",Other:"#94a1bb",All:"#7c8cff"};
const CLOB = "https://clob.polymarket.com"; const CLOB = "https://clob.polymarket.com";
@@ -950,7 +950,12 @@ const SIGNAL_EVAL_HOURS = SIGNAL_EVAL_HORIZONS[0];
const SIGNAL_LEDGER_PENDING_LIMIT = 600; const SIGNAL_LEDGER_PENDING_LIMIT = 600;
const SIGNAL_LEDGER_OUTCOME_LIMIT = 1000; const SIGNAL_LEDGER_OUTCOME_LIMIT = 1000;
const PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES = 875000; const PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES = 875000;
const PUBLIC_SIGNAL_OUTCOME_RESERVE = 96; const PUBLIC_SIGNAL_OUTCOME_RESERVE = 144;
const PUBLIC_SIGNAL_LEDGER_RESERVE_BYTES = 75000;
const PUBLIC_RUNTIME_HISTORY_FLOOR = 24;
const PUBLIC_RUNTIME_MAKER_OUTCOME_LIMIT = 30;
const PUBLIC_RUNTIME_MAKER_OUTCOME_FLOOR = 12;
const PUBLIC_RUNTIME_SUGGESTION_FLOOR = 240;
const SIGNAL_LEDGER_RETRY_HOURS = SIGNAL_EVAL_HORIZONS[SIGNAL_EVAL_HORIZONS.length-1]+SIGNAL_EVAL_TOLERANCE_HOURS; const SIGNAL_LEDGER_RETRY_HOURS = SIGNAL_EVAL_HORIZONS[SIGNAL_EVAL_HORIZONS.length-1]+SIGNAL_EVAL_TOLERANCE_HOURS;
const SIGNAL_LEDGER_DUE_FETCH_LIMIT = 80; const SIGNAL_LEDGER_DUE_FETCH_LIMIT = 80;
const currentCycleHour = () => {const p=partsInLocalTime();return `${p.year}-${p.month}-${p.day}T${p.hour}:${p.minute}|s${SUGGESTION_ENGINE_VERSION}`;}; const currentCycleHour = () => {const p=partsInLocalTime();return `${p.year}-${p.month}-${p.day}T${p.hour}:${p.minute}|s${SUGGESTION_ENGINE_VERSION}`;};
@@ -1952,6 +1957,23 @@ function compactDecisionForPublic(decision){
} }
return out; return out;
} }
function compactHistoryForPublic(row){
if(!row||typeof row!=="object")return row;
return {date:row.date,action:row.action,question:typeof row.question==="string"?row.question.slice(0,140):row.question,
side:row.side,detail:typeof row.detail==="string"?row.detail.slice(0,220):row.detail};
}
function compactSnapshotsForPublic(rows,limit=PUBLIC_RUNTIME_LIMITS.snapshots){
const list=Array.isArray(rows)?rows:[];
if(list.length<=limit)return list;
const recentCount=Math.min(24,limit),older=list.slice(0,-recentCount),olderSlots=limit-recentCount;
if(olderSlots<=0)return list.slice(-limit);
const sampled=[];
for(let i=0;i<olderSlots;i++){
const index=olderSlots===1?older.length-1:Math.round(i*(older.length-1)/(olderSlots-1));
if(older[index]&&sampled.at(-1)!==older[index])sampled.push(older[index]);
}
return sampled.concat(list.slice(-recentCount)).slice(-limit);
}
function compactMakerOutcomeForPublic(row){ function compactMakerOutcomeForPublic(row){
if(!row||typeof row!=="object")return row; if(!row||typeof row!=="object")return row;
return {quote_id:row.quote_id,market_id:row.market_id,event_key:row.event_key,category:row.category, return {quote_id:row.quote_id,market_id:row.market_id,event_key:row.event_key,category:row.category,
@@ -1992,10 +2014,16 @@ function compactSuggestionsForSync(payload,limits=SYNC_LIMITS){
function compactPublicSuggestionsForSync(payload){ function compactPublicSuggestionsForSync(payload){
const compact=compactSuggestionsForSync(payload,PUBLIC_RUNTIME_LIMITS); const compact=compactSuggestionsForSync(payload,PUBLIC_RUNTIME_LIMITS);
compact.suggestions=(compact.suggestions||[]).map(suggestion=>{ compact.suggestions=(compact.suggestions||[]).map(suggestion=>{
const out=Object.assign({},suggestion,{ const out=Object.assign({},suggestion);
drivers:Array.isArray(suggestion.drivers)?suggestion.drivers.slice(0,1).map(driver=>String(driver).slice(0,80)):suggestion.drivers, if(suggestion.trade_ready||suggestion.adaptive_probation||suggestion.bundle_id){
rationale:typeof suggestion.rationale==="string"?suggestion.rationale.slice(0,240):suggestion.rationale, out.drivers=Array.isArray(suggestion.drivers)?suggestion.drivers.slice(0,1).map(driver=>String(driver).slice(0,80)):[];
}); out.rationale=typeof suggestion.rationale==="string"?suggestion.rationale.slice(0,180):"Trade-ready opportunity passed the active execution gate.";
}else{
out.drivers=[];
out.rationale=suggestion.jump_risk?"Watch only: settlement-gap risk prevents a protected entry."
:(suggestion.signal_type&&suggestion.signal_type!=="none"?"Watch only: gathering independent forward evidence before capital is enabled."
:"Watch only: no independently confirmed direction yet.");
}
if(!out.trade_ready){delete out.clob_yes;delete out.clob_no;} if(!out.trade_ready){delete out.clob_yes;delete out.clob_no;}
return out; return out;
}); });
@@ -2115,11 +2143,15 @@ function prepareCycleSuggestions(suggestions,runMode,entriesAllowed){
} }
function collectSyncItems(){const items={};SYNC_KEYS.forEach(k=>{const v=localStorage.getItem(k);if(v!=null)items[k]=v;});return compactSyncItems(items);} function collectSyncItems(){const items={};SYNC_KEYS.forEach(k=>{const v=localStorage.getItem(k);if(v!=null)items[k]=v;});return compactSyncItems(items);}
function collectPublicRuntimeItems(){ function collectPublicRuntimeItems(){
const st=compactAgentStateForSync(loadState(),PUBLIC_RUNTIME_LIMITS); const sourceLimits=Object.assign({},PUBLIC_RUNTIME_LIMITS,{snapshots:SYNC_LIMITS.snapshots});
const st=compactAgentStateForSync(loadState(),sourceLimits);
st.signal_ledger=compactPublicSignalLedger(st.signal_ledger); st.signal_ledger=compactPublicSignalLedger(st.signal_ledger);
AGENTS.forEach(agent=>{if(st.agents&&st.agents[agent.id]){ AGENTS.forEach(agent=>{if(st.agents&&st.agents[agent.id]){
st.agents[agent.id].lastDecision=compactDecisionForPublic(st.agents[agent.id].lastDecision); const p=st.agents[agent.id];
st.agents[agent.id].maker_outcomes=(st.agents[agent.id].maker_outcomes||[]).map(compactMakerOutcomeForPublic); p.history=(p.history||[]).slice(-PUBLIC_RUNTIME_LIMITS.history).map(compactHistoryForPublic);
p.snapshots=compactSnapshotsForPublic(p.snapshots,PUBLIC_RUNTIME_LIMITS.snapshots);
p.lastDecision=compactDecisionForPublic(p.lastDecision);
p.maker_outcomes=(p.maker_outcomes||[]).slice(-PUBLIC_RUNTIME_MAKER_OUTCOME_LIMIT).map(compactMakerOutcomeForPublic);
}}); }});
st.pending_sync=false; st.pending_sync=false;
st.runtime_managed=true; st.runtime_managed=true;
@@ -2137,6 +2169,22 @@ function fitPublicRuntimeSnapshot(snapshot){
const writeState=()=>{snapshot.items[AGENTS_KEY]=JSON.stringify(st);return runtimeSnapshotByteLength(snapshot)<=PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES;}; const writeState=()=>{snapshot.items[AGENTS_KEY]=JSON.stringify(st);return runtimeSnapshotByteLength(snapshot)<=PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES;};
const reservedCount=Math.min(PUBLIC_SIGNAL_OUTCOME_RESERVE,outcomes.length); const reservedCount=Math.min(PUBLIC_SIGNAL_OUTCOME_RESERVE,outcomes.length);
ledger.pending=[];ledger.outcomes=reservedCount?outcomes.slice(-reservedCount):[]; ledger.pending=[];ledger.outcomes=reservedCount?outcomes.slice(-reservedCount):[];
writeState();
const nonLearningTarget=PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES-PUBLIC_SIGNAL_LEDGER_RESERVE_BYTES;
if(runtimeSnapshotByteLength(snapshot)>nonLearningTarget){
AGENTS.forEach(agent=>{const p=st.agents&&st.agents[agent.id];if(!p)return;
p.history=(p.history||[]).slice(-PUBLIC_RUNTIME_HISTORY_FLOOR);
p.maker_outcomes=(p.maker_outcomes||[]).slice(-PUBLIC_RUNTIME_MAKER_OUTCOME_FLOOR);
});
writeState();
}
if(runtimeSnapshotByteLength(snapshot)>nonLearningTarget){
try{
const suggestionState=JSON.parse(snapshot.items[SUG_KEY]);
suggestionState.suggestions=(suggestionState.suggestions||[]).slice(0,PUBLIC_RUNTIME_SUGGESTION_FLOOR);
snapshot.items[SUG_KEY]=JSON.stringify(suggestionState);
}catch(e){}
}
if(!writeState()&&reservedCount){ if(!writeState()&&reservedCount){
let low=0,high=reservedCount; let low=0,high=reservedCount;
while(low<high){ while(low<high){
+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", "119")); const expectedBuild = Number(required("EXPECTED_BUILD", "120"));
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 });
+10 -3
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, 119); assert.equal(build, 120);
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\]\)/);
@@ -21,8 +21,15 @@ assert.match(index, /if\(!out\.trade_ready\)\{delete out\.clob_yes;delete out\.c
assert.match(index, /function compactPublicSignalLedger\(ledger\)/); assert.match(index, /function compactPublicSignalLedger\(ledger\)/);
assert.match(index, /st\.signal_ledger=compactPublicSignalLedger\(st\.signal_ledger\)/); assert.match(index, /st\.signal_ledger=compactPublicSignalLedger\(st\.signal_ledger\)/);
assert.match(index, /const PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES = 875000;/); assert.match(index, /const PUBLIC_RUNTIME_SNAPSHOT_BUDGET_BYTES = 875000;/);
assert.match(index, /const PUBLIC_SIGNAL_OUTCOME_RESERVE = 96;/); assert.match(index, /const PUBLIC_SIGNAL_OUTCOME_RESERVE = 144;/);
assert.match(index, /history:80,suggestions:300/); assert.match(index, /const PUBLIC_SIGNAL_LEDGER_RESERVE_BYTES = 75000;/);
assert.match(index, /history:48,snapshots:96,suggestions:300/);
assert.match(index, /function compactHistoryForPublic\(row\)/);
assert.match(index, /function compactSnapshotsForPublic\(rows,limit=PUBLIC_RUNTIME_LIMITS\.snapshots\)/);
assert.match(index, /sourceLimits=Object\.assign\(\{\},PUBLIC_RUNTIME_LIMITS,\{snapshots:SYNC_LIMITS\.snapshots\}\)/);
assert.match(index, /PUBLIC_RUNTIME_MAKER_OUTCOME_LIMIT/);
assert.match(index, /PUBLIC_RUNTIME_HISTORY_FLOOR/);
assert.match(index, /PUBLIC_RUNTIME_SUGGESTION_FLOOR/);
assert.match(index, /function compactMakerOutcomeForPublic\(row\)/); assert.match(index, /function compactMakerOutcomeForPublic\(row\)/);
assert.match(index, /publicMakerCompactionPreservesCalibration:/); assert.match(index, /publicMakerCompactionPreservesCalibration:/);
assert.match(index, /function fitPublicRuntimeSnapshot\(snapshot\)/); assert.match(index, /function fitPublicRuntimeSnapshot\(snapshot\)/);
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = "polymarket-arena-build-119"; const CACHE_NAME = "polymarket-arena-build-120";
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 => {