Overview
The sinker policy namespace gates what the AI agent is allowed to do. Policies set hard limits on tip size, how aggressively the agent escalates on retries, how many bundles can be in-flight at once, and more.
Settings persist in sinker.policy.json in the working directory. Both the sidecar and the agent read the file once on startup. Restart the stack to apply any changes.
sinker policy <sub-command>
The policy file is partial by design — only the keys you change need to be present. Missing keys resolve silently to built-in defaults. An empty file (or no file at all) means “use all defaults.”
Policy keys
These keys are accepted by sinker policy set and sinker policy reset <key>.
Tip controls
| Key | Default | Unit | Description |
|---|
max-tip | 500000 | lamports | Hard ceiling — agent cannot recommend above this regardless of network conditions |
max-tip-ratio | 5.0 | % | Tip cannot exceed N% of the transaction’s transfer value |
tip-percentile | p75 | — | Percentile the agent targets when the network is calm (p50 / p75 / p95 / p99) |
stale-after | 2000 | ms | Maximum age of tip oracle data before the agent refuses to proceed |
Bundle & retry controls
| Key | Default | Unit | Description |
|---|
max-retries | 3 | — | Maximum re-submission attempts before a bundle is declared expired |
expiry-slots | 150 | slots | How many slots past enqueue the agent keeps retrying before dropping the bundle |
escalation-step | 5000 | lamports | Maximum tip increase per retry cycle — prevents runaway escalation |
max-queue | 20 | — | Maximum in-flight bundles at any time — new enqueues are rejected above this |
Throughput controls
| Key | Default | Unit | Description |
|---|
rate-limit | 60 | /min | Maximum transactions accepted per minute across all callers |
priority | auto | — | Pin all bundles to a tier (normal / high / urgent) or let the agent decide (auto) |
Commands
sinker policy set <key> <value>
Set a single policy value. The change is written to sinker.policy.json immediately.
sinker policy set max-tip 100000
sinker policy set tip-percentile p95
sinker policy set priority high
sinker policy set max-retries 5
set max-tip = 100000
saved → sinker.policy.json
The stack must be restarted for the new value to take effect.
sinker policy show
Print all policy values as a table — current effective value, built-in default, and which keys have been explicitly set.
┌─ Policy ─────────────────────────────────────────────────────────────────
│ KEY CURRENT DEFAULT
│ ──────────────────────────────────────────────────────────────────────
│ max-tip 100000L 500000L ← set
│ max-tip-ratio 5.0% 5.0%
│ tip-percentile p75 p75
│ stale-after 2000ms 2000ms
│ max-retries 3 3
│ expiry-slots 150 150
│ escalation-step 5000L 5000L
│ max-queue 20 20
│ rate-limit 60/min 60/min
│ priority auto auto
│ ──────────────────────────────────────────────────────────────────────
│ file: sinker.policy.json (1 override)
└──────────────────────────────────────────────────────────────────────────
sinker policy reset [<key>]
Reset a single key back to its built-in default, or reset all keys if no key is given.
# Reset one key
sinker policy reset max-tip
# Reset everything
sinker policy reset
reset without a key writes an empty {} JSON file — all keys will resolve to defaults on next start. The file itself is kept; use sinker policy clear to delete it entirely.
sinker policy clear
Delete the policy file. All settings revert to built-in defaults on the next sidecar or agent start.
delete sinker.policy.json? All settings revert to defaults on next start. [y/N]
Pass --yes / -y to skip the confirmation prompt (useful in CI or setup scripts):
sinker policy clear --yes
sinker policy validate
Check the current effective policy for contradictions and dangerous values.
Errors (exit code 1 — block correct operation):
| Condition | Error |
|---|
escalation-step > max-tip | Every retry would immediately exceed the tip ceiling |
max-tip = 0 | Jito requires a non-zero tip — all bundles will be rejected |
max-tip-ratio ≤ 0 | Invalid — would block all tips |
expiry-slots = 0 | Bundles expire immediately and can never be submitted |
max-queue = 0 | All enqueues will be rejected |
Warnings (informational — do not exit non-zero):
| Condition | Warning |
|---|
stale-after < 400ms | Shorter than one Solana slot — oracle may always appear stale |
max-tip-ratio > 100% | Tip can exceed the transaction value |
max-retries = 0 | Failed bundles will not be retried |
rate-limit = 0 | All incoming transactions will be rejected |
Example output with issues:
validating policy from sinker.policy.json
✗ error: escalation-step (600000L) > max-tip (500000L): every retry would immediately exceed the tip ceiling
⚠ warning: stale-after (200ms) is shorter than one slot (~400ms): tip oracle may always appear stale
1 error(s) found — run `sinker policy set` to fix before starting the stack
sinker policy export [--path <file>]
Export the current effective policy — with all defaults resolved — to a JSON file. Unlike the live policy file (which only stores overrides), the export includes every key. Useful for sharing a policy between Sinker deployments.
# Export to the default path (sinker.policy.json)
sinker policy export
# Export to a custom path
sinker policy export --path /shared/prod.policy.json
policy exported → /shared/prod.policy.json
all 10 keys written (defaults resolved)
The exported file can be applied on another machine with sinker policy import.
sinker policy import <file>
Load a policy JSON file, validate it, and apply it as the active policy. Errors block the import; warnings are printed but do not block it.
sinker policy import /shared/prod.policy.json
imported /shared/prod.policy.json → sinker.policy.json
restart the stack to apply the new policy
If validation errors are found, the import is aborted and the existing policy is left unchanged:
✗ error: max-queue is 0: all enqueues will be rejected
import aborted — 1 error(s) found in '/shared/prod.policy.json'. Fix and retry.
Storage and load order
The policy file is looked up in this order on every sinker start or sinker up:
- Path in
SINKER_POLICY_FILE env var — custom override
./sinker.policy.json — working directory
- Built-in defaults — no file required, no warning
# Use a shared policy file across multiple deployments
SINKER_POLICY_FILE=/etc/sinker/policy.json sinker start
The file format is plain JSON. Keys not present resolve to defaults — you only need to store values you change:
{
"max_tip_lamports": 100000,
"tip_percentile": "p75",
"priority": "high"
}
Recommended starting policy
For most production deployments, a conservative starting point:
sinker policy set max-tip 200000 # cap at 200k lamports (~0.0002 SOL)
sinker policy set max-tip-ratio 3 # tip cannot exceed 3% of tx value
sinker policy set escalation-step 5000 # raise by at most 5k lamports per retry
sinker policy set max-retries 4 # up to 4 re-submissions per bundle
sinker policy set max-queue 30 # allow up to 30 in-flight bundles
sinker policy validate # confirm no contradictions