Skip to content

Instantly share code, notes, and snippets.

@ericjuta
Created February 27, 2026 13:44
Show Gist options
  • Select an option

  • Save ericjuta/f3fa0914c88018e4040ffe118bd52579 to your computer and use it in GitHub Desktop.

Select an option

Save ericjuta/f3fa0914c88018e4040ffe118bd52579 to your computer and use it in GitHub Desktop.
AskGina.ai AGI mcp - egalitarian strategy workflow quant spec

Markov Event-Driven Bundles (Strategy Conveyor V1.8: Decision-Gated + Idempotent)

Status

  • This spec encodes the target strategy-conveyor model for personal sandbox deployment.
  • Seeded Markov bundles include discovery-controller/scan/signal/execution_plan/monitor.
  • Live execution is modeled as an optional adapter workflow (not seeded by default).
  • Polymarket entry actions require explicit confirmation before live calls (optional auto-unwind policy for risk-off).
  • Monitoring starts after first non-zero fill (partial or complete).
  • Event payloads are treated as uniformly typed payload envelopes.
  • Valid markov.scan.request events explicitly request markov-scan@latest.
  • markov.scan.completed explicitly requests markov-signal@latest.
  • markov.discovery.request is wired to a discovery controller workflow, which emits markov.scan.request for selected candidates (no direct discovery->scan shortcut hook).
  • Candidate fanout is capped at chain-spawn time via max_new_chains_per_run.
  • Discovery candidate handling is single-path via CandidateDecision (reject or spawn, never both).
  • Discovery filtering now includes keyword relevance and max-hours bounds.
  • Signal completion emits explicit gate fields (edge_score, cost_adjusted_edge_bps, fair_value_confidence).
  • Signal supports outcome=Auto and selects Yes or No by higher post-cost edge.
  • Signal gate now includes min_cost_adjusted_edge_bps threshold (default 5 bps).
  • Expected slippage has a dynamic component from risk-cap vs liquidity, not only static input.
  • Live execution requests transition chain state through execution_requested -> execution_in_progress.
  • Runtime-budget and slippage/retry breach paths fail fast to markov.execution.failed + markov.chain.error.
  • Schedule gating enforces is_enabled, expires_at, and max_executions before discovery emission.
  • Risk allocation uses max-loss basis with per-chain RiskReservation ledger (active/released).
  • markov.execution.unwind.request is now wired to start the execution workflow.
  • Execution requests are validated against stored ExecutionApproval records, not only payload claims.
  • Approval expiry handling releases reserved risk and marks chain execution_approval_expired.
  • Stage transitions now include explicit prior-state guards and idempotency preconditions.
  • ChainError.chain_id is nullable for malformed payload paths.
  • Scan/monitor orderbook calls are token-ID-first (getPredictionOrderbook.tokenId) with market metadata fallback resolution.
  • Numeric/text metric extraction is key-scoped during deep traversal, preventing token IDs from being misread as market metrics.

Strategy Model

A strategy is the root policy object, not a single market and not a single run.

Lineage:

  • strategy_id -> long-lived policy (discovery, signal, risk, execution, monitoring, learning)
  • scheduled_run_id -> one recurring tick of that strategy
  • chain_id -> one market/outcome chain from that run (strategy_id + run_id + market_id + outcome)

Chain ID canonicalization:

  • chain_id = lower(trim(strategy_id)) + ":" + lower(trim(scheduled_run_id)) + ":" + lower(trim(market_id)) + ":" + lower(trim(outcome))
  • Delimiter is fixed (:) and all parts must be lowercased/trimmed before composition.

Objective and Reflection

Primary optimizer target:

  • Sharpe ratio (risk-adjusted returns), with PnL as secondary metric.

Edge model:

  • base_edge from deterministic numeric features (fair_value, implied_price, costs, liquidity, volume, volatility).
  • Fair-value source hierarchy is explicit: model -> orderbook_mid -> time_decay_blend (with declared fallback).
  • edge_score must be reproducible from declared components (mispricing_bps, fees_bps, expected_slippage_bps, liquidity/volume penalties, confidence weight).
  • Reflection/reasoning contributes bounded edge_adjustment.
  • Recommended guardrail: reflection influence capped at +/-0.03 edge_score.
  • Reflection never bypasses hard risk gates.

Learning mode:

  • workflow eval computes built-in run metrics plus optional custom metrics from workflow outputs.
  • workflow optimize creates optimization-run bookkeeping/rollback metadata only.
  • Automatic mutation/promotion is not built into harness commands; it must be orchestrated externally.

Scheduling Model

