taximeter 0.1.1 → 0.2.0

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.
@@ -6,7 +6,7 @@
6
6
  <meta name="color-scheme" content="light dark" />
7
7
  <meta name="description" content="A taximeter for your AI agents. Your local payment ledger." />
8
8
  <title>Taximeter — Local ledger</title>
9
- <script type="module" crossorigin src="/assets/index-BQ3Ivj0y.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-BFxfiuVt.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="/assets/index-De4zKRDL.css">
11
11
  </head>
12
12
  <body>
package/docs/SDK.md CHANGED
@@ -8,7 +8,7 @@ Install the registry release with `npm install taximeter`. From a source checkou
8
8
  run `npm ci` and `npm run build`, then save the examples at the repository root.
9
9
  Their `import "taximeter"` statements resolve the package's own built exports.
10
10
  To try a local build in another project, run `npm pack`, copy the resulting
11
- tarball there, and use `npm install ./taximeter-0.1.1.tgz`.
11
+ tarball there, and use `npm install ./taximeter-0.2.0.tgz`.
12
12
 
13
13
  ## Try it locally
14
14
 
@@ -132,11 +132,24 @@ environment, with explicit SDK options taking precedence. See the
132
132
  files or environment settings. Keep budgets consistent across writers sharing
133
133
  the same database.
134
134
 
135
+ `config.policy.unknownAsset` defaults to `"deny"`. Only network and contract pairs
136
+ in Taximeter's offline asset registry are known; payment-supplied symbols and
137
+ decimal metadata do not establish trust. To use custom-token budgets, explicitly
138
+ set `config.policy.unknownAsset` to `"allow"` and configure the matching contract
139
+ and network budget. This permits parsed unknown assets; the default USDC budgets
140
+ do not cap them.
141
+
135
142
  The wrapper closes only a ledger it created. For an injected ledger, close all
136
143
  wrappers after their requests finish, then let the owner close the ledger.
137
144
  Reusing a closed wrapper passes requests directly to the original transport
138
145
  without metering. Do not use a closed wrapper for later payments.
139
146
 
147
+ Version 0.2.0 upgrades existing ledgers to schema version 2 when opening them.
148
+ Source events and outcomes remain unchanged; the added budget index is rebuilt
149
+ from those records. Upgrade all writers together. Older 0.1.x clients cannot
150
+ reopen a migrated database. `ledger.rebuildCache()` repairs the derived index
151
+ from the append-only log inside a transaction.
152
+
140
153
  ## Fetch behavior and limits
141
154
 
142
155
  - Use a Node fetch implementation that accepts standard `string`, `URL`, or
@@ -159,6 +172,9 @@ without metering. Do not use a closed wrapper for later payments.
159
172
  returns a 402 JSON response with `error: "blocked_by_taximeter"`, `reason`,
160
173
  `budget`, `spent`, and `remaining`, and records a blocked event. The enclosing
161
174
  payment client can apply its own response handling or throw its own error.
175
+ - A parsed unknown asset is denied by default with `reason: "unknown_asset"`,
176
+ `budget: null`, `spent: "0"`, and `remaining: null`. Unsupported or unparseable
177
+ payment formats still pass through with a diagnostic.
162
178
  - If the transport throws after forwarding an authorization, the original
163
179
  error is rethrown and the authorization remains reserved with unknown
164
180
  settlement. Missing settlement evidence has the same conservative treatment.
@@ -171,8 +187,9 @@ without metering. Do not use a closed wrapper for later payments.
171
187
  The initial adapter meters exact EVM EIP-3009 payments: legacy v1 on Base and
172
188
  Base Sepolia, and v2 with EVM CAIP-2 networks. Permit2, ERC-7710, other schemes,
173
189
  and other rails remain unmetered. Known Base/Base Sepolia USDC uses six decimal
