codex-usage-tracking 0.4.0__tar.gz → 0.4.1__tar.gz

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.
Files changed (111) hide show
  1. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/.codex-plugin/plugin.json +1 -1
  2. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/CHANGELOG.md +7 -0
  3. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/PKG-INFO +6 -3
  4. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/README.md +5 -2
  5. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/cli-reference.md +56 -0
  6. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/dashboard-guide.md +2 -2
  7. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/development.md +8 -7
  8. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/install.md +2 -0
  9. codex_usage_tracking-0.4.1/docs/one-dot-oh-readiness.md +226 -0
  10. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/pricing-and-credits.md +4 -1
  11. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/pyproject.toml +1 -1
  12. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/check_release.py +100 -0
  13. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/smoke_installed_package.py +46 -2
  14. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-tracker/scripts/run_mcp.py +2 -2
  15. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/__init__.py +1 -1
  16. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/PKG-INFO +6 -3
  17. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/SOURCES.txt +1 -0
  18. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_cli_lifecycle.py +38 -1
  19. codex_usage_tracking-0.4.1/tests/test_cli_release.py +392 -0
  20. codex_usage_tracking-0.4.1/tests/test_dashboard_state.py +92 -0
  21. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_plugin_installer.py +2 -1
  22. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_store_dashboard_mcp.py +3 -0
  23. codex_usage_tracking-0.4.0/docs/one-dot-oh-readiness.md +0 -130
  24. codex_usage_tracking-0.4.0/tests/test_cli_release.py +0 -178
  25. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/.mcp.json +0 -0
  26. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/AGENTS.md +0 -0
  27. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/CONTRIBUTING.md +0 -0
  28. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/LICENSE +0 -0
  29. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/MANIFEST.in +0 -0
  30. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/SECURITY.md +0 -0
  31. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/assets/icon.svg +0 -0
  32. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/architecture.md +0 -0
  33. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-calls-preview.png +0 -0
  34. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-calls.png +0 -0
  35. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-details.png +0 -0
  36. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-insights.png +0 -0
  37. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-threads.png +0 -0
  38. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/plugin-prompts.png +0 -0
  39. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/plugin-thread-leaderboard.png +0 -0
  40. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/call-detail-panel.png +0 -0
  41. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/insight-overview.png +0 -0
  42. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/thread-investigation.png +0 -0
  43. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/cli-json-schemas.md +0 -0
  44. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/mcp.md +0 -0
  45. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/privacy.md +0 -0
  46. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/ui-ux-improvement-plan.md +0 -0
  47. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/benchmark_synthetic_history.py +0 -0
  48. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/install_local_plugin.py +0 -0
  49. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/setup.cfg +0 -0
  50. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-api/SKILL.md +0 -0
  51. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-tracker/SKILL.md +0 -0
  52. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/__main__.py +0 -0
  53. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/allowance.py +0 -0
  54. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/api_payloads.py +0 -0
  55. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/cli.py +0 -0
  56. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/context.py +0 -0
  57. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/costing.py +0 -0
  58. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/dashboard.py +0 -0
  59. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/diagnostics.py +0 -0
  60. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/formatting.py +0 -0
  61. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/json_contracts.py +0 -0
  62. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/mcp_server.py +0 -0
  63. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/models.py +0 -0
  64. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/parser.py +0 -0
  65. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/paths.py +0 -0
  66. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/__init__.py +0 -0
  67. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/assets/icon.svg +0 -0
  68. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.css +0 -0
  69. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.js +0 -0
  70. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js +0 -0
  71. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js +0 -0
  72. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js +0 -0
  73. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_template.html +0 -0
  74. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls.png +0 -0
  75. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-details.png +0 -0
  76. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-insights.png +0 -0
  77. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-threads.png +0 -0
  78. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/dashboard-guide.html +0 -0
  79. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/rate_cards/codex-credit-rates.json +0 -0
  80. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-api/SKILL.md +0 -0
  81. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-tracker/SKILL.md +0 -0
  82. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_installer.py +0 -0
  83. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing.py +0 -0
  84. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_config.py +0 -0
  85. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_estimates.py +0 -0
  86. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_openai.py +0 -0
  87. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/projects.py +0 -0
  88. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/recommendations.py +0 -0
  89. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/redaction.py +0 -0
  90. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/reports.py +0 -0
  91. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/schema.py +0 -0
  92. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/server.py +0 -0
  93. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/store.py +0 -0
  94. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/support.py +0 -0
  95. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/threads.py +0 -0
  96. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/dependency_links.txt +0 -0
  97. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/entry_points.txt +0 -0
  98. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/requires.txt +0 -0
  99. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/top_level.txt +0 -0
  100. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_allowance.py +0 -0
  101. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_json_contracts.py +0 -0
  102. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_mcp_launcher.py +0 -0
  103. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_parser.py +0 -0
  104. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_pricing.py +0 -0
  105. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_privacy.py +0 -0
  106. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_projects.py +0 -0
  107. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_recommendations.py +0 -0
  108. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_schema.py +0 -0
  109. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_store_migrations.py +0 -0
  110. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_support.py +0 -0
  111. {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_threads.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-usage-tracker",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Unofficial local tracker for aggregate Codex token usage from local session logs.",
5
5
  "author": {
6
6
  "name": "Douglas Monsky"
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.4.1 - 2026-06-09
6
+
7
+ - Harden the production PyPI workflow so manual publishing must run from `main` or a tag ref before artifacts are downloaded and uploaded.
8
+ - Strengthen `scripts/check_release.py` so it validates the publish-ref preflight inside both the TestPyPI and PyPI jobs.
9
+ - Check off completed 1.0 readiness items with evidence for migration coverage, localhost dashboard smoke testing, and the protected GitHub `pypi` environment.
10
+ - Pin the marketplace MCP runtime launcher to the exact `codex-usage-tracking==0.4.1` package.
11
+
5
12
  ## 0.4.0 - 2026-06-09
6
13
 
7
14
  - Add official Python 3.14 support across CI, package classifiers, README/install docs, and installed-package Docker smoke coverage.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-usage-tracking
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Unofficial local Codex plugin and dashboard for investigating aggregate token usage, costs, caching, and thread patterns.
5
5
  Author: Douglas Monsky
6
6
  License-Expression: MIT
@@ -253,10 +253,13 @@ This is optional. The normal shell install above is the fastest trusted path for
253
253
  ## Current Limitations
254
254
 
255
255
  - This is a sidecar dashboard and plugin, not a native Codex chat overlay.
256
+ - Codex upstream log formats can change, and parser compatibility may require tracker updates.
256
257
  - Token counts come from Codex's logged counters; the tracker does not re-tokenize prompts.
257
- - Pricing and Codex credit estimates depend on local rate data and confidence labels.
258
- - Remaining 5-hour and weekly allowance is not read automatically from the logged-in account.
258
+ - Pricing and rate-card sources can change outside this project.
259
+ - Pricing and Codex credit estimates depend on local rate data and confidence labels and are not guaranteed to match exact billing.
260
+ - Live account allowance cannot be read automatically by this local tracker; remaining 5-hour and weekly allowance is only available when you configure copied values.
259
261
  - Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
262
+ - Plugin discovery limitations are separate from core Python CLI/dashboard support.
260
263
  - Parent-child thread relationships are only as good as the metadata Codex logs; inferred auto-review attachments are labeled as inferred.
261
264
 
262
265
  ## Roadmap
@@ -216,10 +216,13 @@ This is optional. The normal shell install above is the fastest trusted path for
216
216
  ## Current Limitations
217
217
 
218
218
  - This is a sidecar dashboard and plugin, not a native Codex chat overlay.
219
+ - Codex upstream log formats can change, and parser compatibility may require tracker updates.
219
220
  - Token counts come from Codex's logged counters; the tracker does not re-tokenize prompts.
220
- - Pricing and Codex credit estimates depend on local rate data and confidence labels.
221
- - Remaining 5-hour and weekly allowance is not read automatically from the logged-in account.
221
+ - Pricing and rate-card sources can change outside this project.
222
+ - Pricing and Codex credit estimates depend on local rate data and confidence labels and are not guaranteed to match exact billing.
223
+ - Live account allowance cannot be read automatically by this local tracker; remaining 5-hour and weekly allowance is only available when you configure copied values.
222
224
  - Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
225
+ - Plugin discovery limitations are separate from core Python CLI/dashboard support.
223
226
  - Parent-child thread relationships are only as good as the metadata Codex logs; inferred auto-review attachments are labeled as inferred.
224
227
 
225
228
  ## Roadmap
@@ -4,6 +4,14 @@ This page lists the common command-line workflows. For tested JSON contract ids,
4
4
 
5
5
  ## Index And Setup
6
6
 
7
+ Run first-time setup:
8
+
9
+ ```bash
10
+ codex-usage-tracker setup
11
+ ```
12
+
13
+ `setup` installs or refreshes the local plugin wrapper, initializes local config templates when needed, refreshes the aggregate index, runs `doctor`, and prints whether Codex needs a restart for plugin discovery.
14
+
7
15
  Refresh the local aggregate index:
8
16
 
9
17
  ```bash
@@ -27,6 +35,36 @@ codex-usage-tracker inspect-log ~/.codex/sessions/YYYY/MM/DD/rollout-...jsonl --
27
35
 
28
36
  `inspect-log` reports parser adapter, aggregate token-count events, session ids, models, and parser diagnostics. It does not store raw prompts, assistant messages, tool output, or transcript snippets.
29
37
 
38
+ Check setup without writing files:
39
+
40
+ ```bash
41
+ codex-usage-tracker doctor
42
+ codex-usage-tracker doctor --suggest-repair
43
+ ```
44
+
45
+ `doctor` validates local paths, database state, parser diagnostics, pricing and allowance config, dashboard output, plugin files, and MCP importability. `--suggest-repair` adds likely next commands without making changes.
46
+
47
+ Reset only the local aggregate database:
48
+
49
+ ```bash
50
+ codex-usage-tracker reset-db --yes
51
+ ```
52
+
53
+ `reset-db` deletes tracker-owned aggregate SQLite rows. It does not delete raw Codex logs and requires `--yes`.
54
+
55
+ ## Plugin Lifecycle
56
+
57
+ ```bash
58
+ codex-usage-tracker install-plugin
59
+ codex-usage-tracker install-plugin --python .venv/bin/python
60
+ codex-usage-tracker upgrade-plugin
61
+ codex-usage-tracker uninstall-plugin
62
+ ```
63
+
64
+ `install-plugin` writes the package-owned local Codex plugin wrapper, companion skills, and MCP config. Use the `--python` form for source checkouts that should use a repo-local virtual environment.
65
+
66
+ `upgrade-plugin` refreshes an existing wrapper in place. `uninstall-plugin` removes only the tracker-owned plugin wrapper and marketplace entry.
67
+
30
68
  ## Dashboard
31
69
 
32
70
  ```bash
@@ -110,6 +148,14 @@ codex-usage-tracker export --output usage.csv --limit 0
110
148
 
111
149
  Use `--privacy-mode redacted` or `--privacy-mode strict` before sharing CSV output.
112
150
 
151
+ ## Support Bundle
152
+
153
+ ```bash
154
+ codex-usage-tracker --privacy-mode strict support-bundle --output ~/.codex-usage-tracker/support-bundle.json
155
+ ```
156
+
157
+ Support bundles are diagnostic summaries for issues. They include package, platform, doctor, schema, parser, pricing, allowance, threshold, project-config, and privacy metadata. They exclude raw logs, aggregate rows, prompts, assistant messages, tool output, and context text.
158
+
113
159
  ## Local Config
114
160
 
115
161
  ```bash
@@ -125,6 +171,16 @@ codex-usage-tracker init-projects
125
171
 
126
172
  Local config files live under `~/.codex-usage-tracker/` and are never committed by this project.
127
173
 
174
+ Stable local config files:
175
+
176
+ - `pricing.json`: schema `_schema: codex-usage-tracker-pricing-v1`, optional `_source`, `models`, `aliases`, and `_estimated_models`. `models` maps model labels to USD-per-million-token rates such as `input`, `cached_input`, and `output`.
177
+ - `rate-card.json`: schema `codex-usage-tracker-codex-rate-card-v1`, optional `_source`, `credit_rates`, and `aliases`. `credit_rates` maps Codex model labels to credit rates for aggregate token counters.
178
+ - `allowance.json`: schema `codex-usage-tracker-allowance-v1`, `windows`, optional `credit_rates`, and `aliases`. `windows` stores copied 5-hour, weekly, or other allowance snapshots such as `remaining_percent`, `reset_at`, `remaining_credits`, and `total_credits`.
179
+ - `thresholds.json`: JSON object keyed by recommendation threshold names such as `low_cache_ratio`, `high_context_percent`, and `high_cost_usd`. Unknown keys are ignored.
180
+ - `projects.json`: JSON object with `aliases`, `ignored_paths`, and `tags` for local project attribution.
181
+
182
+ These config schemas are part of the 1.0 compatibility surface. New optional fields may be added, but existing meanings should not change without documentation and a compatibility plan.
183
+
128
184
  ## Privacy Mode
129
185
 
130
186
  `--privacy-mode` is a global option, so place it before the subcommand:
@@ -22,9 +22,9 @@ codex-usage-tracker init-allowance
22
22
  codex-usage-tracker parse-allowance "5h 79% 6:50 PM Weekly 33% Jun 7"
23
23
  ```
24
24
 
25
- To tune review thresholds locally, run `codex-usage-tracker init-thresholds` and edit `~/.codex-usage-tracker/thresholds.json`. These thresholds control low-cache, high-context, high-uncached-input, large-thread, reasoning-spike, low-output, and high-cost recommendations.
25
+ To tune review thresholds locally, run `codex-usage-tracker init-thresholds` and edit `~/.codex-usage-tracker/thresholds.json`. This file is a JSON object keyed by recommendation threshold names such as `low_cache_ratio`, `high_context_percent`, and `high_cost_usd`; unknown keys are ignored. These thresholds control low-cache, high-context, high-uncached-input, large-thread, reasoning-spike, low-output, and high-cost recommendations.
26
26
 
27
- To tune project attribution locally, run `codex-usage-tracker init-projects` and edit `~/.codex-usage-tracker/projects.json`. The dashboard derives project name, relative cwd, branch, tags, and a hashed remote origin from aggregate `cwd` and local Git metadata when available.
27
+ To tune project attribution locally, run `codex-usage-tracker init-projects` and edit `~/.codex-usage-tracker/projects.json`. This file supports `aliases`, `ignored_paths`, and `tags`. The dashboard derives project name, relative cwd, branch, tags, and a hashed remote origin from aggregate `cwd` and local Git metadata when available.
28
28
 
29
29
  Before sharing screenshots or generated artifacts, use `--privacy-mode redacted` or `--privacy-mode strict` before the subcommand:
30
30
 
@@ -38,7 +38,7 @@ fix/<issue-number>-short-description
38
38
  docs/<issue-number>-short-description
39
39
  chore/<issue-number>-short-description
40
40
  test/<issue-number>-short-description
41
- release/0.4.0
41
+ release/0.4.1
42
42
  hotfix/0.3.3
43
43
  ```
44
44
 
@@ -91,7 +91,7 @@ blocked
91
91
  Recommended milestones:
92
92
 
93
93
  ```text
94
- 0.4.0
94
+ 0.4.1
95
95
  1.0-readiness
96
96
  1.0.0
97
97
  ```
@@ -147,8 +147,8 @@ python scripts/smoke_installed_package.py --docker
147
147
  To verify the public PyPI package instead of the local checkout:
148
148
 
149
149
  ```bash
150
- python scripts/smoke_installed_package.py --from-pypi --version 0.4.0
151
- python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.0
150
+ python scripts/smoke_installed_package.py --from-pypi --version 0.4.1
151
+ python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1
152
152
  ```
153
153
 
154
154
  Docker avoids local toolchain side effects during install testing. Keep one local `pipx` smoke for platform-specific PATH and plugin-discovery behavior, but use Docker for repeatable Linux package verification.
@@ -264,8 +264,8 @@ After the release branch merges, tag from updated `main`, not from an unreviewed
264
264
  ```bash
265
265
  git switch main
266
266
  git pull --ff-only
267
- git tag -a v0.4.0 -m "codex-usage-tracker 0.4.0"
268
- git push origin v0.4.0
267
+ git tag -a v0.4.1 -m "codex-usage-tracker 0.4.1"
268
+ git push origin v0.4.1
269
269
  ```
270
270
 
271
271
  Do not create or push release tags without maintainer approval.
@@ -274,12 +274,13 @@ Do not create or push release tags without maintainer approval.
274
274
 
275
275
  Publishing uses GitHub Actions Trusted Publishing through `.github/workflows/publish.yml`; do not upload from a local machine and do not add PyPI or TestPyPI API tokens.
276
276
 
277
- The first public package release, `0.3.0`, was published on June 8, 2026. Patch release `0.3.1` followed the same day to ship the live-dashboard skill launch fix. Patch release `0.3.2` made dashboard launch refresh the default and added runtime enablement for context loading. Minor release `0.4.0` added Python 3.14 support, release recovery docs, stricter privacy/support-bundle regression coverage, and large-history benchmark thresholds:
277
+ The first public package release, `0.3.0`, was published on June 8, 2026. Patch release `0.3.1` followed the same day to ship the live-dashboard skill launch fix. Patch release `0.3.2` made dashboard launch refresh the default and added runtime enablement for context loading. Minor release `0.4.0` added Python 3.14 support, release recovery docs, stricter privacy/support-bundle regression coverage, and large-history benchmark thresholds. Patch release `0.4.1` hardened the PyPI publish workflow and checked off completed 1.0 readiness gates:
278
278
 
279
279
  - GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.0`
280
280
  - GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.1`
281
281
  - GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.2`
282
282
  - GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.4.0`
283
+ - GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.4.1`
283
284
  - PyPI: `https://pypi.org/project/codex-usage-tracking/`
284
285
  - TestPyPI: `https://test.pypi.org/project/codex-usage-tracking/`
285
286
 
@@ -38,6 +38,8 @@ By default the tracker looks for Codex JSONL logs under `~/.codex`, stores its o
38
38
 
39
39
  Windows support should work for the core dashboard/CLI when Codex writes readable JSONL logs, but plugin discovery is tied to Codex's local plugin directory behavior. Run `codex-usage-tracker doctor --suggest-repair` after setup if Codex does not show the plugin.
40
40
 
41
+ Plugin discovery limitations are separate from core Python CLI/dashboard support. If Codex cannot discover the local plugin wrapper, the installed command, SQLite index, generated dashboard, localhost server, and CLI JSON reports can still work.
42
+
41
43
  ## Upgrade
42
44
 
43
45
  ```bash
@@ -0,0 +1,226 @@
1
+ # 1.0 Readiness
2
+
3
+ This checklist tracks the work needed to move from the first public PyPI releases toward a stable 1.0 contract. Keep all verification data synthetic or aggregate-only.
4
+
5
+ Each completed checkbox names the primary verification command inline. The evidence reference section at the end maps those commands to the concrete tests, scripts, workflow checks, or public-install smokes that prove the completed items.
6
+
7
+ ## Compatibility Promise
8
+
9
+ - CLI command names documented in `docs/cli-reference.md` are stable after 1.0.
10
+ - JSON schema IDs documented in `docs/cli-json-schemas.md` are stable after 1.0.
11
+ - New JSON fields may be added in minor releases, but existing required fields should not be removed or change type without a new schema version.
12
+ - MCP tool names and response schemas are stable after 1.0.
13
+ - CSV export columns are stable after 1.0 unless a new export schema or version flag is introduced.
14
+ - Config file schemas for pricing, allowance, thresholds, projects, and rate cards are stable after 1.0.
15
+ - Privacy-mode semantics are stable after 1.0.
16
+ - SQLite migrations must support upgrade from the last pre-1.0 release to 1.0.
17
+
18
+ Not guaranteed:
19
+
20
+ - Codex upstream log format stability.
21
+ - OpenAI pricing or rate-card source stability.
22
+ - Automatic access to live account allowance.
23
+ - Exact billing equivalence.
24
+
25
+ ## 1. Public Install And Package Metadata
26
+
27
+ - [x] Verify the current public PyPI version is visible as `0.4.1`: `python -c "import json, urllib.request; print(json.load(urllib.request.urlopen('https://pypi.org/pypi/codex-usage-tracking/json'))['info']['version'])"`.
28
+ - [x] Verify public venv install for `0.4.1`: `python -m venv /tmp/codex-usage-pypi-smoke && . /tmp/codex-usage-pypi-smoke/bin/activate && python -m pip install codex-usage-tracking==0.4.1 && codex-usage-tracker --version`.
29
+ - [x] Verify public pipx install path for `0.4.1`: `PIPX_HOME=/tmp/codex-usage-pipx-home PIPX_BIN_DIR=/tmp/codex-usage-pipx-bin pipx install codex-usage-tracking==0.4.1 && /tmp/codex-usage-pipx-bin/codex-usage-tracker --version`.
30
+ - [x] Verify installed package resources from a built wheel: `python scripts/smoke_installed_package.py`.
31
+ - [x] Verify installed package resources in Linux Docker: `python scripts/smoke_installed_package.py --docker`.
32
+ - [x] Verify public PyPI package in Docker: `python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1`.
33
+ - [x] Verify PyPI metadata names remain unchanged: `python scripts/check_release.py`.
34
+ - [x] Add Python 3.14 as an official support target after CI, package classifiers, docs, and installed-package smoke coverage were added. Docker smoke coverage uses `python:3.14-slim` by default. Track this in issue #12.
35
+
36
+ ## 2. Upgrade And Migration
37
+
38
+ - [x] Add synthetic legacy SQLite fixture test proving `init_db` upgrades without data loss: `python -m pytest tests/test_store_migrations.py`.
39
+ - [x] Reassess whether a synthetic v0.3-style SQLite fixture is required; the current legacy migration fixture covers active schema drift, so no separate v0.3 fixture is currently needed: `python -m pytest tests/test_store_migrations.py`.
40
+ - [x] Verify `schema_state` reports expected version and checksum after migration: `python -m pytest tests/test_store_migrations.py`.
41
+ - [x] Verify `rebuild-index` clears only tracker-owned aggregate tables: `python -m pytest tests/test_store_dashboard_mcp.py`.
42
+ - [x] Verify `reset-db` does not touch raw Codex logs: `python -m pytest tests/test_cli_lifecycle.py`.
43
+ - [x] Verify refresh metadata and parser diagnostics survive migration: `python -m pytest tests/test_store_migrations.py tests/test_parser.py`.
44
+ - [x] Verify CSV export columns after migration: `python -m pytest tests/test_store_migrations.py`.
45
+
46
+ ## 3. CLI Compatibility
47
+
48
+ - [x] Confirm every documented command in `docs/cli-reference.md` exists: `python -m pytest tests/test_cli_release.py`.
49
+ - [x] Confirm no documented command is removed without a deprecation plan: manual diff review plus `python -m pytest tests/test_cli_release.py`.
50
+ - [x] Verify command help works from an installed wheel: `python scripts/smoke_installed_package.py`.
51
+ - [x] Verify lifecycle commands still return actionable errors without real logs: `python -m pytest tests/test_cli_lifecycle.py`.
52
+
53
+ ## 4. MCP Compatibility
54
+
55
+ - [x] Verify MCP tool names remain documented in `docs/mcp.md`: `python -m pytest tests/test_cli_release.py`.
56
+ - [x] Verify MCP JSON responses use tracked schema IDs where applicable: `python -m pytest tests/test_store_dashboard_mcp.py`.
57
+ - [x] Verify companion skill packaged copy matches source skill: `python scripts/check_release.py`.
58
+ - [x] Verify plugin installer writes MCP config from an installed wheel: `python scripts/smoke_installed_package.py`.
59
+
60
+ ## 5. JSON Contract Stability
61
+
62
+ - [x] Verify every documented `--json` command has a tracked schema: `python -m pytest tests/test_json_contracts.py`.
63
+ - [x] Verify every schema in `docs/cli-json-schemas.md` exists in `src/codex_usage_tracker/json_contracts.py`: `python -m pytest tests/test_json_contracts.py`.
64
+ - [x] Verify every schema in `json_contracts.py` is documented: `python -m pytest tests/test_json_contracts.py`.
65
+ - [x] Verify known payload examples pass `validate_json_payload_contract`: `python -m pytest tests/test_json_contracts.py`.
66
+ - [x] Verify invalid or missing required fields fail contract validation: `python -m pytest tests/test_json_contracts.py`.
67
+ - [x] Cover query, recommendations, summary, session, doctor, pricing-coverage, dashboard, export, support-bundle, and plugin lifecycle JSON payload contracts: `python -m pytest tests/test_json_contracts.py`.
68
+
69
+ ## 6. CSV Export Stability
70
+
71
+ - [x] Verify expected CSV columns for aggregate exports: `python -m pytest tests/test_cli_lifecycle.py`.
72
+ - [x] Verify redacted and strict privacy CSV exports omit private metadata: `python -m pytest tests/test_privacy.py`.
73
+ - [x] Verify migration fixtures still export the expected CSV shape: `python -m pytest tests/test_store_migrations.py`.
74
+
75
+ ## 7. Config File Stability
76
+
77
+ - [x] Verify pricing config initialization and parsing: `python -m pytest tests/test_pricing.py`.
78
+ - [x] Verify allowance and rate-card config initialization and parsing: `python -m pytest tests/test_allowance.py`.
79
+ - [x] Verify threshold config initialization and parsing: `python -m pytest tests/test_recommendations.py`.
80
+ - [x] Verify project alias/tag config initialization and parsing: `python -m pytest tests/test_projects.py`.
81
+ - [x] Document config schema changes before release: manual review of `docs/pricing-and-credits.md`, `docs/dashboard-guide.md`, and `docs/cli-reference.md`; enforced by `python -m pytest tests/test_cli_release.py`.
82
+
83
+ ## 8. Dashboard Behavior
84
+
85
+ - [x] Verify dashboard aggregate payload remains raw-context-free: `python -m pytest tests/test_store_dashboard_mcp.py`.
86
+ - [x] Verify dashboard URL state round trips: `python -m pytest tests/test_dashboard_state.py`.
87
+ - [x] Verify dashboard formatting helpers: `node --check src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js`.
88
+ - [x] Verify dashboard data helpers: `node --check src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js`.
89
+ - [x] Verify active-history and all-history state labels: `python -m pytest tests/test_cli_release.py tests/test_store_dashboard_mcp.py`.
90
+ - [x] Run a manual localhost dashboard smoke before release with temporary aggregate-only paths: `codex-usage-tracker serve-dashboard --open` plus `curl -fsS http://127.0.0.1:8897/dashboard.html`.
91
+
92
+ ## 9. Privacy And Sharing Safety
93
+
94
+ - [x] Verify dashboard payloads in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
95
+ - [x] Verify query JSON in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
96
+ - [x] Verify session JSON in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
97
+ - [x] Verify CSV export in redacted and strict modes: `python -m pytest tests/test_privacy.py`.
98
+ - [x] Verify strict mode does not leak raw cwd, source paths, branch, remote labels, project tags, or synthetic private project names: `python -m pytest tests/test_privacy.py`.
99
+ - [x] Verify raw context fields never appear in SQLite, CSV, dashboard payloads, support bundles, generated static HTML, docs, or screenshots: `python -m pytest tests/test_privacy.py scripts/check_release.py`.
100
+
101
+ ## 10. Support-Bundle Safety
102
+
103
+ - [x] Verify support bundles include package version, Python version, OS/platform, doctor status, schema state, parser diagnostics, pricing status, allowance status, threshold status, project config status, and privacy metadata: `python -m pytest tests/test_support.py`.
104
+ - [x] Verify support bundles exclude raw logs, prompt text, assistant text, tool output, context text, and raw source paths in strict mode: `python -m pytest tests/test_support.py`.
105
+ - [x] Update issue templates to request only strict-mode support bundles: `python scripts/check_release.py`.
106
+
107
+ ## 11. Large-History Performance
108
+
109
+ - [x] Run synthetic 10k benchmark: `python scripts/benchmark_synthetic_history.py --rows 10000 --json --enforce-thresholds`.
110
+ - [x] Run synthetic 100k benchmark: `python scripts/benchmark_synthetic_history.py --rows 100000 --json --enforce-thresholds`.
111
+ - [x] Run synthetic 500k benchmark as a release gate when practical: `python scripts/benchmark_synthetic_history.py --rows 500000 --json --enforce-thresholds`.
112
+ - [x] Define thresholds for active-only dashboard query, all-history dashboard query, since/until, model/effort, min_tokens, recommendations, pricing coverage, and project summary.
113
+ - [x] Add a smaller CI-safe benchmark if it can stay fast and deterministic.
114
+
115
+ ## 12. Release Process
116
+
117
+ - [x] Verify publish workflow publishes `codex-usage-tracking`, not `codex-usage-tracker`: `python scripts/check_release.py`.
118
+ - [x] Verify publish workflow uses Trusted Publishing, not API tokens: `python scripts/check_release.py`.
119
+ - [x] Verify TestPyPI and PyPI jobs exist and publish only on workflow dispatch or release events: `python scripts/check_release.py`.
120
+ - [x] Verify manual PyPI workflow dispatch is restricted to `main` or tag refs: `python scripts/check_release.py`.
121
+ - [x] Verify PyPI job is gated by environment `pypi`: `gh api repos/douglasmonsky/codex-usage-tracker/environments/pypi`.
122
+ - [x] Verify dist filenames match `codex_usage_tracking`: `python -m build && python scripts/check_release.py --dist`.
123
+ - [ ] Verify TestPyPI process: run `Publish Python package` with `target=testpypi` only when intentionally testing release publication.
124
+ - [ ] Verify PyPI process: publish a GitHub Release or run workflow dispatch with `target=pypi` only when intentionally publishing a reviewed release.
125
+ - [x] Document release recovery by cutting a new patch version when an uploaded artifact is wrong: see `docs/development.md`.
126
+
127
+ ## 13. Known Limitations
128
+
129
+ - [x] Document that Codex upstream log formats can change and parser compatibility may require updates.
130
+ - [x] Document that pricing and rate-card sources can change outside this project.
131
+ - [x] Document that live account allowance cannot be read automatically by this local tracker.
132
+ - [x] Document that cost and credit estimates are not guaranteed to match exact billing.
133
+ - [x] Document platform/plugin discovery limitations separately from the core Python CLI/dashboard support.
134
+
135
+ ## Evidence References
136
+
137
+ These references are the concrete proof behind completed checklist items. Public package smoke commands are version-specific to `0.4.1`; all repo tests use synthetic or aggregate-only data.
138
+
139
+ ### Public Install And Package Metadata
140
+
141
+ - Public PyPI version, public venv install, and public pipx install are proven by the exact public-install commands in section 1.
142
+ - Built-wheel and installed-resource coverage is proven by `scripts/smoke_installed_package.py` and `tests/test_cli_release.py::test_installed_package_smoke_checks_help_for_stable_commands`.
143
+ - Linux package-resource coverage is proven by `scripts/smoke_installed_package.py --docker`.
144
+ - Public PyPI Docker coverage is proven by `scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1`.
145
+ - PyPI metadata, package/distribution names, package resources, source/wheel member names, Python 3.10-3.14 support metadata, CI workflow requirements, publish workflow safety text, and tracked secret patterns are proven by `scripts/check_release.py`, `scripts/check_release.py --dist`, and `tests/test_cli_release.py::test_release_check_script_passes`.
146
+
147
+ ### Upgrade And Migration
148
+
149
+ - Legacy SQLite migration, schema state, migration idempotence, malformed legacy schema handling, and migration CSV shape are proven by `tests/test_store_migrations.py`.
150
+ - The v0.3 fixture decision is covered by `tests/test_store_migrations.py`; no additional v0.3-specific fixture is currently required because the active pre-1.0 migration path is already represented by the legacy fixture.
151
+ - `rebuild-index` clearing only tracker-owned aggregate rows is proven by `tests/test_store_dashboard_mcp.py::test_rebuild_index_clears_aggregate_rows_before_rescan`.
152
+ - `reset-db` preserving raw Codex logs is proven by `tests/test_cli_lifecycle.py::test_setup_support_bundle_and_reset_db_cli`.
153
+ - Refresh metadata and parser diagnostics are proven by `tests/test_store_migrations.py`, `tests/test_parser.py`, and `tests/test_store_dashboard_mcp.py::test_refresh_reports_skipped_corrupt_token_events`.
154
+
155
+ ### CLI Compatibility
156
+
157
+ - Documented CLI command existence and stable command coverage are proven by `tests/test_cli_release.py::test_cli_reference_documents_only_existing_stable_commands` and `tests/test_cli_release.py::test_stable_cli_commands_are_not_removed_without_a_deprecation_plan`.
158
+ - Installed-wheel subcommand help coverage is proven by `scripts/smoke_installed_package.py` and guarded by `tests/test_cli_release.py::test_installed_package_smoke_checks_help_for_stable_commands`.
159
+ - Lifecycle actionable errors without real logs are proven by `tests/test_cli_lifecycle.py::test_lifecycle_commands_return_actionable_errors_without_real_logs`.
160
+
161
+ ### MCP Compatibility
162
+
163
+ - MCP tool documentation parity is proven by `tests/test_cli_release.py::test_mcp_tool_names_remain_documented`.
164
+ - MCP JSON response schema IDs and wrapper payload contracts are proven by `tests/test_store_dashboard_mcp.py::test_mcp_wrappers_smoke`.
165
+ - Companion skill source/package parity is proven by `scripts/check_release.py`.
166
+ - Installed-wheel plugin MCP config is proven by `scripts/smoke_installed_package.py`.
167
+
168
+ ### JSON Contract Stability
169
+
170
+ - Documented schema table parity, runtime schema ID tracking, example validation, invalid-payload rejection, and minimal payload validation are proven by `tests/test_json_contracts.py`.
171
+ - README and CLI schema doc references are additionally guarded by `tests/test_cli_release.py::test_cli_json_schema_doc_lists_tracked_contracts`.
172
+
173
+ ### CSV Export Stability
174
+
175
+ - Aggregate CSV columns are proven by `tests/test_cli_lifecycle.py::test_report_json_and_query_cli`.
176
+ - Redacted and strict privacy CSV behavior is proven by `tests/test_privacy.py::test_privacy_modes_cover_dashboard_query_session_and_csv` and `tests/test_privacy.py::test_aggregate_outputs_exclude_raw_transcript_content`.
177
+ - Migration CSV shape is proven by `tests/test_store_migrations.py::test_csv_export_keeps_current_columns_after_legacy_migration`.
178
+
179
+ ### Config File Stability
180
+
181
+ - Pricing config initialization and parsing are proven by `tests/test_pricing.py` and `tests/test_cli_lifecycle.py::test_rate_card_allowance_and_pricing_snapshot_cli`.
182
+ - Allowance and Codex rate-card config initialization/parsing are proven by `tests/test_allowance.py` and `tests/test_cli_lifecycle.py::test_rate_card_allowance_and_pricing_snapshot_cli`.
183
+ - Threshold config initialization/parsing is proven by `tests/test_recommendations.py::test_threshold_template_and_overrides`.
184
+ - Project alias, ignored-path, tag, and privacy behavior is proven by `tests/test_projects.py`.
185
+ - Config schema documentation coverage is proven by `tests/test_cli_release.py::test_local_config_schema_docs_reference_stable_fields`.
186
+
187
+ ### Dashboard Behavior
188
+
189
+ - Aggregate-only dashboard payloads and CSV are proven by `tests/test_store_dashboard_mcp.py::test_dashboard_and_csv_are_aggregate_only` and `tests/test_privacy.py::test_aggregate_outputs_exclude_raw_transcript_content`.
190
+ - URL-state round trips are proven by `tests/test_dashboard_state.py::test_dashboard_url_state_round_trips`.
191
+ - Dashboard helper syntax is proven by the `node --check` commands in section 8 and the CI dashboard JavaScript syntax job.
192
+ - Active/all-history payload behavior is proven by `tests/test_store_dashboard_mcp.py::test_dashboard_history_scope_excludes_archived_rows_by_default` and `tests/test_store_dashboard_mcp.py::test_dashboard_server_usage_api_switches_history_scope`.
193
+ - Active/all-history user-facing labels are proven by `tests/test_cli_release.py::test_dashboard_history_scope_labels_remain_user_facing`.
194
+ - No-context startup and runtime context enablement are proven by `tests/test_store_dashboard_mcp.py::test_dashboard_server_can_enable_context_api_at_runtime` and `tests/test_privacy.py::test_context_server_requires_loopback_origin_token_and_enablement`.
195
+ - Manual localhost smoke is proven by running `codex-usage-tracker serve-dashboard --open` against temporary database, config, output, and Codex-home paths on `127.0.0.1:8897`, then probing `/dashboard.html` with `curl -fsS`.
196
+
197
+ ### Privacy And Sharing Safety
198
+
199
+ - Dashboard, query, session, CSV, support-bundle, and generated-static-HTML privacy behavior is proven by `tests/test_privacy.py`.
200
+ - Strict project metadata redaction is proven by `tests/test_privacy.py::test_privacy_modes_cover_dashboard_query_session_and_csv` and `tests/test_projects.py::test_project_privacy_modes_redact_sensitive_metadata`.
201
+ - Raw context exclusion and explicit context loading are proven by `tests/test_privacy.py::test_context_loading_is_explicit_redacted_and_not_static_html`, `tests/test_privacy.py::test_context_server_requires_loopback_origin_token_and_enablement`, and `tests/test_store_dashboard_mcp.py::test_context_loads_raw_log_only_on_demand`.
202
+ - Tracked-file secret scanning is proven by `scripts/check_release.py`.
203
+
204
+ ### Support-Bundle Safety
205
+
206
+ - Support-bundle payload shape and secret safety are proven by `tests/test_support.py::test_support_bundle_default_mode_contract_and_secret_safety`.
207
+ - Strict support-bundle path and doctor-text redaction is proven by `tests/test_support.py::test_support_bundle_strict_mode_redacts_local_paths_and_doctor_text`.
208
+ - Safe issue-template requests are proven by `scripts/check_release.py`.
209
+
210
+ ### Large-History Performance
211
+
212
+ - Benchmark command behavior and threshold contract are smoke-tested by `tests/test_cli_release.py::test_synthetic_history_benchmark_script_smoke`.
213
+ - Release-size 10k, 100k, and 500k benchmark claims are proven by running `python scripts/benchmark_synthetic_history.py --rows 10000 100000 500000 --json --enforce-thresholds` before release work when practical.
214
+ - CI-safe benchmark coverage is proven by the CI `Release readiness` job through `tests/test_cli_release.py::test_synthetic_history_benchmark_script_smoke`.
215
+
216
+ ### Release Process
217
+
218
+ - Normal CI package build plus `twine check` and dist verification are proven by `.github/workflows/ci.yml` and enforced by `scripts/check_release.py::_check_ci_workflow`.
219
+ - Publish workflow package name, Trusted Publishing, TestPyPI/PyPI job presence, event guards, no push/PR publishing, no token/password publishing, and manual PyPI main/tag preflight are proven by `scripts/check_release.py::_check_publish_workflow`.
220
+ - The GitHub `pypi` environment gate is proven by `gh api repos/douglasmonsky/codex-usage-tracker/environments/pypi`, which reports a `required_reviewers` protection rule and `can_admins_bypass=false`.
221
+ - Dist filename and wheel/sdist member checks are proven by `python -m build`, `python -m twine check dist/*`, and `python scripts/check_release.py --dist`.
222
+ - Release recovery documentation is proven by `scripts/check_release.py` required-file and docs checks.
223
+
224
+ ### Known Limitations
225
+
226
+ - Parser-format drift, pricing/rate-card drift, live allowance, non-billing-equivalence, and plugin-discovery boundary documentation are proven by `tests/test_cli_release.py::test_known_limitations_are_documented`.
@@ -83,8 +83,11 @@ Configure the usage component:
83
83
 
84
84
  ## Accuracy Notes
85
85
 
86
+ - Codex upstream log formats can change, and parser compatibility may require tracker updates before new event shapes are fully understood.
87
+ - Pricing and rate-card sources can change outside this project. Refresh or pin local files when reports need a known source snapshot.
86
88
  - Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
87
- - The dashboard does not infer live remaining allowance from the logged-in account plan.
89
+ - Live account allowance cannot be read automatically by this local tracker, and the dashboard does not infer live remaining allowance from the logged-in account plan.
88
90
  - Pricing can change after a report is generated. Use `pin-pricing` when you need reproducible historical cost estimates.
89
91
  - Rows with direct model/rate-card matches are more trustworthy than inferred aliases or local overrides.
90
92
  - Cost and credit calculations use aggregate counters; the tracker does not re-tokenize prompts or reconstruct usage from raw text.
93
+ - Cost and credit estimates are not guaranteed to match exact billing.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codex-usage-tracking"
7
- version = "0.4.0"
7
+ version = "0.4.1"
8
8
  description = "Unofficial local Codex plugin and dashboard for investigating aggregate token usage, costs, caching, and thread patterns."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -110,6 +110,7 @@ def main() -> int:
110
110
  failures.extend(_check_required_files())
111
111
  failures.extend(_check_versions())
112
112
  failures.extend(_check_docs())
113
+ failures.extend(_check_issue_templates())
113
114
  failures.extend(_check_packaging_metadata())
114
115
  failures.extend(_check_tracked_files_for_secrets())
115
116
  if args.dist:
@@ -173,6 +174,37 @@ def _check_docs() -> list[str]:
173
174
  return failures
174
175
 
175
176
 
177
+ def _check_issue_templates() -> list[str]:
178
+ failures: list[str] = []
179
+ templates = {
180
+ "bug_report.yml": [
181
+ "Do not paste real Codex logs",
182
+ "strict support bundle",
183
+ "--privacy-mode strict support-bundle",
184
+ ],
185
+ "parser_log_compatibility.yml": [
186
+ "Do not attach or paste raw Codex JSONL logs",
187
+ "Synthetic log shape",
188
+ ],
189
+ "pricing_or_allowance.yml": [
190
+ "Do not paste account screenshots with private details",
191
+ "--privacy-mode strict pricing-coverage --json",
192
+ ],
193
+ }
194
+ for filename, required_texts in templates.items():
195
+ path = REPO_ROOT / ".github" / "ISSUE_TEMPLATE" / filename
196
+ if not path.exists():
197
+ failures.append(f"missing issue template: {path.relative_to(REPO_ROOT)}")
198
+ continue
199
+ text = path.read_text(encoding="utf-8")
200
+ for required in required_texts:
201
+ if required not in text:
202
+ failures.append(
203
+ f"{path.relative_to(REPO_ROOT)} is missing safe-reporting text: {required}"
204
+ )
205
+ return failures
206
+
207
+
176
208
  def _check_packaging_metadata() -> list[str]:
177
209
  sys.path.insert(0, str(REPO_ROOT / "src"))
178
210
  from codex_usage_tracker.plugin_installer import plugin_manifest
@@ -231,6 +263,7 @@ def _check_packaging_metadata() -> list[str]:
231
263
  if "PACKAGE_SPEC_MARKER" not in launcher:
232
264
  failures.append("MCP runtime launcher should invalidate cached runtimes when package spec changes")
233
265
  failures.extend(_check_python_support_metadata(project))
266
+ failures.extend(_check_ci_workflow())
234
267
  failures.extend(_check_publish_workflow())
235
268
  return failures
236
269
 
@@ -279,6 +312,14 @@ def _check_publish_workflow() -> list[str]:
279
312
  "id-token: write",
280
313
  "repository-url: https://test.pypi.org/legacy/",
281
314
  "python -m twine check dist/*",
315
+ "if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'",
316
+ "if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.target == 'pypi')",
317
+ "echo \"ref=$GITHUB_REF\"",
318
+ "echo \"sha=$GITHUB_SHA\"",
319
+ "refs/heads/main|refs/tags/*",
320
+ "Manual PyPI publishing must run from main or a tag ref.",
321
+ "name: testpypi",
322
+ "name: pypi",
282
323
  "https://test.pypi.org/project/codex-usage-tracking/",
283
324
  "https://pypi.org/project/codex-usage-tracking/",
284
325
  ]:
@@ -290,6 +331,65 @@ def _check_publish_workflow() -> list[str]:
290
331
  failures.append("publish workflow must not publish on pull requests")
291
332
  if "secrets." in workflow or "api-token" in workflow or "password:" in workflow:
292
333
  failures.append("publish workflow must not use token secrets or password-based publishing")
334
+ for job_name in ["publish-testpypi", "publish-pypi"]:
335
+ job_block = _workflow_job_block(workflow, job_name)
336
+ if job_block is None:
337
+ failures.append(f"publish workflow is missing job: {job_name}")
338
+ continue
339
+ for required in [
340
+ "Verify PyPI publish ref",
341
+ "echo \"event=$GITHUB_EVENT_NAME\"",
342
+ "echo \"ref=$GITHUB_REF\"",
343
+ "echo \"sha=$GITHUB_SHA\"",
344
+ "refs/heads/main|refs/tags/*",
345
+ "Manual PyPI publishing must run from main or a tag ref.",
346
+ ]:
347
+ if required not in job_block:
348
+ failures.append(f"publish workflow {job_name} job is missing preflight: {required}")
349
+ return failures
350
+
351
+
352
+ def _workflow_job_block(workflow: str, job_name: str) -> str | None:
353
+ match = re.search(
354
+ rf"(?ms)^ {re.escape(job_name)}:\n(?P<body>.*?)(?=^ [A-Za-z0-9_-]+:\n|\Z)",
355
+ workflow,
356
+ )
357
+ if not match:
358
+ return None
359
+ return match.group("body")
360
+
361
+
362
+ def _check_ci_workflow() -> list[str]:
363
+ workflow_path = REPO_ROOT / ".github" / "workflows" / "ci.yml"
364
+ if not workflow_path.exists():
365
+ return ["missing CI workflow: .github/workflows/ci.yml"]
366
+ workflow = workflow_path.read_text(encoding="utf-8")
367
+ failures: list[str] = []
368
+ for required in [
369
+ "name: Build package",
370
+ "python -m build",
371
+ "python -m twine check dist/*",
372
+ "python scripts/check_release.py --dist",
373
+ ]:
374
+ if required not in workflow:
375
+ failures.append(f"CI package job is missing required build check: {required}")
376
+ return failures
377
+
378
+
379
+ def _check_ci_workflow() -> list[str]:
380
+ workflow_path = REPO_ROOT / ".github" / "workflows" / "ci.yml"
381
+ if not workflow_path.exists():
382
+ return ["missing CI workflow: .github/workflows/ci.yml"]
383
+ workflow = workflow_path.read_text(encoding="utf-8")
384
+ failures: list[str] = []
385
+ for required in [
386
+ "name: Build package",
387
+ "python -m build",
388
+ "python -m twine check dist/*",
389
+ "python scripts/check_release.py --dist",
390
+ ]:
391
+ if required not in workflow:
392
+ failures.append(f"CI package job is missing required build check: {required}")
293
393
  return failures
294
394
 
295
395