Recommended:

  • One recurring schedule per strategy.
  • No per-candidate one-time schedules for fanout (avoids schedule explosion and stale jobs).
  • Schedule must be active, not expired, and below max execution count.

Use structured schedule target (workflow or command) and emit markov.discovery.request each run. Seeded discovery-controller wiring converts that into accepted-chain scan fanout.

Example schedule payload shape (createScheduledPrompt):

{
  "name": "Markov Crypto Discovery",
  "target": {
    "kind": "workflow",
    "workflowId": "markov-discovery-trigger",
    "revision": "latest",
    "inputs": {
      "strategy_id": "strat-crypto-sharpe",
      "query": "crypto"
    }
  },
  "trigger": {
    "type": "time_based",
    "schedule": {
      "pattern": "recurring",
      "cronExpression": "*/15 * * * *",
      "timezone": "America/Los_Angeles"
    }
  },
  "metadata": {
    "agent": {
      "name": "predictions",
      "strategy": "fixed"
    }
  }
}

Workflow Eval/Optimize Reality

What is available in commands.ts today:

  • workflow eval <run-id> evaluates run artifacts using built-in metrics (total_duration_ms, step_count, success_rate, error_rate, output_size_bytes).
  • Custom metrics are supported only when defined in workflow.evaluation.custom_metrics and sourced from step results (steps.<stepId>.<path>).
  • workflow optimize <workflow-id> [--baseline <run-id>] creates an optimization run record; it does not automatically mutate workflow code.
  • workflow optimize-list and workflow rollback manage optimization records and rollback metadata.

Implication for alpha loops:

  • Sharpe/edge quality must be emitted as numeric step outputs and wired as custom metrics.
  • GEPA/champion-challenger promotion must be implemented by an external controller workflow/agent, not by built-in optimize alone.

Required custom metric contract (minimum):

  • strategy_sharpe from steps.monitor.result.strategy_sharpe
  • edge_realization_bps from steps.monitor.result.edge_realization_bps
  • realized_slippage_bps from steps.monitor.result.realized_slippage_bps

Canonical Runtime Contract

Workflow IDs

Seeded now:

  • markov-discovery-controller@latest
  • markov-scan@latest
  • markov-signal@latest
  • markov-execution-plan@latest
  • markov-monitor@latest

Optional extension (live adapter):

  • markov-execution@latest

Hook IDs

Seeded now:

  • markov-discovery-controller-start
  • markov-scan-start
  • markov-signal-on-scan
  • markov-exec-plan-on-signal
  • markov-monitor-on-execution-filled
  • markov-monitor-on-tick

Optional extension (live adapter):

  • markov-execution-on-plan

Event Namespace

  • markov.discovery.request
  • markov.scan.request
  • markov.scan.completed
  • markov.signal.completed
  • markov.signal.rejected
  • markov.execution_plan.completed
  • markov.execution.approval_required
  • markov.execution.request
  • markov.execution.started
  • markov.execution.partial_fill
  • markov.execution.completed
  • markov.execution.failed
  • markov.execution.filled
  • markov.execution.unwind.request
  • markov.monitor.tick
  • markov.monitor.active
  • markov.monitor.invalidated
  • markov.chain.error

Stage Semantics

0) discovery (fanout)

Inputs:

  • strategy_id, scheduled_prompt_id, scheduled_run_id, query, keyword
  • risk_pct_per_trade, account_size_usd, max_slippage_bps, outcome
  • max_candidates_per_discovery, max_new_chains_per_run
  • min_hours_until_end, max_hours_until_end, min_volume_24h_usd, min_liquidity_usd, min_keyword_relevance

Behavior:

  • markov.discovery.request runs markov-discovery-controller@latest.
  • Enumerates candidate markets from discovery sources.
  • Filters by quality (time-to-end window, liquidity, volume, keyword relevance, data completeness).
  • Ranks candidates and selects top-N for this run.
  • Computes exactly one candidate decision per market/outcome (accepted or rejected).
  • Rejects candidates when active position already exists for same market/outcome.
  • Rejects candidates when strategy/portfolio risk is exhausted.
  • Enforces max_new_chains_per_run before chain identity spawn.
  • Uses a single discovery request per run with reason annotated as periodic scan vs periodic re-evaluation.

On success:

  • Emits one markov.scan.request per selected candidate chain.

1) scan

Inputs:

  • chain_id, strategy_id, scheduled_prompt_id, scheduled_run_id
  • market_id, outcome
  • token_id, yes_token_id, no_token_id (optional, resolved if absent)
  • risk_pct_per_trade, account_size_usd, max_slippage_bps