174
- places; unknown tokens remain exact atomic units. Budgets and totals are
175
- separate for every network and asset. See [SPEC-NOTES](../SPEC-NOTES.md) for
190
+ places; explicitly allowed unknown tokens remain exact atomic units. Budgets and totals are
191
+ separate for every network and asset. See
192
+ [protocol notes](https://github.com/Ding808/taximeter/blob/main/SPEC-NOTES.md) for
176
193
  wire formats, challenge correlation, idempotency, and settlement rules.
177
194
 
178
195
  ## Read the same ledger from the CLI
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taximeter",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "A taximeter for your AI agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,15 +28,10 @@
28
28
  "README.md",
29
29
  "LICENSE",
30
30
  "SECURITY.md",
31
- "CONTRIBUTING.md",
32
- "CODE_OF_CONDUCT.md",
33
31
  "CHANGELOG.md",
34
- "DECISIONS.md",
35
- "VERIFICATION.md",
36
- "SPEC.md",
37
- "SPEC-NOTES.md",
38
32
  "taximeter.config.example.json",
39
- "docs"
33
+ "docs/SDK.md",
34
+ "docs/demo.gif"
40
35
  ],
41
36
  "scripts": {
42
37
  "typecheck": "tsc --noEmit",
@@ -9,7 +9,8 @@
9
9
  "denyHosts": [],
10
10
  "allowPayTo": [],
11
11
  "maxSinglePayment": "1000000",
12
- "maxSingleAsset": "USDC"
12
+ "maxSingleAsset": "USDC",
13
+ "unknownAsset": "deny"
13
14
  },
14
15
  "ports": { "proxy": 8402, "dashboard": 8403 },
15
16
  "db": "~/.taximeter/ledger.db"
@@ -1,31 +0,0 @@
1
- # Code of conduct
2
-
3
- Taximeter welcomes contributions from people with different backgrounds,
4
- identities, abilities, and levels of experience. Everyone participating in
5
- project issues, pull requests, reviews, and discussions must treat others with
6
- respect.
7
-
8
- Discuss the work, explain your reasoning, and accept corrections when the
9
- evidence changes. Give useful feedback without personal attacks. Respect other
10
- people's time and their right to decline a request. Ask before sharing private
11
- messages or personal information.
12
-
13
- Harassment, threats, discriminatory remarks, sexualized attention, doxxing,
14
- impersonation, and repeated unwanted contact are not acceptable. Disagreement
15
- about a technical decision does not justify abuse. These expectations apply
16
- when someone represents the project outside the repository as well.
17
-
18
- Maintainers may edit or remove harmful content, close disruptive conversations,
19
- restrict participation, or ban a participant. They should explain an action
20
- when doing so is appropriate and avoid exposing private information. Decisions
21
- should consider the behavior, its impact, and whether it is repeated.
22
-
23
- Use GitHub's reporting controls to report harmful content. For sensitive
24
- concerns, contact a maintainer through an available private channel; do not post
25
- personal details in a public issue. Reports should include the relevant links
26
- and enough context to understand what happened. Maintainers should share a
27
- report only with people needed to address it and must not retaliate against
28
- someone for reporting a concern in good faith.
29
-
30
- This is the project's own conduct policy. Security vulnerabilities have a
31
- separate private reporting process in [SECURITY.md](SECURITY.md).
package/CONTRIBUTING.md DELETED
@@ -1,141 +0,0 @@
1
- # Contributing to Taximeter
2
-
3
- Taximeter observes agent payments, records them locally, and gates supported
4
- authorizations against budgets. Start with [SPEC.md](SPEC.md), then read
5
- [SPEC-NOTES.md](SPEC-NOTES.md) for the supported protocol and
6
- [DECISIONS.md](DECISIONS.md) for implementation choices.
7
-
8
- ## Development
9
-
10
- Use Node.js 20 or 22 and npm. The package is TypeScript with ESM exports. CI is
11
- configured for both Node versions on Linux and Windows. Dependencies and tooling
12
- are pinned; keep `package-lock.json` consistent with `package.json`.
13
-
14
- From a checkout, run the same sequence as CI:
15
-
16
- ```sh
17
- npm ci
18
- npm run typecheck
19
- npm run lint
20
- npm test
21
- npm run build
22
- npm pack
23
- npm run check:package
24
- npm run smoke:package
25
- git status --porcelain
26
- ```
27
-
28
- The build creates the Node package in `dist/` and the prebuilt React dashboard in
29
- `dist/ui/`. A package consumer must not need to build the dashboard. On a clean
30
- checkout, the final command must print nothing. During development, it should
31
- show only your intentional changes. Do not commit generated bundles, coverage,
32
- tarballs, local configuration, or SQLite state.
33
-
34
- Use `npm run format` to apply Biome formatting. Keep LF line endings as specified
35
- in `.gitattributes`. Check the package contents and compressed size with
36
- `npm pack --dry-run`; the release tarball must stay below 2 MB.
37
-
38
- ## Changes that preserve trust
39
-
40
- - Preserve unknown HTTP traffic byte for byte. Record a diagnostic when a format
41
- cannot be parsed; do not guess the payment fields or rewrite its payload.
42
- - Store monetary amounts as integer strings. Use `BigInt` for arithmetic and
43
- convert to a display string only at the rendering edge. Never combine assets
44
- or networks, infer exchange rates, or use floating point for money.
45
- - Parse external inputs with Zod. Keep strict TypeScript types and
46
- `noUncheckedIndexedAccess`; do not introduce `any` to silence a type error.
47
- - Keep policy and ledger derivations pure and synchronous. Evaluate policy and
48
- reserve capacity within the same SQLite transaction before forwarding.
49
- - Keep events and outcomes append-only. Preserve uncertainty, retry identity,
50
- concurrent attempt accounting, and original attribution.
51
- - Never add custody, private-key handling, payment signing, settlement,
52
- telemetry, hosted accounts, or runtime metadata lookups. Runtime networking
53
- is limited to forwarding the caller's traffic and the local dashboard.
54
-
55
- Read the primary x402 specification and published package types before changing
56
- a wire parser. Record changed assumptions and supported subsets in
57
- `SPEC-NOTES.md`. An internal model field is not necessarily a protocol field.
58
-
59
- ## Tests and review
60
-
61
- For policy changes, write the failing behavioral test first. Add regressions for
62
- traffic corruption, arithmetic, replay, concurrency, and settlement failures when
63
- changing those paths. Keep policy and ledger coverage at least 90%; coverage is
64
- a floor, not a substitute for asserting observable behavior.
65
-
66
- Fixtures use synthetic authorizations and localhost servers. Tests must not
67
- require wallets, keys, funds, a facilitator, or an external API. Keep cleanup
68
- bounded to directories created by the test. Dashboard changes should be checked
69
- in light and dark themes at both desktop and narrow mobile widths.
70
-
71
- Golden CSV snapshots live in `test/__snapshots__/`. Regenerate a snapshot only
72
- for an intentional output change that is explained in the pull request and
73
- accepted in review. Never update a snapshot, remove a test, or relax an assertion
74
- simply to make a failure disappear.
75
-
76
- Open a focused pull request with the problem, resulting behavior, and actual
77
- validation results. Explain compatibility changes and known limitations. Use
78
- Conventional Commits, such as `fix(proxy): preserve response trailers`. Update
79
- the relevant docs when behavior or configuration changes. Report vulnerabilities
80
- privately as described in [SECURITY.md](SECURITY.md).
81
-
82
- ## Versioning and releases
83
-
84
- For a user-visible change, run `npm run changeset` and commit the generated
85
- changeset with the change. Describe its effect on users and choose the appropriate
86
- version bump. Documentation-only changes may omit a changeset when they do not
87
- change package behavior.
88
-
89
- The release workflow uses Changesets on `main` to prepare version changes and
90
- publish after the release pull request is merged. With no pending changesets,
91
- the action also publishes the current version if npm does not yet contain it.
92
- A push to `main` with working npm credentials can therefore publish directly.
93
- Maintainers configure npm credentials separately.
94
- `npm run version-packages` updates package versions and
95
- the changelog; `npm run release` builds and runs Changesets publishing. Publishing
96
- requires maintainer authorization and credentials. The presence of that workflow
97
- does not mean any package version has already been published.
98
-
99
- ### npm publishing credentials
100
-
101
- The current workflow uses token authentication. Create an npm **granular access
102
- token** with package **Read and write** permissions and **Bypass two-factor
103
- authentication** enabled for unattended publishing. Give it permission to publish
104
- the intended package and an appropriate expiration. Follow the
105
- [npm token setup instructions](https://docs.npmjs.com/creating-and-viewing-access-tokens/).
106
-
107
- For the first publication of a new unscoped package, it cannot yet be selected
108
- individually in npm's token settings. A temporary bootstrap token needs the
109
- **All Packages** selection to permit creating it. Replace it with a token limited
110
- to `taximeter` after the package exists, or use trusted publishing for later releases.
111
-
112
- In the repository's **Settings → Secrets and variables → Actions**, add a
113
- **repository secret** named exactly `NPM_TOKEN`. Use the token as its value.
114
- An Actions variable or a Dependabot secret will not populate `secrets.NPM_TOKEN`.
115
- An environment secret needs a matching job environment; this workflow does not
116
- select one. Organization secrets must grant this repository access. See
117
- [GitHub's Actions secret instructions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions).
118
-
119
- `changesets/action@v1` configures npm authentication from this secret. Its publish
120
- hook checks that the secret is present and that npm accepts the credentials
121
- before building or publishing. This identity check does not prove package write
122
- permission or 2FA bypass; npm validates those during publication. Version PRs
123
- can still be prepared without npm credentials. Do not commit a token to `.npmrc`
124
- or paste one into an issue or chat.
125
-
126
- After adding or correcting the secret, rerun the failed Release job. A local
127
- `npm login` does not authenticate a GitHub-hosted runner. `ENEEDAUTH` combined
128
- with `No NPM_TOKEN or OIDC available` means the runner received no usable
129
- authentication; the successful build and dependency-comment warnings do not
130
- resolve that missing configuration.
131
-
132
- Trusted publishing is a separate setup, not enabled by adding `GITHUB_TOKEN`.
133
- It requires npm-side trust, a supported npm CLI, and `id-token: write` on the
134
- workflow. The present hook deliberately requires `NPM_TOKEN`; migrate both the
135
- hook and workflow together when adopting
136
- [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/).
137
- The package must already exist before trust can be configured; see the
138
- [npm trust prerequisites](https://docs.npmjs.com/cli/v11/commands/npm-trust/).
139
-
140
- Contributions are provided under the project's [MIT license](LICENSE). Follow the
141
- [code of conduct](CODE_OF_CONDUCT.md) in issues, reviews, and other project spaces.
package/DECISIONS.md DELETED
@@ -1,54 +0,0 @@
1
- # Decisions
2
-
3
- - 2026-09-08 — The hosted release log passed the build but failed with npm `ENEEDAUTH`; Changesets explicitly reported neither `NPM_TOKEN` nor OIDC. Keep the existing token-based authentication route and add a publish-only presence/identity check, preserving credential-free version PR creation. Document the exact repository-secret setup. A local code change cannot supply the owner's npm credential, and an identity check cannot attest package write permissions.
4
- - 2026-09-08 — Replace the SPEC §6 demo placeholder with a 20-second Windows terminal recording. Native ConPTY capture and the standalone agg renderer work without WSL. Only the compact GIF ships in the package; capture tools and intermediate files remain local development artifacts.
5
- - Release packaging includes all relative README/SDK/contributor documentation targets and the example configuration. The package checker verifies these links and the explicit whitelist; source trees, tests, local state, and UI source maps stay excluded.
6
- - The release workflow can publish the first unpublished version on a credentialed `main` push when no changesets remain. Contributor instructions identify this initial-release behavior; no push or registry publication is performed during local verification.
7
- - The demo's unpaid v2 challenge branch is exercised before its signed synthetic replays, including the required `resource.url`, so demonstration code follows the same verified protocol contract.
8
-
9
- Recorded through the implementation audit on **2026-09-08**. The consolidated
10
- deviation inventory and detailed protocol evidence are in
11
- [SPEC-NOTES.md](SPEC-NOTES.md#implemented-deviations-and-release-limits).
12
- This log records the reasons for those choices and corrections made during the
13
- build; successful verification output belongs in [VERIFICATION.md](VERIFICATION.md).
14
-
15
- - 2026-09-08 — Work follows SPEC §8 on `feat/taximeter-v0.1.0`; each numbered step gets a full passing suite and a Conventional Commit.
16
- - Pin better-sqlite3 12.8.0: version 13 requires Node 22, while this release promises Node 20 support.
17
- - ESM only: a second CJS runtime adds packaging complexity without serving the primary CLI or modern fetch integrations.
18
- - Runtime requests are limited to forwarding traffic and the local dashboard API. Development dependency installation and protocol research are build activities.
19
- - Biome's automatic configuration migration emitted `preset: none`; corrected it to `recommended` immediately so lint remains a real quality gate.
20
- - Initial dependency audit found advisories in uuid 11.1.0 and tsup's esbuild 0.27.x. Pin uuid 11.1.1 and override tsup's esbuild to 0.28.1; validate with the full suite and build. Keep Changesets 2.x for Node 20 compatibility.
21
- - SQLite adds append-only `outcomes` and `diagnostics` tables beside `events`; this preserves original payment authorizations while recording settlement uncertainty and parser diagnostics. The migration is bundled as text from the tracked SQL source.
22
- - Idempotency binds the network/asset/payer/nonce identity to immutable authorization details; conflicting authorizations receive separate conservative reservations rather than bypassing policy through nonce reuse.
23
- - Zod 4 applies inner defaults even through `.partial()`. Configuration patch schemas therefore have no defaults; a regression test verifies later layers cannot reset earlier sibling options.
24
- - Independent ledger tests initially expected checksum-case output and `settlement_unknown: true` on blocked rows. Correct those expectations: EVM identities are canonical lowercase, and a replay blocked before forwarding has no uncertain settlement. Exact-value and deduplication assertions remain intact.
25
- - Track individual forwarding attempts in append-only outcomes. Any unresolved attempt retains capacity; confirmation anywhere wins. An unconfirmed retry outside a rolling window must reacquire capacity, with `attemptedAt` separate from the original immutable timestamp.
26
- - Runtime storage failures fail open and emit a visible local stderr warning: preserving the agent's traffic is the stated highest priority. Budget guarantees require working local storage. The original reservation survives a failed outcome write.
27
- - CLI precedence is flags > environment > explicit `--config` file > cwd file > home file > defaults. Relative database paths resolve against cwd; `~` expands locally. Explicit config files layer rather than replace lower-priority settings.
28
- - `reset --yes` archives the database under an atomic CLI lock. Stop all SDK writers first; the CLI lock coordinates CLI instances, while SQLite coordinates payment reservations. Reports, exports, and doctor use an in-memory empty ledger when the requested path does not yet exist, avoiding accidental file creation.
29
- - CSV includes every derived payment row. `amount` is its counted contribution (zero for blocked rows and authorizations whose known attempts all failed); `authorizedAmount` preserves the original proposal. Sum `amount` separately by network/asset to reproduce dashboard ledger totals. Formula-like text cells are escaped; monetary cells remain exact integer strings. Invoice export is a standalone printable HTML statement, with no PDF generation or claim of independent settlement verification.
30
- - SDK inspection clones only legacy 402 bodies, capped at 64 KiB and 100 ms, then returns the original response object. Slow/oversized unknown challenges are diagnosed and passed through. Request bodies are never consumed by the meter. Put `withMeter` inside the payment wrapper so signed retries are visible.
31
- - Dashboard reads share the ledger derivations and exact CSV accounting. The loopback API rejects foreign Host/Origin values, cross-site requests, mutations, ambiguous duplicate query options, and paths outside its bundled UI directory.
32
- - Dashboard typography uses system grotesque and monospace stacks: remote Google Fonts would violate the runtime network invariant. Financial chart coordinates and proportional widths use BigInt and become strings only when rendered.
33
- - The SDK cannot observe redirects or retries inside the supplied fetch transport. Preserve transport behavior, diagnose visible redirects, and avoid correlating redirected v1 challenges to the initial URL. Host-sensitive callers can request `redirect: "error"` or expose each hop to the wrapper.
34
- - Release review found truncated rejected-upgrade responses could leave clients hanging. Add a failing regression first, then mirror the ordinary response's abort/error cleanup.
35
- - Preserve the original HTTP request path and query while validating the routing authority separately. WHATWG URL normalization of encoded dot segments would otherwise change opaque or signature-sensitive traffic; HTTP and upgrade regressions cover both proxy modes.
36
- - The first dashboard shows the latest 30 events and a trailing 24-hour timeline. Rows remain readable and tables scroll on shorter or narrow screens; exact totals and clear settlement labels take priority over fitting every row into every viewport.
37
-
38
- ## Scope and release audit
39
-
40
- - Support `exact` EVM EIP-3009 only: v1 `base` and `base-sepolia`, and v2 positive `eip155:<chain-id>` networks. Permit2, ERC-7710, and other transfer methods have different authorization semantics and stay transparent with diagnostics. Optional or variable-length signatures are structurally accepted according to the published 2.25.0 types; Taximeter never verifies them.
41
- - Bound v1 challenge context to URL, method, task, agent, Authorization, and Cookie, with a five-minute TTL and at most 1,000 contexts per intake instance. Require an unambiguous matching asset. This avoids inventing missing replay fields or sharing challenges across distinct request identities. The SDK does not cache redirected challenges under the original URL.
42
- - Limit inspected v1 bodies to 64 KiB and encoded payment header text to 65,536 characters. The SDK additionally stops challenge observation after 100 ms. The proxy streams its bounded body tap without holding the response; compressed legacy challenges pass through unmetered. These limits prioritize intact, responsive traffic over metering every possible challenge.
43
- - Keep local metadata only for Base and Base Sepolia USDC. Unknown assets use exact atomic strings with `decimalsKnown: false`; `decimals: 0` is an internal placeholder, never a token-metadata claim. Runtime metadata, RPC, and price calls would violate the network invariant.
44
- - Keep every budget separate by network and asset contract. `maxSingleAsset: "USDC"` makes the scalar per-payment cap's scope explicit, and optional budget `network` narrows a rule. Add nullable budgets/caps and fixed `1h`, `24h`, `7d`, and `30d` windows without introducing exchange rates or cross-chain combined balances.
45
- - Matching settlement evidence must use the event's network and, when provided, its payer and amount. A reported success with a nonempty transaction can confirm on any response status; an explicit failure on a 5xx remains uncertain. Missing evidence, disconnects, and malformed responses retain the reservation. Confirmation on any attempt wins over later contradictions; otherwise an unresolved attempt wins over a failed attempt.
46
- - Interpret explicit `upstream` as an origin: an incoming origin-form path replaces any configured path prefix. Preserve encoded path/query bytes while keeping leading `//` on that fixed origin. This rule is documented so callers do not silently route `/weather` to an assumed `/v1/weather`.
47
- - Forward HTTPS CONNECT as an unmetered encrypted tunnel, with no certificate installation or TLS interception. Gate recognized signed HTTP upgrade handshakes but do not claim to inspect subsequent stream frames. Payload-byte transparency excludes hop-by-hop headers and transfer framing that an HTTP proxy must reconstruct.
48
- - Keep the dashboard timeline to the current UTC hour plus the preceding 23 hourly buckets; do not invent a persistent process-session model. Show each asset's active global budget separately from the all-time ledger total. Show 30 recent events and 10 recent diagnostics; keep original payment JSON in JSON export rather than the live summary API.
49
- - Add `TAXIMETER_DB`, `TAXIMETER_PORT`, and `TAXIMETER_DASHBOARD_PORT` between explicit flags and configuration files. This follows the brief's environment-variable naming while making precedence explicit. Allow port `0` for local tests and ephemeral listeners. An injected SDK ledger uses supplied configuration plus defaults, avoiding hidden user-file dependencies for embedded callers.
50
- - `doctor` is deliberately local. With a nonexistent database it checks an empty in-memory SQLite ledger and configuration; it does not claim to test that future path's write permissions, wallet access, or upstream/facilitator readiness. Existing malformed config remains a visible error.
51
- - Protocol fixtures use deterministic synthetic authorizations and settlement results derived from documented envelopes. A structural parser test is not a real payment, wallet integration, or chain-settlement test. Record this boundary instead of presenting synthetic fixture success as live-network proof.
52
- - Rechecked the npm name on **2026-09-08**: `npm view taximeter` returned `E404`, so no fallback name was needed. The README keeps the required `npx taximeter start` command and labels registry publication as pending; source quickstart commands use `npm ci`, `npm run build`, and `node dist/cli/index.js start`. Validate the local `taximeter-0.1.0.tgz` in a fresh temporary directory before claiming packaged startup; record the actual result in `VERIFICATION.md`.
53
- - Generate the initial `CHANGELOG.md` with Changesets using a transient, uncommitted `0.0.0` version and an initial minor changeset, then restore the intended `0.1.0` through `npm run version-packages` and resynchronize the lockfile. This produces a generated changelog without changing the release version or rewriting commit history. The demo uses local synthetic payments: its recording script demonstrates 20 accepted payments and a blocked twenty-first payment without making a transfer. The initial GIF placeholder was subsequently replaced by the Windows recording documented above.
54
- - Repository visibility, description, and npm publication are maintainer-managed release settings. The intended repository description is **A taximeter for your AI agents.** A successful local build does not establish that registry publication or repository configuration has completed.