Symptom
Following the documented Notion cheat sheet against `config/fork.toml` with `FORK_BLOCK` pinned (per the cheat sheet's demo block) or unset (defaulting to `scripts/anvil_fork.sh`'s `DEFAULT_FORK_BLOCK=94000000`), startup aborts:
```
WARN chainlink refresh failed symbol=BNB err=feed 'BNB' is stale (updated 2165161 s ago, max_age 3600 s)
WARN chainlink refresh failed symbol=ETH err=... max_age 3600 s
WARN chainlink refresh failed symbol=BTCB ... max_age 3600 s
Error: chainlink feed for 'BNB' missing or stale on chain 'bnb' after 5 attempts — gas cost cannot be priced
```
Root cause
`config/fork.toml:122-127` keeps mainnet-grade per-symbol windows:
```toml
[chainlink_max_age_secs.bnb]
USDT = 86400
USDC = 86400
BNB = 3600
BTCB = 3600
ETH = 3600
```
On a pinned-block fork:
- `block.timestamp` on the fork is set to the pin block's mainnet timestamp.
- The fork's local clock advances at `--block-time 3` (plus the keep-alive nudge).
- Chainlink feed timestamps inside the forked state reflect the most recent on-chain feed update at or before the pin block.
In practice, at the documented demo block (`91323624`) and at the script default (`94000000`), heartbeat-feed staleness measured in `block.timestamp` units exceeds 3600s often enough that the demo never reaches `venus pipeline ready`. Multi-day staleness has been observed when forking close to current head, indicating either feed deprecation or aggregator rotation gaps that no operator should be expected to debug for a local demo.
Proposed fix
Loosen the windows in `config/fork.toml` to demo-realistic values that still detect a genuinely dead feed but tolerate the kind of staleness any pinned fork can exhibit:
```toml
[chainlink_max_age_secs.bnb]
USDT = 2592000 # 30d — stable feed, deviation-triggered, irrelevant for a demo
USDC = 2592000 # 30d
BNB = 2592000 # 30d — wide enough to outlast any demo block we might pin
BTCB = 2592000
ETH = 2592000
```
`config/default.toml` (production) stays untouched — this is a fork-profile-only relaxation. Add a config comment explaining why the windows differ from `default.toml` so future tuners do not paste production values back in.
Also pairs with #413 (env override) so an operator can override further with `CHARON_PRICE_MAX_AGE_SECS` without editing config.
Impact
Today the documented Notion cheat sheet does not run end-to-end without an undocumented config edit. New operators interpret the staleness error as a genuine wiring failure rather than a config tightness mismatch.
Symptom
Following the documented Notion cheat sheet against `config/fork.toml` with `FORK_BLOCK` pinned (per the cheat sheet's demo block) or unset (defaulting to `scripts/anvil_fork.sh`'s `DEFAULT_FORK_BLOCK=94000000`), startup aborts:
```
WARN chainlink refresh failed symbol=BNB err=feed 'BNB' is stale (updated 2165161 s ago, max_age 3600 s)
WARN chainlink refresh failed symbol=ETH err=... max_age 3600 s
WARN chainlink refresh failed symbol=BTCB ... max_age 3600 s
Error: chainlink feed for 'BNB' missing or stale on chain 'bnb' after 5 attempts — gas cost cannot be priced
```
Root cause
`config/fork.toml:122-127` keeps mainnet-grade per-symbol windows:
```toml
[chainlink_max_age_secs.bnb]
USDT = 86400
USDC = 86400
BNB = 3600
BTCB = 3600
ETH = 3600
```
On a pinned-block fork:
In practice, at the documented demo block (`91323624`) and at the script default (`94000000`), heartbeat-feed staleness measured in `block.timestamp` units exceeds 3600s often enough that the demo never reaches `venus pipeline ready`. Multi-day staleness has been observed when forking close to current head, indicating either feed deprecation or aggregator rotation gaps that no operator should be expected to debug for a local demo.
Proposed fix
Loosen the windows in `config/fork.toml` to demo-realistic values that still detect a genuinely dead feed but tolerate the kind of staleness any pinned fork can exhibit:
```toml
[chainlink_max_age_secs.bnb]
USDT = 2592000 # 30d — stable feed, deviation-triggered, irrelevant for a demo
USDC = 2592000 # 30d
BNB = 2592000 # 30d — wide enough to outlast any demo block we might pin
BTCB = 2592000
ETH = 2592000
```
`config/default.toml` (production) stays untouched — this is a fork-profile-only relaxation. Add a config comment explaining why the windows differ from `default.toml` so future tuners do not paste production values back in.
Also pairs with #413 (env override) so an operator can override further with `CHARON_PRICE_MAX_AGE_SECS` without editing config.
Impact
Today the documented Notion cheat sheet does not run end-to-end without an undocumented config edit. New operators interpret the staleness error as a genuine wiring failure rather than a config tightness mismatch.