Behavior:

  • Validates scan payload bounds and runs markov-scan@latest from markov.scan.request hook wiring.
  • Pulls market snapshot and resolves Yes/No token IDs from market outcomes (outcomes[] / clob_token_ids).
  • Calls orderbook tool with tokenId (tool-contract-aligned) and falls back to alternate outcome token when needed.
  • Computes risk cap and market-quality snapshot.
  • Persists chain state under markov_chain:{chain_id}.

On success:

  • Emits markov.scan.completed.

2) signal

Inputs:

  • Scan payload plus model inputs:
    • fair_value_price, fair_value_source, fair_value_confidence, edge_uncertainty_bps, model_version
    • orderbook_imbalance, volatility_proxy, fees_bps, expected_slippage_bps
    • min_cost_adjusted_edge_bps

Behavior:

  • Computes pseudo-greeks and inefficiency.
  • Uses fair-value source hierarchy (input -> prior_state -> orderbook_mid) when explicit fair value is absent.
  • If requested outcome is Auto, evaluates Yes vs No cost-adjusted edge and selects side with stronger edge.
  • Carries forward token_id for the selected outcome plus yes_token_id/no_token_id for downstream execution/monitoring.
  • Computes deterministic base_edge and bounded final edge_score.
  • Writes signal summary and reflection logs.
  • Applies execution gate (edge, confidence, uncertainty, cost-adjusted edge threshold).

On success:

  • Emits markov.signal.completed (gate passed) or markov.signal.rejected (gate failed), always with explicit gate fields.
  • markov-exec-plan-on-signal requests markov-execution-plan@latest only for markov.signal.completed.

3) execution_plan

Inputs:

  • Accepted signal payload.

Behavior:

  • Builds executable intent (entry_price_band, size_cap_usd, stop_policy, compounding_policy, execution cadence).
  • Enforces per-trade max-loss cap and remaining strategy/portfolio risk availability.
  • Uses position risk_usd plus active RiskReservation totals for exposure accounting.
  • Creates active RiskReservation on approved plan and releases on terminal execution outcomes.
  • Enforces one active execution plan/reservation/approval tuple per chain via idempotency guards.
  • Defaults to paper intent and transitions chain state to execution_approval_required.
  • Creates approval contract fields (approval_token, approval_expires_at, requested_at) for live escalation.
  • Emits markov.execution.approval_required for live intent escalation.

On success:

  • Emits markov.execution_plan.completed.

4) execution (live)

Inputs:

  • markov.execution.request payload with explicit confirmation fields.

Behavior:

  • Runs live order placement (TWAP-style slices / partial fill handling) within max slippage and runtime limits.
  • Uses Predictions tool tradePredictionMarket for slice entry/exit.
  • Uses Predictions tool cancelPredictionOrder for stale/violating open orders.
  • Uses getPolymarketPositions and getPolymarketOrderHistory for reconciliation.
  • Enforces policy gate: confirmation required before trade/cancel/redeem/funding actions.
  • Requires confirmation provenance (confirmed_by_user, approved_by_user_id, approval_token) validated against stored ExecutionApproval.
  • Requires slice_count * slice_interval_seconds <= max_execution_runtime_seconds before workflow launch.
  • Transitions chain status to execution_requested on accepted request and execution_in_progress on markov.execution.started.
  • Runtime-budget breaches explicitly persist chain execution_failed state and emit chain error snapshot.
  • Emits partial updates as fills accumulate and final completion/failure terminal events.
  • Persists per-slice attempts and aggregate fill summary for post-trade attribution.
  • Periodic strategy ticks expire stale pending approvals and release reserved risk.

On success:

  • Emits markov.execution.partial_fill for in-flight progress.
  • Emits markov.execution.completed when fill ratio threshold is reached.
  • Emits markov.execution.filled to trigger monitor on both partial and complete fills.

On failure:

  • Emits markov.execution.failed and markov.chain.error.

5) monitor (post-first-fill)

Inputs:

  • markov.execution.filled payload or markov.monitor.tick payload.

Behavior:

  • Starts once there is non-zero filled exposure (partial or complete).
  • Refreshes market and evaluates alpha decay/invalidation.
  • Reuses persisted token_id for orderbook refresh (with snapshot-based token fallback by outcome).
  • Metric refresh reads only key-matched nested fields (hours_until_end, volume_24h_usd, liquidity_usd) and ignores unrelated scalar leaves.
  • On invalidation, emits markov.execution.unwind.request to force risk-off action.
  • Emits active vs invalidated state.

