Participant policy — the trio's tunables and invariants
--- name: participant-policy version: 0.1.0 description: Operator-facing policy documentation for the SPEC-103 §3.6 market-participant trio (value-funder / contrarian-bettor / diversifier) — the shared risk-envelope...
Participant policy — the trio’s tunables and invariants
The SPEC-103 §3.6 market-participant trio (participant_value_funder,
participant_contrarian_bettor, participant_diversifier) acts as
the platform’s exchange-side economic agents. Each holds a budget,
honours a risk envelope, and emits one specific action class against
one specific bias the unaided market exhibits:
| Participant | Signal | Action | Bias countered |
|---|---|---|---|
| Value Funder | thinness × inverse-current-fund | signal(kind='fund') on under-funded thin gaps |
platform-wide neglect of underexplored directions |
| Contrarian Bettor | consensus vs. model residual | markets.trade on the under-priced side |
crowd over-confidence on consensus markets |
| Diversifier | mechanism-family monoculture in a gap | signal(kind='fund') on under-represented families + QF top-up |
within-gap mechanism monoculture |
The trio exhausts the design surface — each counters a different failure mode. The numbers below are what makes that work in practice.
Participant execution is agent-owned. The substrate stores durable market
participant rows, risk envelopes, ledgers, signals, and settlement mechanics;
the runtime loop that decides whether to fund, diversify, or trade should run
from this agent skill bundle and write back through substrate verbs. Per-row
risk envelopes are stored in market_participants.risk_envelope; runtime
defaults may still be overridden by deployment config.
Shared risk-envelope tunables
All three honour the same envelope shape; the defaults vary by participant and the ordering is load-bearing.
max_position_size — value-funder 500, diversifier 300, contrarian 200
Cap on tokens any single trade or fund signal can move.
The descending order matches the strategies’ inverse variance: value-funder allocates over gaps (broad, slow theses); diversifier over families within a gap (narrower, QF-amplified); contrarian over binary markets (highest variance per token). A single wrong contrarian bet can blow through a quarter’s gains in one settlement — the tight per-position cap is the only thing keeping a streak of bad calibrations from being existential. Flattening these to one value silently breaks the implicit risk-scaling.
max_drawdown — contrarian 0.25, diversifier 0.25, value-funder 0.30
Fraction of starting balance that triggers a pause-all-new-bids state. Contrarian and diversifier pause earlier because their strategies should be more predictable than the value-funder’s; a 25% drawdown for either is a strong signal of strategy malfunction. The value-funder tolerates 30% because gap-level theses take longer to resolve and can drift further before reverting. Above 0.5 you’ve effectively disabled the circuit-breaker; under 0.15 you’ll trip on routine market noise within a week.
concentration_cap — contrarian 0.30, value-funder 0.20, diversifier 0.15
Fraction of portfolio that may sit in one artifact. Inverse of the position-size order, also load-bearing. Defines an implicit minimum portfolio: contrarian needs ≥4 markets, value-funder ≥5 gaps, diversifier ≥7 gaps. A diversifier with 30% in one gap is not diversifying anything.
Value-Funder–specific
FUND_FLOOR = 100 tokens — env SCIDEX_VALUE_FUNDER_FUND_FLOOR
Eligibility cutoff: only gaps with current_fund < FUND_FLOOR get
allocations. Channels capital to genuinely orphaned gaps rather than
dogpiling already-funded ones. Cross-references the
gap-roi-realloc-policy “underfunded” band — raising one without
the other lets the realloc worker reclaim value-funder allocations
the moment they land.
-
Higher (200–500): stretch into mid-funded gaps when the under-funded tail is small and budget is idle.
-
Lower (25–50): last-resort backstop only.
top-N = 5 — implicit per-deployment constant
Number of value-score-ranked gaps funded per tick. Per-gap dose is
budget_remaining / N; raising N spreads thinner. Not env-overridable
today because it interacts with allocation arithmetic — revisit if
deployments diverge.
Contrarian-Bettor–specific
sigma_threshold = 2.0 — contrarian_decide.decide(sigma_threshold=...)
σ multiples of model uncertainty the consensus must deviate by to trigger a stake. Two sigma ≈ outer 5% of the bettor’s confidence interval — if the per-market posterior is approximately Gaussian. In heavy-tailed regimes the same “2σ” is much looser; check the empirical distribution before lowering. Raising to 2.5–3.0 narrows to only the strongest crowd errors; lowering to 1.5–1.8 chases more noise.
STAKE_SIZE = 50 tokens — per-trade nominal
Stake before envelope-clipping. 50 against max_position_size=200
means up to 4 stake-quotas per market. Larger (100+) = fewer/bigger
trades when calibration is strong; smaller (10–25) = more update
samples while the Bayesian prior is wide.
model_decay = 0.95 — Bayesian prior decay per tick
0.95^14 ≈ 0.49 so older information halves over ~14 ticks. Higher
(≥0.98) for stable markets; lower (0.85–0.90) where regime change is
common (e.g. drug development after a major preclinical readout).
Diversifier-specific
Monoculture trigger: dominant_family_share ≥ 0.70 — implicit
gap.exploration_invited fires when one mechanism family commands
≥70% of hypotheses on a gap. Above 70% = tolerate moderate
monoculture (use when total hypothesis volume is low); below 55–65%
= intervene early (use in mature domains with multiple established
families). Crosses the SPEC-104 diversity_score “monoculture-suspect”
band at the same point — keep them aligned.
SCIDEX_DIVERSITY_MIN = 0.3 — env SCIDEX_DIVERSITY_MIN
SPEC-104 Simpson-style diversity_score cutoff at which the upstream
gap_diversity_trigger worker emits the event. The diversifier
consumes; it doesn’t compute. Same phenomenon as the 70% trigger
above from a different angle — they MUST move together.
RECOVERY_THRESHOLD = 0.5 — close diversifier positions
diversity_score at which the diversifier stops funding. The
hysteresis (intervene at 0.3, withdraw at 0.5) prevents thrashing.
Equal values cause chatter; reversed values cause the diversifier to
fund already-healthy gaps. Invariant: RECOVERY_THRESHOLD > SCIDEX_DIVERSITY_MIN.
ALLOCATION_UNIT = 50, EXPLORATION_GRANT = 100, diversity_bonus cap = 1.5×
Per-hypothesis base allocation (deliberately mirrors contrarian
STAKE_SIZE); QF top-up for empty families (2× the per-hypothesis
unit because attracting a new hypothesis is harder than topping up
existing); cap on the SPEC-104 §3.4 diversity_bonus multiplier. The
1.5× cap prevents a feedback loop where the diversifier over-funds
the first hypothesis in a new family until its own funding becomes
the dominant signal. Above 2× the loop closes.
Load-bearing invariants
-
max_position_size: value-funder > diversifier > contrarian. The per-position cap is the only thing keeping high-variance binary contrarian trades from killing the portfolio. -
concentration_cap: contrarian > value-funder > diversifier. Inverse of position-size. Defines implicit minimum portfolios; if the live market landscape doesn’t support those counts, the participant cannot deploy a full book. -
RECOVERY_THRESHOLD > SCIDEX_DIVERSITY_MIN. Diversifier hysteresis; equal/reversed causes oscillation or self-defeating allocations. -
70%-monoculture trigger ↔
SCIDEX_DIVERSITY_MIN = 0.3. Same phenomenon, two angles. Must move together. -
sigma_threshold ≥ 2.0requires Gaussian posteriors. In heavy-tailed markets 2σ is much looser than 5%. Check before lowering. -
diversity_bonus_cap ≤ 2.0. Above 2× the diversifier dominates its own funding signal.
Operator playbook
Symptom: value-funder budget sits idle, few allocations emit.
Diagnose: is FUND_FLOOR too low? Check gap count where
current_fund < 100. Lever: raise FUND_FLOOR, or check whether
gap-roi-realloc-policy is clawing back faster than allocation.
Symptom: contrarian in continuous drawdown.
Diagnose: is model variance calibrated? Compare emitted model_sigma
to observed settlement spread. Lever: raise sigma_threshold to
2.5, tighten STAKE_SIZE, or investigate whether the Bayesian
update is being applied at all.
Symptom: diversifier oscillating on the same gap.
Diagnose: are SCIDEX_DIVERSITY_MIN and RECOVERY_THRESHOLD too
close? Lever: widen the hysteresis (raise recovery to 0.6+, or lower
the trigger to 0.25).
Symptom: new mechanism families never attract hypotheses.
Diagnose: is EXPLORATION_GRANT reaching the QF round? Check
signal(kind='fund') events with metadata.purpose='diversity_exploration'.
Lever: raise EXPLORATION_GRANT, or audit QF matching per SPEC-104 §3.8.
Symptom: participant repeatedly hits max_drawdown.
Diagnose: deployment-wide or this participant only? Lever: not this
policy. Drawdown is a strategy-malfunction signal; pause-and-investigate
is the correct circuit-breaker response. Loosening the envelope masks
the underlying problem.
Tuning protocol
-
Tune ONE class at a time (envelope OR per-participant defaults).
-
All six invariants above MUST still hold after the change. The taxonomy + skill-design-quality tests enforce some structurally.
-
Wait ≥2 weeks before assessing impact — ROI signals compound through
trust-score-weight-policyslowly and the QF round is weekly cadence. -
50% changes from default need a Senate proposal citing this policy and the symptom-and-lever pair. Don’t unilaterally rebalance the trio.
Why this is one policy doc, not three workers’ constants
Per SPEC-199 §4.3, Wave-3 converts hardcoded policy constants into
operator-facing policy skills with env-var overrides. The participant
trio is the 26th explicit Wave-3 externalization — three skills
in one doc because the tunables are cross-coupled: changing the
diversifier’s SCIDEX_DIVERSITY_MIN without looking at the
contrarian’s sigma_threshold can leave the platform with two
participants chasing the same noise. The policy skill is what makes
that coupling explicit so the runtime selector
(skill_taxonomy.taxonomy_for) routes @ops / @analyst queries to
the right doctrine rather than three drifting tables.
This also closes the iter-220 design-quality directive: each of the three participant SKILL.md files scored 1.8 / 5.0 on the “no-hardcoded-constants” axis. With the constants in this doctrine and the three skills rewritten to point to it, that’s a 3-for-1 design-quality lift in one PR.
Cross-references
-
SPEC-103 §3.6 — market-participant trio architecture
-
SPEC-104 §3.4 + §3.8 — diversity score, QF round, exploration invitations
-
participant_value_funder— consumer ofFUND_FLOOR+ top-N -
participant_contrarian_bettor— consumer ofsigma_threshold,STAKE_SIZE,model_decay -
participant_diversifier— consumer ofSCIDEX_DIVERSITY_MIN,RECOVERY_THRESHOLD,ALLOCATION_UNIT,EXPLORATION_GRANT,diversity_bonuscap -
gap-roi-realloc-policy— downstream reallocator interacting withFUND_FLOOR -
trust-score-weight-policy— downstream aggregator consumingparticipant_roi -
docs/architecture/skill-taxonomy.md— this skill:category: policy / permission_level: policy(iter-221) -
docs/design/spec-199-skill-first-architecture.md§4.1 — Wave-3 catalog (this PR adds the 26th entry)