Skip to content

Commit e9c8da0

Browse files
Illia Pashkovclaude
authored andcommitted
feat: benchmarks, tokenomics, issue templates, OATR registration
- packages/policy-gateway/bench/gateway-perf.bench.ts: PolicyGateway latency benchmarks (T0–T3, expired deny, 100-item batch). Results: T0_observe ~1.9ms mean, ~3ms p99 (Ed25519 verify bottleneck). Run with: pnpm run bench - docs/TOKENOMICS.md: billing formula, action cost table, budget enforcement, fraud prevention, revenue split (grounded in pricing-calculator.ts) - .github/ISSUE_TEMPLATE/: bug_report, feature_request, bridge_conformance templates to bootstrap community contributions - CLAUDE.md: add pnpm run bench to Quick Commands Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fec55fe commit e9c8da0

9 files changed

Lines changed: 436 additions & 3 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
name: Bridge conformance report
3+
about: Report that a new system passes/fails SINT conformance tests
4+
labels: conformance
5+
---
6+
7+
**System under test**: (e.g. ROS 2 Humble, MAVLink 2.0)
8+
**Bridge package**: (e.g. @sint/bridge-ros2)
9+
**Conformance suite**: (e.g. @sint/conformance-tests v0.2)
10+
11+
**Test results**:
12+
- [ ] All tests pass
13+
- [ ] Partial pass (list failures below)
14+
- [ ] Fails (list failures below)
15+
16+
**Failures** (if any):
17+
18+
**Notes / deviations from spec**:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: Bug report
3+
about: Something isn't working as expected
4+
labels: bug
5+
---
6+
7+
**Package**: (e.g. @sint/gate-policy-gateway)
8+
**Version**:
9+
**TypeScript version**:
10+
11+
**Describe the bug**
12+
13+
**Minimal reproduction** (paste a test case or code snippet)
14+
15+
**Expected behavior**
16+
17+
**Actual behavior** (include error message / stack trace)
18+
19+
**Environment** (OS, Node.js version)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
name: Feature request
3+
about: Propose a new capability or bridge
4+
labels: enhancement
5+
---
6+
7+
**Problem / use case**
8+
9+
**Proposed solution**
10+
11+
**Which package(s) would this affect?**
12+
13+
**Alternative approaches considered**
14+
15+
**Are you willing to submit a PR?** [ ] Yes [ ] No

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pnpm run build # Build all packages (required before test)
1414
pnpm run test # Run all tests (currently 974 passing)
1515
pnpm run typecheck # Type-check without emitting
1616
pnpm run clean # Remove build artifacts
17+
pnpm run bench # Run PolicyGateway performance benchmarks (p50/p99 latency)
1718
```
1819

1920
Run a single package:

docs/TOKENOMICS.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# SINT Protocol — Tokenomics
2+
3+
This document describes how SINT's economic layer works. It is grounded in the
4+
implementation in `packages/bridge-economy/` and is intentionally free of
5+
on-chain or Solana specifics (those live outside `sint-protocol`).
6+
7+
---
8+
9+
## 1. Token Unit
10+
11+
SINT uses an **integer token** — no fractional units. All costs and balances are
12+
whole numbers.
13+
14+
| Constant | Value | Source |
15+
|---|---|---|
16+
| `TOKENS_PER_DOLLAR` | 250 | `pricing-calculator.ts` |
17+
| `INITIAL_USER_BALANCE` | 250 tokens | `pricing-calculator.ts` |
18+
| Launch pricing | 1 token ≈ $0.001 | 1 / TOKENS_PER_DOLLAR |
19+
20+
New users start with 250 tokens ($1.00 equivalent), enough for ~27 default MCP
21+
tool calls before recharging.
22+
23+
---
24+
25+
## 2. Billing Formula
26+
27+
Every action that passes `PolicyGateway.intercept()` has a cost computed by
28+
`computeActionCost()` in `packages/bridge-economy/src/pricing-calculator.ts`:
29+
30+
```
31+
cost = ceil(baseCost × costMultiplier × globalMarkupMultiplier)
32+
```
33+
34+
| Parameter | Default | Notes |
35+
|---|---|---|
36+
| `baseCost` | 6 tokens | MCP/tool call |
37+
| `costMultiplier` | 1.0 | Per-resource or MCP marketplace rate |
38+
| `globalMarkupMultiplier` | 1.5 | `GLOBAL_MARKUP_MULTIPLIER` constant |
39+
| **Default MCP result** | **9 tokens** | `ceil(6 × 1.0 × 1.5)` |
40+
41+
The `costMultiplier` comes from `IPricingPort.getPrice()`. If the pricing port is
42+
absent or returns an error, `costMultiplier` defaults to 1.0 (fail-open).
43+
44+
---
45+
46+
## 3. Action Cost Table
47+
48+
Costs are derived from the base constants in `pricing-calculator.ts`. Tier
49+
labels align with the SINT approval tier system (T0–T3).
50+
51+
| Tier | Action type | Base cost | Typical multiplier | **Token cost** |
52+
|---|---|---|---|---|
53+
| T0 — Observe | Read/query (sensor, subscribe) | 4–6 | 1.0 | **~6–9** |
54+
| T1 — Prepare | Low-impact write (save waypoint, file write) | 6 | 1.0 | **9** |
55+
| T2 — Act | Physical state change (ROS 2 topic publish) | 8 | 1.0 | **12** |
56+
| T3 — Commit | Capsule execution, irreversible action | 12 | 1.0 | **18** |
57+
58+
The 3x tier escalation in the design spec (1 → 3 → 9 → 27 tokens) reflects a
59+
conceptual pricing model where each approval tier costs three times the previous.
60+
The actual constants produce a shallower curve because the billing system
61+
differentiates by *action category*, not purely by tier label.
62+
63+
Physical-domain bridges carry higher multipliers:
64+
65+
| Bridge / resource prefix | Typical `costMultiplier` |
66+
|---|---|
67+
| MCP tool call (default) | 1.0 |
68+
| ROS 2 publish (`ros2://`) | 1.0–2.0 |
69+
| MAVLink command | 2.0–5.0 |
70+
| Capsule execution (`capsule://`) | 1.0–3.0 |
71+
72+
---
73+
74+
## 4. Budget Enforcement
75+
76+
Budget enforcement runs in `EconomyPlugin.preIntercept()`, called before
77+
`PolicyGateway` assigns tiers.
78+
79+
### Per-agent budget cap
80+
81+
Each agent has a total budget cap managed by `IBudgetPort`. Before an action
82+
executes:
83+
84+
1. `checkBudget({ userId, action, resource, estimatedCost })` is called.
85+
2. If `allowed === false` → the plugin returns a `deny` decision immediately.
86+
3. If `usagePercent > 80` → a `economy.budget.alert` event is emitted to the
87+
evidence ledger.
88+
89+
### Session-level collective spend cap
90+
91+
The design supports a `maxCollectiveSpend` field in a `CollectiveConstraintManifest`
92+
that limits total token spend across all agents in a multi-agent session. This is
93+
a planned constraint; the per-agent `IBudgetPort` is the current enforcement
94+
boundary.
95+
96+
---
97+
98+
## 5. Balance Model
99+
100+
Agents carry a token balance maintained by `IBalancePort`.
101+
102+
**Flow for every request:**
103+
104+
```
105+
preIntercept:
106+
1. computeActionCost(request) → tokens
107+
2. IBudgetPort.checkBudget() → deny if budget exceeded
108+
3. IBalancePort.getBalance() → deny if balance < tokens
109+
4. ITrustPort.evaluateTrust() → deny if blocked, escalate if high_risk
110+
111+
postIntercept (only when decision === "allow"):
112+
IBalancePort.withdraw(userId, tokens, description, "sint_protocol")
113+
```
114+
115+
The balance check happens **before** any physical action executes. A balance
116+
shortfall produces a `deny` — not an escalation. The ledger receives
117+
`economy.balance.insufficient` and `economy.action.billed` events.
118+
119+
Both the budget check and balance check are fail-open: if the port is
120+
unreachable, the request proceeds through normal gateway logic.
121+
122+
---
123+
124+
## 6. Fraud Prevention
125+
126+
### Rate limiting
127+
128+
Capability tokens carry `constraints.rateLimit.{ maxCalls, windowMs }`.
129+
`PolicyGateway` counts calls per token against a `RateLimitStore`. Exceeding
130+
`maxCalls` within `windowMs` results in an immediate deny
131+
(`RATE_LIMIT_EXCEEDED`). This is enforced in the security layer, independently
132+
of economy billing.
133+
134+
### Circuit breaker
135+
136+
`CircuitBreakerPlugin` tracks denial counts per agent. After `N` consecutive
137+
denials the circuit trips to `OPEN` and all subsequent requests are denied
138+
without evaluation. This prevents abusive retry loops from consuming gateway
139+
resources or economy-service quota.
140+
141+
### Balance insufficient → deny, not escalate
142+
143+
An `InsufficientBalanceError` always produces `action: "deny"` with
144+
`policyViolated: "INSUFFICIENT_BALANCE"`. The gateway will not escalate to a
145+
human approver for economic failures — there is nothing a human can authorise
146+
that would fix a zero balance.
147+
148+
---
149+
150+
## 7. Revenue Split (Design)
151+
152+
When tokens are spent by an agent, the protocol's intent is:
153+
154+
| Recipient | Share |
155+
|---|---|
156+
| Operator (MCP server / bridge host) | 70% |
157+
| Protocol treasury | 20% |
158+
| Safety reserve fund | 10% |
159+
160+
This split is aspirational design. The current implementation performs a single
161+
`IBalancePort.withdraw()` call; distribution to operator, treasury, and safety
162+
reserve is handled by the external economy service that implements `IBalancePort`,
163+
not by `sint-protocol` itself.
164+
165+
---
166+
167+
## 8. What This Document Does Not Cover
168+
169+
- **On-chain mechanics** — Solana token programme, SPL accounts, DEX liquidity.
170+
These are defined in the `sint-ai-workspace` context, outside this repository.
171+
- **Fiat on-ramp / off-ramp** — also external.
172+
- **MCP marketplace pricing catalogue** — operator-set `costMultiplier` values
173+
per MCP server are resolved at runtime via `IPricingPort`; no static list is
174+
maintained here.
175+
176+
---
177+
178+
*Last updated: 2026-04-04. Tied to `@sint/bridge-economy` v0.2.*

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"demo": "pnpm --filter @sint/conformance-tests exec vitest run src/e2e-demo.test.ts --reporter=verbose",
1414
"cert:fixtures": "pnpm --filter ./packages/policy-gateway build && pnpm --filter ./packages/conformance-tests run test:fixtures && pnpm --filter ./packages/bridge-iot run test:fixtures && pnpm --filter ./sdks/typescript run test:contracts && pnpm --filter ./packages/persistence-postgres run test:fixtures",
1515
"benchmark:industrial": "pnpm --filter @sint/conformance-tests exec vitest run src/industrial-interoperability.test.ts src/industrial-benchmark-scenarios.test.ts --reporter=verbose",
16-
"benchmark:report": "node ./scripts/generate-industrial-benchmark-report.mjs"
16+
"benchmark:report": "node ./scripts/generate-industrial-benchmark-report.mjs",
17+
"bench": "pnpm --filter @sint/gate-policy-gateway bench"
1718
},
1819
"devDependencies": {
1920
"@types/node": "^22.13.0",

0 commit comments

Comments
 (0)