On success:

  • Emits markov.monitor.active or markov.monitor.invalidated.

6) unwind execution bridge

Inputs:

  • markov.execution.unwind.request payload (from monitor invalidation).

Behavior:

  • Starts markov-execution@latest with unwind intent.
  • Supports auto-unwind via policy flag or explicit user confirmation fields.
  • Reuses execution telemetry/events for traceability.

Risk Governance Defaults

  • Portfolio hard cap + per-strategy cap both enforced.
  • Execution mode defaults to paper until explicit confirmation.
  • Trade/cancel/redeem/funding actions require confirmation by policy.
  • Execution runtime is bounded (max slices + max runtime + slippage breach retries).
  • Suggested defaults:
    • default_execution_mode = paper
    • require_trade_confirmation = true
    • allow_auto_unwind_on_invalidation = true
    • approval_ttl_minutes = 10
    • daily_realized_loss_pause_pct = 1.5
    • consecutive_invalidations_pause_count = 4
    • consecutive_slippage_breach_pause_count = 3
    • slippage_breach_multiplier = 2
    • stale_data_max_runs = 3
    • max_execution_slices = 8
    • min_slice_interval_seconds = 20
    • max_execution_runtime_seconds = 900
    • max_slippage_breach_retries = 2
    • min_fill_ratio_for_completion = 0.95

Payload Contract Notes

Core fields:

  • All custom events use payload envelope (no bare top-level chain_id emits).
  • chain_id, strategy_id, scheduled_prompt_id, scheduled_run_id, query
  • market_id, token_id, yes_token_id, no_token_id, outcome, requested_outcome, selected_outcome
  • risk_pct_per_trade, account_size_usd, max_slippage_bps
  • max_hours_until_end, min_keyword_relevance, keyword_relevance
  • edge_score, cost_adjusted_edge_bps, hours_until_end, volume_24h_usd, liquidity_usd
  • implied_price, yes_price, no_price, fair_value_price, fair_value_source, fair_value_confidence, edge_uncertainty_bps, model_version
  • orderbook_imbalance, volatility_proxy, fees_bps, expected_slippage_bps
  • min_cost_adjusted_edge_bps
  • execution_mode, confirmed_by_user, approved_by_user_id, approval_token, approval_expires_at
  • slice_count, slice_interval_seconds, order_id, slice_index
  • filled_size_usd, average_fill_price, fill_ratio, realized_slippage_bps
  • risk_usd (active positions), reserved_risk_usd (risk reservations)
  • timestamp, source_stage

Invocation

Discovery start (strategy run):

Note: seeded bundles bind this event to markov-discovery-controller@latest, which emits markov.scan.request for accepted candidates.

event emit markov.discovery.request '{"strategy_id":"strat-crypto-sharpe","scheduled_prompt_id":"sp-123","scheduled_run_id":"run-2026-02-26T15:00Z","query":"crypto","keyword":"crypto","outcome":"Auto","risk_pct_per_trade":0.5,"account_size_usd":10000,"max_slippage_bps":50,"max_hours_until_end":336,"min_keyword_relevance":0.2}'

Direct scan start (single market/manual):

event emit markov.scan.request '{"chain_id":"strat-crypto-sharpe:run-2026-02-26T15:00Z:market-abc:yes","strategy_id":"strat-crypto-sharpe","scheduled_run_id":"run-2026-02-26T15:00Z","market_id":"market-abc","outcome":"Yes","risk_pct_per_trade":0.5,"account_size_usd":10000,"max_slippage_bps":50}'

Execution start (usually emitted by execution_plan):

event emit markov.execution.request '{"chain_id":"strat-crypto-sharpe:run-2026-02-26T15:00Z:market-abc:yes","strategy_id":"strat-crypto-sharpe","market_id":"market-abc","outcome":"Yes","execution_mode":"live","confirmed_by_user":true,"approved_by_user_id":"usr-123","approval_token":"appr-8d31","approval_expires_at":"2026-02-26T15:20:00Z","size_cap_usd":2500,"entry_price_band_low":0.59,"entry_price_band_high":0.62,"max_slippage_bps":50,"slice_count":6,"slice_interval_seconds":30,"source_stage":"execution_plan"}'

Run evaluation / optimization (harness commands):

workflow eval run_abc123
workflow optimize markov-signal@latest --baseline run_abc123
workflow optimize-list markov-signal@latest --json

Execution fill (starts monitor):

