Skip to content

Seneca calibration of RCPAgent.baseFraction

This page documents the v1.1 S0 calibration of RCPAgent.baseFraction on the Bardi-scale Seneca engine, and fixes the default value adopted by the v1.1 vignette scripts S1, S2, and S3.

The calibration is the operational closure of the Paper BDPD⁰ calibration debt: the Seneca engine shipped at v0.4, but RCPAgent.baseFraction = 0.4 was tuned for logistic-scale commons (R in the order of 10²). On the Bardi canonical scale (R₀ = 1.0), the same fraction extracts ~40% of R per turn per player and depletes the commons in a handful of turns — well before C accumulation and P feedback can develop.

V1.1 A1 surfaced baseFraction as config.strategyParams.baseFraction (default 0.4 unchanged for the logistic case). S0 then swept the parameter on a Bardi-scale single-arena Seneca game and read the effective game length, where:

Effective game length = the first turn at which R drops below 5% of R₀.

After this point, harvests are vanishing and Bardi dynamics are out of play, so it is the operational end of the game even though the platform threshold field is ignored by SenecaEngine.checkEnd (which closes only on R ≤ 0 or maxTurns).


Setup

Knob Value
Script scripts/calibration_v11_s0_seneca.mjs
Engine seneca, canonical defaults (SENECA_DEFAULTS)
Arena 1, no Link, no governance, no perturbation
Players 5 × RCPAgent, privateResource = R₀
Scheduler simultaneous
R₀ 1.0
maxTurns 60
Observability noise 0 across all fields
Seed 17 (pilot anchor)
Target band [25, 30] turns

The setup is fully deterministic — Seneca's engine is a Bardi ODE, observability noise is zero, and RCPAgent.decide() consults no internal RNG. A given (seed, baseFraction) pair always produces the same trajectory, so N = 1 per cell is rigorous: re-sweeping with different seeds reproduces the table below verbatim.


Findings

baseFraction Effective end (turn) In band [25, 30]?
0.020 52
0.025 40
0.030 34
0.035 29
0.040 24
0.045 22
0.050 19
0.100 9
0.150 5
0.200 1

The full per-cell trajectory (R at turns 5/10/20/30, final R, close reason) is in data/calibration/v11_s0_seneca/aggregate.json after a local run of the script. The artefact is gitignored — re-run the script (see reproduce) to regenerate.


For the v1.1 vignette scripts (S1 — Seneca standalone, S2 — polycentric cascade, S3 — pollution governance):

const SENECA_RCP_BASE_FRACTION = 0.035;     // v1.1 S0 calibration; see this doc

arena.addPlayer({
  agentType:      'builtin',
  strategy:       'rcp',
  strategyParams: { baseFraction: SENECA_RCP_BASE_FRACTION },
  privateResource: 1.0,
  displayName:    `rcp${i}`,
});

The shipped vignette scripts also accept a PILOT_BASE_FRACTION environment variable so the calibration can be revisited per-run without an edit.


Caveats and reading rules

  • N = 1, but rigorous. Determinism makes seed sweeping pointless here. If observability noise or a stochastic perturbation is later introduced into S1/S2/S3, the calibration must be re-run with the same noise budget and with N ≥ 3.
  • The number is a function of N_PLAYERS. All else equal, the pre-discount per-turn extraction is N_PLAYERS × baseFraction. The calibrated value 0.035 is correct for the planned N = 5 setup. Halving the population would let baseFraction roughly double for the same game length; doubling the population would roughly halve it. Vignette designs that depart from N = 5 must re-run S0.
  • The RCP ratio discount kicks in below 50%. RCPAgent.decide() applies rFraction = baseFraction when commonsRatio > 0.5 and rFraction = baseFraction × 0.5 otherwise. The decay below 50% is therefore slower than naive geometric, which is why the S0 → 25–30 band requires baseFraction ≈ 0.035 instead of the naive 1 / (5 × 27) ≈ 0.0074 estimate. See agents §RCP for the full harvest rule.
  • Only RCP is calibrated. ConservativeAgent and AdaptiveAgent have their own internal fraction logic and are not parameterised here. If a Seneca-mode vignette mixes RCP with Conservative / Adaptive, the same baseFraction = 0.035 does not automatically apply to the latter — they need their own calibration pass or, more practically, the vignette should run RCP-only unless a specific ablation is being studied.
  • What the band buys. A 25–30-turn game leaves enough room for Bardi C accumulation to register (peak C is at ODE-time t ≈ 145 on canonical defaults, i.e. ~1450 base game turns at dt = 0.10 — but the cliff edge sits much earlier, in the same 25–30-turn window on this calibration). Shorter games miss the cliff; longer games cost compute without surfacing additional dynamics.

Cross-references

  • agents/built-in.jsRCPAgent constructor exposes strategyParams.baseFraction.
  • scripts/calibration_v11_s0_seneca.mjs — the sweep itself.
  • agents §RCP — agent-side formula and discount gate.
  • reproduce §S0 — invocation recipe.
  • BDPD³ paper §Model — the scientific consumer of this calibration.