taximeter 0.1.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Taximeter
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Announce legacy ledger migration and save a standalone, WAL-aware schema-1 backup before upgrading. Abort the upgrade if the backup fails, retain completed backups for rollback, and document recovery using a separate database path. Extend the reproducible ledger benchmark to cover larger histories and task/agent partition counts.
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Default to rejecting parsed payments for unknown assets. Set `policy.unknownAsset` to `allow` to opt in and configure exact contract-address budgets for custom tokens.
14
+
15
+ Replace full ledger replay during payment gating with transactional, rebuildable payment projections and exact timestamp-indexed budget sums. Preserve append-only source records, retry and settlement semantics, and precise rolling-window boundaries. Existing databases migrate to schema version 2 when opened; older 0.1.x clients cannot reopen the migrated schema.
16
+
3
17
  ## 0.1.2
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -51,7 +51,7 @@ Open a terminal in this source checkout, with Node 20+ and npm installed.
51
51
  You should now see:
52
52
 
53
53
  ```text
54
- Taximeter 0.1.2
54
+ Taximeter 0.2.1
55
55
  Proxy: http://127.0.0.1:8402
56
56
  Dashboard: http://127.0.0.1:8403
57
57
  Point an HTTP-proxy-aware agent at http://127.0.0.1:8402.
@@ -116,6 +116,8 @@ their amount before forwarding the payment replay.
116
116
  Policy evaluation and reservation share one SQLite transaction, so concurrent
117
117
  payments cannot all consume the same remaining capacity.
118
118
  Append-only payment, outcome, and diagnostic records derive every total with BigInt.
119
+ Payment checks use an incrementally maintained index of exact budget sums, avoiding
120
+ a replay of all prior payments. The index can be rebuilt from the original log.
119
121
  The local dashboard polls that ledger every second and exports the same counted amounts.
120
122
 
121
123
  An initial 402 challenge is an offer, not spend. Reported settlement counts as
@@ -138,6 +140,22 @@ as text to prevent a spreadsheet application from rounding them.
138
140
 
139
141
  ## Configuration
140
142
 
143
+ When upgrading from 0.1.x, upgrade all writers together. Opening an existing
144
+ ledger prints `Migrating ledger…`, saves a standalone schema-1 backup beside it
145
+ at `<database>.backup-v1-<unique suffix>/ledger.db`, and prints the backup path
146
+ before building the budget index. The backup includes committed WAL records;
147
+ if it cannot be completed, the upgrade stops. Large ledgers take longer on this
148
+ first open. Fresh databases and already-upgraded ledgers do not create backups.
149
+
150
+ The source log is preserved, but older 0.1.x clients cannot reopen the upgraded
151
+ database. To roll back, stop all CLI and SDK writers, copy the saved `ledger.db`
152
+ to a **new database path**, and start 0.1.x with `--db` pointing there. Keep the
153
+ upgraded database: the backup does not contain payments made after migration.
154
+ Backups are retained until you remove them; a `ledger.partial.db` file means the
155
+ backup did not finish and must not be used for rollback. Progress goes to stderr,
156
+ so JSON report/export output stays machine-readable. Parsed unknown assets now
157
+ require an explicit opt-in as described below.
158
+
141
159
  No file is required. Start from [the example](taximeter.config.example.json) when
142
160
  needed. Precedence, highest first: flags, environment, explicit `--config` file,
143
161
  `taximeter.config.json` in the working directory, `~/.taximeter/config.json`, defaults.
@@ -158,6 +176,7 @@ invalid values are rejected with Zod.
158
176
  | `policy.allowPayTo` | `[]` | Empty allows all recipients; otherwise exact case-insensitive addresses. |
159
177
  | `policy.maxSinglePayment` | `"1000000"` | One USDC per authorization by default; `null` disables the cap. |
160
178
  | `policy.maxSingleAsset` | `USDC` | Asset to which the single-payment cap applies. |
179
+ | `policy.unknownAsset` | `"deny"` | `deny` blocks parsed payments whose network and contract are absent from the offline asset registry; `allow` opts in to those assets. |
161
180
  | `ports.proxy` | `8402` | Loopback HTTP listener; `0` selects an available port. |
162
181
  | `ports.dashboard` | `8403` | Loopback dashboard listener; `0` selects an available port. |
163
182
  | `db` | `~/.taximeter/ledger.db` | SQLite path; relative paths resolve against the working directory. |
@@ -168,9 +187,16 @@ All commands accept `--db` and `--config`. Start also accepts `--proxy-port`,
168
187
  `TAXIMETER_PORT`, and `TAXIMETER_DASHBOARD_PORT`.
169
188
 
170
189
  Missing task/agent labels share an **Unattributed** bucket. Supply `Taximeter-Task`
171
- and `Taximeter-Agent` headers, or SDK options. The local USDC registry recognizes
172
- Base and Base Sepolia; other contracts remain separate atomic-unit balances with
173
- unknown decimals. Default USDC budgets do not cap unknown assets.
190
+ and `Taximeter-Agent` headers, or SDK options. The offline asset registry recognizes
191
+ USDC by its network and contract on Base and Base Sepolia. Parsed payments for
192
+ other assets are denied by default with `unknown_asset`; supplied symbols or
193
+ decimal metadata cannot make a token known. Unsupported or unparseable payment
194
+ formats still pass through with a diagnostic.
195
+
196
+ Custom-token budgets require `policy.unknownAsset: "allow"`. This opts in to parsed
197
+ unknown assets, which remain separate atomic-unit balances with unknown decimals.
198
+ Configure budgets using the exact contract address and, when needed, its network.
199
+ Default USDC budgets do not cap these assets; only matching budgets and caps apply.
174
200
 
175
201
  A denied replay receives HTTP 402 before it reaches the upstream. For a cap of
176
202
  140 atomic units already fully consumed, the response is:
@@ -185,9 +211,10 @@ A denied replay receives HTTP 402 before it reaches the upstream. For a cap of
185
211
  }
186
212
  ```
187
213
 
188
- Reasons are `host_denied`, `host_not_allowed`, `recipient_not_allowed`,
214
+ Reasons are `host_denied`, `host_not_allowed`, `recipient_not_allowed`, `unknown_asset`,
189
215
  `max_single_payment`, `per_task_budget`, `per_agent_budget`, and `global_budget`.
190
- Host/recipient denials have `budget: null` and `remaining: null`.
216
+ Host, recipient, and unknown-asset denials have `budget: null`, `spent: "0"`, and
217
+ `remaining: null`.
191
218
 
192
219
  ## What this is not
193
220
 
package/SECURITY.md CHANGED
@@ -7,7 +7,7 @@ on-chain settlement.
7
7
 
8
8
  ## Supported version
9
9
 
10
- Security fixes currently target the `0.1.0` release line. No older release line
10
+ Security fixes currently target the `0.2.x` release line. No older release line
11
11
  is maintained. This policy describes support; it is not a claim that the package
12
12
  has already been published or independently audited.
13
13
 
@@ -32,6 +32,9 @@ against a hostile agent or another process running as the same user.
32
32
  - Unsupported or malformed payment forms pass through with a diagnostic.
33
33
  Supported parsing is narrower than the full x402 protocol; see
34
34
  [protocol notes](https://github.com/Ding808/taximeter/blob/main/SPEC-NOTES.md).
35
+ - Parsed payments outside the offline asset registry are denied by default.
36
+ Setting `policy.unknownAsset` to `allow` permits them; only matching contract
37
+ budgets and caps then apply. Metadata supplied with a payment does not make its asset trusted.
35
38
  - HTTPS CONNECT tunnels encrypted bytes without metering their payments.
36
39
  Taximeter does not install a certificate authority or intercept TLS.
37
40
  - The SDK must wrap the transport inside the payment wrapper. Redirects and