event emit markov.execution.filled '{"chain_id":"strat-crypto-sharpe:run-2026-02-26T15:00Z:market-abc:yes","market_id":"market-abc","outcome":"Yes","filled_size_usd":2500,"average_fill_price":0.61,"timestamp":"2026-02-26T15:12:00Z","source_stage":"execution_filled"}'

Monitor re-check:

event emit markov.monitor.tick '{"chain_id":"strat-crypto-sharpe:run-2026-02-26T15:00Z:market-abc:yes"}'

Transition Sequence

flowchart LR
  A["recurring strategy schedule tick"] --> B["markov.discovery.request"]
  B --> C["discovery filter + rank + top-N select"]
  C --> D["emit markov.scan.request (fanout per candidate)"]
  D --> E["markov-scan@latest"]
  E --> F["markov.scan.completed"]
  F --> G["markov-signal@latest"]
  G --> H{"edge/confidence gate"}
  H -->|"reject"| I["markov.signal.rejected"]
  H -->|"accept"| J["markov.signal.completed"]
  J --> K["markov-execution-plan@latest"]
  K --> L["markov.execution_plan.completed"]
  L --> M["markov.execution.approval_required"]
  M -->|"confirmed"| N["markov.execution.request"]
  N -->|"runtime budget breach"| T["markov.execution.failed"]
  N --> O["markov-execution@latest (optional adapter)"]
  O --> P{"fill ratio reached?"}
  P -->|"partial"| Q["markov.execution.partial_fill"]
  Q --> S["markov.execution.filled"]
  P -->|"complete"| R["markov.execution.completed"]
  R --> S["markov.execution.filled"]
  O -->|"failed"| T["markov.execution.failed"]
  S --> U["markov-monitor@latest"]
  V["markov.monitor.tick"] -.-> U
  U --> W{"thesis + alpha decay check"}
  W -->|"valid"| X["markov.monitor.active"]
  W -->|"invalidated"| Y["markov.monitor.invalidated"]
  Y --> AA["markov.execution.unwind.request"]
  AA --> AB["markov-execution@latest (unwind intent)"]
  O -->|"error"| Z["markov.chain.error"]
  U -->|"error"| Z
Loading

Failure Modes

  • Invalid payload -> markov.chain.error
  • Missing market data -> markov.chain.error
  • Signal below edge/confidence threshold -> markov.signal.rejected
  • Live execution request without confirmation -> markov.execution.approval_required (no trade call)
  • Approval token missing/expired -> markov.execution.approval_required (refresh required)
  • Approval expired while pending -> execution_approval_expired + reservation release + markov.chain.error
  • Execution request runtime-budget breach -> markov.execution.failed + markov.chain.error
  • Execution slippage/retry breach in workflow completion payload -> markov.execution.failed + markov.chain.error
  • Execution fill ratio below completion threshold -> markov.execution.partial_fill (monitor still starts on filled exposure)
  • Monitor before any fill -> skipped + markov.chain.error (no filled exposure yet)
  • Missing required eval custom metrics -> eval fails quality gate, no auto-promotion
  • Duplicate stage transitions -> dropped by idempotency guard
  • Risk cap exhausted -> candidate rejected (no chain spawn)
  • Expired/disabled/over-limit schedule -> no discovery run emitted

Next Steps

  1. Market Metadata Enrichment
  • Resolve accepted numeric market IDs to canonical metadata (question, slug, outcomes, end time) during discovery.
  • Persist metadata into chain state and run artifacts for operator review.
  1. Fair Value Model Upgrade
  • Replace orderbook-only fallback with a pluggable fair-value model per strategy.
  • Version and log model inputs so edge derivation is auditable.
  1. Signal Gate Calibration
  • Calibrate min_cost_adjusted_edge_bps, confidence floor, and uncertainty bounds from realized runs.
  • Add regime-specific thresholds by liquidity and time-to-resolution buckets.
  1. Live Execution Wiring
  • Enable markov-execution@latest adapter with confirmation, slice controls, and unwind flows.
  • Add explicit close policy for invalidation and stale-alpha exits.
  1. Portfolio and Scheduler Guardrails
  • Add max-concurrent-chain and cooldown controls per strategy.
  • Add schedule-level risk throttles to prevent over-allocation across simultaneous candidates.
  1. Observability and Evaluation Loop
  • Emit compact per-run summaries (accepted/rejected reasons, reserved risk, gate outcomes, slippage).
  • Run recurring workflow eval and staged workflow optimize with human promotion gates.
  1. Hardening Tests
  • Add integration fixtures for discovery -> scan -> signal with realistic payloads.
  • Add regression tests for Auto side selection, dynamic slippage, and duplicate-event idempotency.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment