@oneciel-ai/ciel-runtime 0.2.22 → 0.2.23

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 (86) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +150 -57
  3. package/ciel-runtime-stop.cmd +1 -0
  4. package/ciel-runtime.cmd +1 -0
  5. package/ciel-runtimectl.cmd +1 -0
  6. package/ciel_runtime.py +56 -53
  7. package/ciel_runtime_support/anthropic_tool_turns.py +81 -0
  8. package/ciel_runtime_support/architecture.py +17 -0
  9. package/ciel_runtime_support/channel_injection.py +113 -3
  10. package/ciel_runtime_support/channel_message_prompt.py +15 -0
  11. package/ciel_runtime_support/channel_pending_injection.py +28 -4
  12. package/ciel_runtime_support/channel_pending_poll.py +2 -0
  13. package/ciel_runtime_support/channel_terminal_context.py +6 -0
  14. package/ciel_runtime_support/channel_terminal_dispatch.py +2 -0
  15. package/ciel_runtime_support/channel_terminal_proxy.py +8 -2
  16. package/ciel_runtime_support/channel_wake_claim_repository.py +7 -0
  17. package/ciel_runtime_support/channel_wake_context.py +7 -3
  18. package/ciel_runtime_support/cli_parser.py +6 -0
  19. package/ciel_runtime_support/codex_backend_context.py +4 -0
  20. package/ciel_runtime_support/codex_turn_recovery.py +75 -12
  21. package/ciel_runtime_support/config_migrations.py +102 -10
  22. package/ciel_runtime_support/config_repository.py +9 -0
  23. package/ciel_runtime_support/event_settings_cli.py +284 -2
  24. package/ciel_runtime_support/openai_chat_passthrough.py +2 -0
  25. package/ciel_runtime_support/protocols/openai_responses.py +22 -18
  26. package/ciel_runtime_support/provider_adapters.py +7 -0
  27. package/ciel_runtime_support/provider_policy.py +10 -1
  28. package/ciel_runtime_support/provider_request_builder.py +9 -2
  29. package/ciel_runtime_support/provider_responses_passthrough.py +4 -0
  30. package/ciel_runtime_support/providers/__init__.py +2 -0
  31. package/ciel_runtime_support/providers/alibaba.py +33 -10
  32. package/ciel_runtime_support/providers/constants.py +1 -0
  33. package/ciel_runtime_support/providers/opencode.py +25 -5
  34. package/ciel_runtime_support/providers/opencode_go.py +3 -3
  35. package/ciel_runtime_support/providers/openrouter.py +76 -3
  36. package/ciel_runtime_support/providers/tabitoken.py +130 -0
  37. package/ciel_runtime_support/remote_instructions.py +20 -6
  38. package/ciel_runtime_support/remote_memory.py +515 -55
  39. package/ciel_runtime_support/responses_input_compatibility.py +14 -0
  40. package/ciel_runtime_support/router_http.py +5 -0
  41. package/ciel_runtime_support/runtime_constants.py +1 -1
  42. package/ciel_runtime_support/runtime_launch.py +9 -2
  43. package/ciel_runtime_support/runtime_paths.py +2 -0
  44. package/ciel_runtime_support/tool_side_effect_dedupe.py +7 -4
  45. package/ciel_runtime_support/transcript_delta_delivery.py +333 -0
  46. package/ciel_runtime_support/usage_events.py +45 -3
  47. package/ciel_runtime_support/usage_service.py +871 -0
  48. package/ciel_runtime_support/windows_conpty.py +108 -2
  49. package/ciel_runtime_support/workspace_mcp.py +4 -0
  50. package/docs/CLI-Reference.md +11 -0
  51. package/docs/Configuration.md +7 -2
  52. package/docs/MCP-Channels.md +7 -3
  53. package/docs/Module-Map.md +4 -0
  54. package/docs/Providers.md +32 -0
  55. package/docs/Remote-Memory.md +29 -10
  56. package/docs/Test-Suite.md +1 -0
  57. package/docs/journal/2026/08/20/kevin-wake-orphan-tool-repair.md +161 -0
  58. package/docs/journal/2026/08/20/nightly-push-local-deployment.md +59 -2
  59. package/docs/journal/2026/08/20/wing-remote-memory-replication-verification.md +107 -0
  60. package/docs/journal/2026/08/21/alibaba-singapore-qwen38-official-alignment.md +64 -0
  61. package/docs/journal/2026/08/21/codex-visible-sse-wake-submit-regression.md +85 -0
  62. package/docs/journal/2026/08/21/external-sse-wake-only-change-analysis.md +131 -0
  63. package/docs/journal/2026/08/21/hyundai-invalid-replayed-tool-name-repair.okf +88 -0
  64. package/docs/journal/2026/08/21/local-stale-temporary-runtime-pin-repair.okf +118 -0
  65. package/docs/journal/2026/08/21/transcript-compaction-external-events.okf +131 -0
  66. package/docs/journal/2026/08/21/wing-ai-net-mcp-boundary-diagnosis.okf +129 -0
  67. package/docs/journal/2026/08/21/wing-cold-start-wake-submit-repair.okf +161 -0
  68. package/docs/journal/2026/08/21/wing-powershell-memory-runaway.okf +101 -0
  69. package/docs/journal/2026/08/21/wing-repeated-reasoning-tool-turn-repair.okf +112 -0
  70. package/docs/journal/2026/08/21/wing-repeated-tool-guard-finalization.okf +81 -0
  71. package/docs/journal/2026/08/21/wing-working-directory-memory-deployment.md +110 -0
  72. package/docs/journal/2026/08/21/wing-workspace-state-memory-prompt-injection.md +88 -0
  73. package/docs/journal/2026/08/22/alibaba-singapore-dual-endpoint-wire-alignment.okf +142 -0
  74. package/docs/journal/2026/08/22/delluhiold-claude-compaction-empty-tool-name.okf +168 -0
  75. package/docs/journal/2026/08/22/remote-memory-relative-prompt-paths.okf +79 -0
  76. package/docs/journal/2026/08/22/remote-memory-root-system-prompt.okf +121 -0
  77. package/docs/journal/2026/08/23/claude-web-chat-stateless-mcp-repair.okf +97 -0
  78. package/docs/journal/2026/08/23/cross-runtime-token-usage-interfaces-research.okf +378 -0
  79. package/docs/journal/2026/08/23/main-0.2.23-readme-release.okf +81 -0
  80. package/docs/journal/2026/08/23/mia-openrouter-ox-alpha-latency-diagnosis.okf +146 -0
  81. package/docs/journal/2026/08/23/openrouter-opencode-ox-alpha-support.okf +114 -0
  82. package/docs/journal/2026/08/23/tabitoken-provider-model-catalog.okf +97 -0
  83. package/docs/journal/2026/08/23/usage-stream-snapshot-implementation.okf +134 -0
  84. package/docs/usage-observability.md +141 -0
  85. package/install.ps1 +24 -3
  86. package/package.json +2 -1
@@ -0,0 +1,121 @@
1
+ okf_version: "1.0"
2
+ knowledge:
3
+ task:
4
+ id: remote-memory-root-system-prompt-20260822
5
+ date: "2026-08-22"
6
+ objective: >-
7
+ When remote instructions and remote memory are downloaded, append the
8
+ verified workspace memory root, index path, and an explicit instruction
9
+ to consult that memory at the end of the system context.
10
+
11
+ evidence:
12
+ before_change:
13
+ source: ciel_runtime_support/remote_memory.py
14
+ observed: >-
15
+ The managed prompt block contained only Memory index. It did not expose
16
+ the memory-tree root or explicitly direct the model to consult the
17
+ downloaded files.
18
+ delivery_paths:
19
+ observed: >-
20
+ Provider normalization, tool-schema compaction, protocol conversion,
21
+ and native instruction refresh can all run after an early injection;
22
+ therefore each final wire path requires a final memory projection.
23
+
24
+ implementation:
25
+ managed_tail:
26
+ fields:
27
+ - Memory root
28
+ - Memory index
29
+ - Memory guidance
30
+ guidance: >-
31
+ Read the memory index first and use the relevant files under the memory
32
+ root as context for your work.
33
+ placement:
34
+ native_files:
35
+ claude: CLAUDE.md
36
+ codex_and_codex_app_server: AGENTS.md
37
+ agy: GEMINI.md
38
+ kimi_and_grok: AGENTS.md
39
+ routed_protocols:
40
+ - Anthropic Messages
41
+ - OpenAI Responses
42
+ - OpenAI and Ollama chat
43
+ - Google Generative system instructions
44
+ invariant: >-
45
+ Stale blocks are removed, one current block is emitted, and that block
46
+ is restored at the final privileged tail after normalization and hard
47
+ context compaction.
48
+ validation:
49
+ memory_paths: >-
50
+ Root and index are emitted only when both resolve inside the recorded
51
+ launch workspace and the downloaded directory and index file exist.
52
+ native_file_ownership: >-
53
+ A native instruction file is modified only when its current content
54
+ matches the recorded remote-instruction download, either byte-for-byte
55
+ or after removing the managed block and normalizing line endings.
56
+ legacy_state_upgrade: >-
57
+ State records without the normalized content hash are fetched once
58
+ without conditional HTTP validators so Windows installations acquire a
59
+ verifiable state instead of trusting stale metadata.
60
+ transaction: >-
61
+ Memory tree replacement and state commit roll back together. A later
62
+ native-pointer write failure is reported without misreporting the
63
+ already committed memory download as failed.
64
+
65
+ verification:
66
+ status: passed
67
+ focused:
68
+ command: >-
69
+ python -m unittest -q test_remote_instructions test_remote_memory
70
+ test_remote_memory_runtime_integration
71
+ test_remote_instruction_compaction test_codex_turn_recovery
72
+ result: "79 tests run; all passed"
73
+ live_http:
74
+ result: passed
75
+ observation: >-
76
+ A loopback HTTP server delivered a multi-line CRLF instruction,
77
+ manifest, and nested memory tree on Windows. The instruction bytes and
78
+ text were preserved and the file ended with exactly one verified
79
+ root/index/guidance block.
80
+ final_wire:
81
+ result: passed
82
+ observation: >-
83
+ Direct Chat, Responses, native Anthropic, vLLM Anthropic, and translated
84
+ OpenAI/Ollama transport tests captured the final outgoing body after
85
+ provider policy and context compaction and found one current block at
86
+ the final privileged tail.
87
+ safety_regressions:
88
+ - "A stale shared AGENTS.md state does not modify a user-owned replacement."
89
+ - "LF and CRLF instruction content produce the same ownership digest."
90
+ - "LF and CRLF downloads retain their exact bytes before pointer projection."
91
+ - "A failed memory state commit preserves the prior tree, state, and pointer."
92
+ - "Memory-only configuration does not create native instruction files."
93
+ - "Disabling memory removes only the managed block and preserves user text."
94
+ full_suite:
95
+ total_run: 2690
96
+ passed: 2554
97
+ skipped_environment_dependent: 136
98
+ groups:
99
+ unit: "1147 run, 44 skipped"
100
+ router: "910 run"
101
+ channel: "381 run, 80 skipped"
102
+ runtime: "252 run, 12 skipped"
103
+ quality:
104
+ compileall: passed
105
+ ruff: passed
106
+ documentation_metadata: "passed; 22 Markdown files"
107
+ diff_check: passed
108
+ package_dry_run: "passed; 400 entries"
109
+
110
+ deployment:
111
+ local:
112
+ status: passed
113
+ path: C:/Users/djlov/.local/share/ciel-runtime
114
+ command: C:/Users/djlov/.local/bin/ciel-runtime.ps1
115
+ version_output: "ciel-runtime 0.2.22"
116
+ evidence: >-
117
+ Installed remote_memory.py and remote_instructions.py SHA-256 values
118
+ matched the tested source. Executing the installed module emitted the
119
+ verified root, index, guidance, and closing marker.
120
+ nightly:
121
+ mechanism: "git push origin HEAD:nightly triggers npm-publish.yml"
@@ -0,0 +1,97 @@
1
+ okf_version: "1.0"
2
+ knowledge:
3
+ task:
4
+ id: claude-web-chat-stateless-mcp-repair-20260823
5
+ date: "2026-08-23"
6
+ workspace: G:/ncc
7
+ objective: >-
8
+ Determine why a Web Chat message reached the Claude prompt but the
9
+ session could not reply through Ciel Runtime, then restore only the
10
+ supported stateless internal MCP path.
11
+ status: implementation-complete
12
+
13
+ observed_evidence:
14
+ router_instance: C:/Users/djlov/AppData/Roaming/ciel-runtime/router-instances/9467-84a9f0d21381
15
+ workspace_state: C:/Users/djlov/AppData/Roaming/ciel-runtime/workspaces/84a9f0d21381
16
+ message:
17
+ persisted_id: 1
18
+ channel: web-chat-1dc2cba6-9ac5-4970-8d46-e90574fe77cb
19
+ tty_submit_log:
20
+ timestamp: "2026-08-23T18:26:50"
21
+ enter: crlf
22
+ submit_confirmed: true
23
+ claude_launch:
24
+ timestamp: "2026-08-23T18:25:11"
25
+ log: "claude_launch_cmd ciel_mcp_config=- argv_len=7"
26
+ actual_command_contains_mcp_config: false
27
+ router_probe_before_change:
28
+ method: POST
29
+ path: /ca/mcp
30
+ status: 404
31
+ conclusion: >-
32
+ The message queue and TTY injection were active, but the launched Claude
33
+ process had no Ciel MCP configuration and the composed router disabled
34
+ the internal MCP POST handler.
35
+
36
+ historical_constraint:
37
+ retired_implementation:
38
+ commit: e354683ecbb804c25560dce067b8c2fc18f163ca
39
+ kind: legacy Claude channel MCP bridge
40
+ retained_constraint: >-
41
+ Do not restore the legacy SSE endpoint, session registry, replay cursor,
42
+ or Ciel ownership of external MCP server lifecycles.
43
+
44
+ implementation:
45
+ router:
46
+ restored: stateless POST /ca/mcp handler only
47
+ get_stream_restored: false
48
+ sse_restored: false
49
+ claude_launch:
50
+ condition: LLM channel delivery plus workspace Web backend start
51
+ server_name: ciel-runtime-router
52
+ transport: streamable_http
53
+ url_suffix: /ca/mcp
54
+ artifact_scope: ephemeral workspace launch lease
55
+ persistent_workspace_config_mutated: false
56
+ genericity: >-
57
+ Workspace MCP launch preparation accepts normalized injected server maps;
58
+ the mechanism is not keyed to a user, machine, or provider.
59
+
60
+ verification:
61
+ workspace_mcp_tests: "17 passed"
62
+ channel_bridge_tests: "207 passed, 80 skipped"
63
+ deepseek_provider_tests: "21 passed"
64
+ architecture_contracts: "261 passed, 42 skipped"
65
+ live_isolated_router:
66
+ initialize_status: 200
67
+ protocol: 2025-03-26
68
+ server: ciel-runtime-router
69
+ tools_list_status: 200
70
+ tools: [compact_session, send_message, send_file, llm_options]
71
+ full_suite:
72
+ unit: "1164 passed, 44 skipped"
73
+ router: "923 passed"
74
+ channel: "381 passed, 80 skipped"
75
+ runtime: "252 passed, 12 skipped"
76
+ ruff: passed
77
+ documentation_metadata: "passed; 23 Markdown files"
78
+ package_dry_run: "passed; 411 files"
79
+
80
+ deployment:
81
+ local:
82
+ status: passed
83
+ path: C:/Users/djlov/.local/share/ciel-runtime
84
+ source_hash_matched: true
85
+ installed_tools_list_status: 200
86
+ installed_tools: [compact_session, send_message, send_file, llm_options]
87
+ restart_required_for_existing_claude_session: true
88
+ nightly:
89
+ status: passed
90
+ source_commit: 45a9456ffaa554598e5196bae3df18a936f3c88b
91
+ version: 0.2.22-nightly.20260823-234610.45a9456
92
+ ci_run: 32674465612
93
+ publish_run: 32674465609
94
+ registry_git_head_matched: true
95
+ clean_registry_install_source_hash_matched: true
96
+ clean_registry_install_tools_status: 200
97
+ clean_registry_install_tools: [compact_session, send_message, send_file, llm_options]
@@ -0,0 +1,378 @@
1
+ okf_version: "1.0"
2
+ knowledge:
3
+ task:
4
+ id: cross-runtime-token-usage-interfaces-research-20260823
5
+ date: "2026-08-23"
6
+ objective: >-
7
+ Research evidence-backed interfaces for real-time token-usage delivery and
8
+ authenticated time-range queries across every CLI runtime supported by
9
+ ciel-runtime.
10
+ status: research-complete
11
+ implementation_status: not-started
12
+
13
+ confirmed_current_state:
14
+ runtime_families:
15
+ - claude-code
16
+ - codex-tui
17
+ - codex-app-server
18
+ - agy
19
+ - kimi-code
20
+ - grok-build
21
+ usage_event:
22
+ source: ciel_runtime_support/usage_events.py
23
+ persisted_fields:
24
+ - provider
25
+ - model
26
+ - input_tokens
27
+ - output_tokens
28
+ - request_id
29
+ - protocol
30
+ - status
31
+ - timestamp
32
+ missing_required_fields:
33
+ - runtime
34
+ - workspace_id
35
+ - session_id
36
+ - turn_id
37
+ - cache_read_input_tokens
38
+ - cache_write_input_tokens
39
+ - reasoning_output_tokens
40
+ - request_started_at
41
+ - request_completed_at
42
+ - duration_ms
43
+ - usage_source
44
+ - is_estimated
45
+ - is_incomplete
46
+ storage: rotating-jsonl
47
+ current_summary_dimensions: [provider, model]
48
+ current_summary_values: [requests, input_tokens, output_tokens]
49
+ router_activity:
50
+ source: ciel_runtime_support/runtime_activity.py
51
+ behavior: >-
52
+ An atomic latest-state snapshot is overwritten for each update. It is
53
+ not a durable usage ledger and cannot answer historical range queries.
54
+ event_bus:
55
+ source: ciel_runtime_support/event_bus.py
56
+ behavior: >-
57
+ A process-local bounded deque feeds recent-event and SSE routes. It is
58
+ not restart-safe and therefore cannot be the source of truth.
59
+ external_authentication:
60
+ source: ciel_runtime_support/router_access.py
61
+ behavior: >-
62
+ One router-wide bearer token or x-ciel-runtime-token protects external
63
+ router access. There are no independent usage-consumer keys, scopes,
64
+ expirations, per-key revocation records, or last-used audit fields.
65
+ outbound_delivery_pattern:
66
+ source: ciel_runtime_support/transcript_delta_delivery.py
67
+ reusable_properties:
68
+ - CloudEvents 1.0 envelope
69
+ - persistent per-destination cursor
70
+ - cursor advance only after HTTP 2xx
71
+ - stable Idempotency-Key across retries
72
+ - environment-expanded authorization header
73
+ - byte-bounded batching
74
+ - rotation-aware incremental delivery
75
+ observed_local_state:
76
+ workspace_state: C:/Users/djlov/AppData/Roaming/ciel-runtime/workspaces/bd5f642b3583
77
+ router_instance: C:/Users/djlov/AppData/Roaming/ciel-runtime/workspaces/bd5f642b3583/router-instances/6971-bd5f642b3583
78
+ usage_events_jsonl: absent
79
+ router_activity_json: present
80
+ implication: >-
81
+ The inspected instance has a latest request snapshot but no durable
82
+ usage-event file from which a time-range total could be produced.
83
+
84
+ confirmed_collection_sources:
85
+ claude_code:
86
+ official_source: https://code.claude.com/docs/en/monitoring-usage
87
+ exact_source: OpenTelemetry claude_code.api_request event or LLM span
88
+ available_fields:
89
+ - model
90
+ - duration_ms
91
+ - input_tokens
92
+ - output_tokens
93
+ - cache_read_tokens
94
+ - cache_creation_tokens
95
+ - request_id
96
+ - client_request_id
97
+ - cost
98
+ - effort
99
+ current_ciel_adapter: absent
100
+ codex_app_server:
101
+ official_source: https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md
102
+ exact_source: experimental rawResponse/completed usage
103
+ accumulated_source: thread/tokenUsage/updated
104
+ persistence_note: >-
105
+ thread/tokenUsage/updated is accumulated and replayed on resume;
106
+ rawResponse/completed is exact per upstream response but experimental
107
+ and is not persisted or replayed.
108
+ current_ciel_adapter: absent
109
+ codex_tui:
110
+ local_evidence:
111
+ version: 0.149.0
112
+ source: ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
113
+ observed_event: token_count
114
+ observed_fields:
115
+ - input_tokens
116
+ - cached_input_tokens
117
+ - cache_write_input_tokens
118
+ - output_tokens
119
+ - reasoning_output_tokens
120
+ - total_tokens
121
+ deduplication_constraint: >-
122
+ token_count records can repeat unchanged last_token_usage values. A
123
+ collector must use monotonic total deltas or a stable request identity,
124
+ not blindly sum every record.
125
+ current_ciel_adapter: absent
126
+ agy:
127
+ official_source: https://www.agy.dev/docs/cli/headless/
128
+ confirmed_headless_source: --output-format stream-json
129
+ available_fields:
130
+ - input_tokens
131
+ - output_tokens
132
+ - thinking_tokens
133
+ - cache_read_tokens
134
+ - total_tokens
135
+ - duration
136
+ interactive_source_status: not-confirmed
137
+ ciel_routed_semantics:
138
+ source: ciel_runtime_support/provider_choice.py
139
+ behavior: >-
140
+ AGY Routed retains native Google Antigravity model authentication and
141
+ settings; Ciel adds channel and PTY wake support only. Model requests
142
+ do not thereby become observable at the Ciel router.
143
+ kimi_code:
144
+ official_source: https://github.com/MoonshotAI/kimi-code/blob/main/AGENTS.md
145
+ installed_package_source: '@moonshot-ai/kimi-code 0.36.0'
146
+ exact_source: agents/<agentId>/wire.jsonl usage.record entries
147
+ available_fields:
148
+ - inputOther
149
+ - output
150
+ - inputCacheRead
151
+ - inputCacheCreation
152
+ - model
153
+ - usageScope
154
+ routed_behavior:
155
+ source: ciel_runtime_support/kimi_runtime_context.py
156
+ behavior: >-
157
+ Kimi Routed sets KIMI_MODEL_BASE_URL to the local Ciel /v1 endpoint,
158
+ so routed requests are also observable at the router.
159
+ current_ciel_adapter: absent
160
+ grok_build:
161
+ official_source: https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/14-headless-mode.md
162
+ confirmed_headless_source: streaming-json end event
163
+ available_fields:
164
+ - input_tokens
165
+ - cache_read_input_tokens
166
+ - output_tokens
167
+ - reasoning_tokens
168
+ - total_tokens
169
+ - modelUsage
170
+ - usage_is_incomplete
171
+ interactive_source:
172
+ source: ~/.grok/README.md
173
+ confirmed_storage: sessions/<encoded-cwd>/<session-id>/signals.json
174
+ exact_schema_status: not-observed-locally
175
+ current_ciel_adapter: absent
176
+ routed_protocols:
177
+ openai_responses:
178
+ official_source: https://developers.openai.com/api/reference/resources/responses
179
+ current_ciel_observer: ciel_runtime_support/responses_usage_observer.py
180
+ observed_fields:
181
+ - input_tokens
182
+ - output_tokens
183
+ - cache_read_tokens
184
+ - cache_creation_tokens
185
+ - uncached_input_tokens
186
+ current_gap: >-
187
+ These detailed fields reach the latest router-activity snapshot but
188
+ are reduced to input/output in the durable UsageEvent.
189
+ openai_chat:
190
+ current_ciel_behavior: streamed bytes are passed through without usage parsing
191
+ anthropic_messages:
192
+ official_source: https://platform.claude.com/docs/en/api/messages/create
193
+ official_fields:
194
+ - input_tokens
195
+ - output_tokens
196
+ - cache_creation_input_tokens
197
+ - cache_read_input_tokens
198
+ - output_tokens_details.thinking_tokens
199
+ current_ciel_behavior: native/routed Anthropic SSE lacks a general durable usage observer
200
+ ollama:
201
+ official_source: https://docs.ollama.com/api/usage
202
+ official_fields:
203
+ - prompt_eval_count
204
+ - eval_count
205
+ - total_duration
206
+ - load_duration
207
+ - prompt_eval_duration
208
+ - eval_duration
209
+ cache_breakdown_status: not-defined-in-the-cited-usage-contract
210
+
211
+ proposed_contract:
212
+ collection_boundary:
213
+ truly_routed_requests: >-
214
+ Capture usage once at the Ciel Router response boundary. The router is
215
+ the canonical collector because both the upstream request and response
216
+ pass through it. Do not also ingest the CLI journal for the same call.
217
+ native_or_bypass_requests: >-
218
+ Use the runtime-specific collector because the model API exchange does
219
+ not cross the Ciel Router.
220
+ terminology_exception: >-
221
+ AGY Routed is not a model-traffic route in the current implementation;
222
+ it adds channel and PTY wake support only. It therefore belongs to the
223
+ native-or-bypass collection case.
224
+ protocol_constraint: >-
225
+ Exact token counts still depend on the upstream response exposing usage.
226
+ Each routed protocol adapter must parse its non-streaming response or
227
+ terminal streaming usage event. Missing provider usage remains null or
228
+ explicitly estimated; it must not be presented as an exact count.
229
+ canonical_usage_event:
230
+ identity:
231
+ fields: [event_id, schema_version, workspace_id, runtime, session_id, turn_id, request_id]
232
+ routing:
233
+ fields: [provider, model, protocol, runtime_version]
234
+ time:
235
+ fields: [observed_at, request_started_at, request_completed_at, duration_ms]
236
+ usage:
237
+ fields:
238
+ - input_tokens_uncached
239
+ - cache_read_input_tokens
240
+ - cache_write_input_tokens
241
+ - input_tokens_total
242
+ - output_tokens
243
+ - reasoning_output_tokens
244
+ - total_tokens
245
+ quality:
246
+ fields: [usage_source, is_estimated, is_incomplete, status]
247
+ raw:
248
+ field: raw_usage
249
+ rule: optional, redacted, and protocol-namespaced
250
+ nullability_rule: >-
251
+ An unavailable metric remains null. Unknown cache usage must not be
252
+ represented as zero.
253
+ normalization_rules:
254
+ openai: >-
255
+ input_tokens is total input; derive uncached input by subtracting cache
256
+ read and cache write details when those details are present.
257
+ anthropic: >-
258
+ input_tokens is uncached input; total processed input is input_tokens
259
+ plus cache_read_input_tokens plus cache_creation_input_tokens.
260
+ output_reasoning: >-
261
+ Reasoning or thinking tokens are stored as a breakdown. They are not
262
+ added a second time when the provider's output total already includes
263
+ them.
264
+ source_precedence:
265
+ - exact routed response usage when the request traverses Ciel Router
266
+ - exact CLI-native per-request event when the request bypasses Ciel Router
267
+ - monotonic session-journal delta
268
+ - explicit estimate
269
+ deduplication:
270
+ rule: >-
271
+ Prefer provider response/request IDs. Otherwise use runtime, workspace,
272
+ session, turn, and sequence identity. Never sum a native CLI event and a
273
+ router event for the same request.
274
+
275
+ proposed_interfaces:
276
+ durable_ledger:
277
+ scope: workspace
278
+ proposed_location: WORKSPACE_STATE_DIR/usage/usage.sqlite3
279
+ not_router_instance_reason: >-
280
+ Router-instance directories are process/port-specific. A time-range
281
+ ledger must survive router restarts and instance rotation.
282
+ indexes:
283
+ - request_completed_at
284
+ - workspace_id-runtime-request_completed_at
285
+ - provider-model-request_completed_at
286
+ - request_id
287
+ realtime_delivery:
288
+ event_type: ai.oneciel.ciel-runtime.usage.recorded
289
+ ordering: persist-ledger-then-enqueue-outbox
290
+ transports:
291
+ - outbound authenticated webhook to configured receivers
292
+ - authenticated local SSE stream with a resumable after cursor
293
+ delivery_rules:
294
+ - never block a model response on receiver availability
295
+ - retry with the same event_id and Idempotency-Key
296
+ - advance delivery cursor only after HTTP 2xx
297
+ - preserve immutable usage records
298
+ - retain retry state and dead-letter state separately
299
+ query_api:
300
+ event_route: GET /ca/usage/events
301
+ summary_route: GET /ca/usage/summary
302
+ stream_route: GET /ca/usage/stream
303
+ required_filters:
304
+ - from
305
+ - to
306
+ - runtime
307
+ - provider
308
+ - model
309
+ - workspace_id
310
+ pagination: cursor-and-limit
311
+ aggregation_dimensions: [runtime, provider, model, hour, day]
312
+ response_integrity:
313
+ fields: [coverage, incomplete_sources]
314
+ reason: >-
315
+ A cross-runtime total must reveal which collectors were unavailable or
316
+ incomplete during the requested interval.
317
+ consumer_api_keys:
318
+ separation_rule: >-
319
+ Usage-consumer credentials are separate from the router-wide external
320
+ token and from every upstream provider secret. Provider API keys are
321
+ never returned in usage events or query responses.
322
+ issued_secret: returned-once
323
+ persisted_metadata:
324
+ - key_id
325
+ - key_prefix
326
+ - keyed_hash
327
+ - scopes
328
+ - created_at
329
+ - expires_at
330
+ - revoked_at
331
+ - last_used_at
332
+ scopes: [usage:read, usage:stream]
333
+ administration: local-or-admin-only issue, rotate, list, and revoke operations
334
+ verification: constant-time comparison, rate limiting, and audit logging
335
+
336
+ coverage_and_gaps:
337
+ exact_or_documented_paths:
338
+ - Claude Code OpenTelemetry
339
+ - Codex app-server raw response and accumulated token usage
340
+ - Codex TUI rollout token_count journal
341
+ - AGY headless stream-json
342
+ - Kimi wire.jsonl usage.record
343
+ - Grok Build headless streaming-json end event
344
+ - routed OpenAI Responses observer
345
+ unconfirmed_or_incomplete_paths:
346
+ - AGY interactive exact usage source
347
+ - Grok interactive signals.json exact schema on this machine
348
+ - OpenAI Chat streaming usage parser in Ciel
349
+ - general Anthropic Messages durable usage observer in Ciel
350
+ - durable cache and reasoning fields in UsageEvent
351
+ - per-consumer API-key issuance and authorization
352
+ - durable time-range query store and API
353
+ - usage-specific outbound webhook worker
354
+ conclusion: >-
355
+ Both requested interfaces are feasible, but the current repository does
356
+ not implement them end to end. Implementation requires runtime-specific
357
+ collectors feeding one workspace-scoped canonical ledger, an idempotent
358
+ asynchronous delivery outbox, and a separately authenticated query API.
359
+
360
+ verification:
361
+ evidence_types:
362
+ - repository source inspection
363
+ - installed CLI version and package inspection
364
+ - local Codex rollout JSONL inspection
365
+ - current workspace state inspection
366
+ - official vendor documentation
367
+ no_live_inference_performed: true
368
+ reason: >-
369
+ This task requested research. No provider request was sent and no usage
370
+ feature implementation or deployment was performed.
371
+ focused_baseline_tests:
372
+ command_style: python -m unittest discover -s tests -p <file> -v
373
+ results:
374
+ test_usage_events.py: "3 passed"
375
+ test_responses_usage_observer.py: "2 passed"
376
+ test_transcript_delta_delivery.py: "4 passed"
377
+ test_router_access.py: "7 passed"
378
+ total: "16 passed"
@@ -0,0 +1,81 @@
1
+ okf_version: "1.0"
2
+ knowledge:
3
+ task:
4
+ id: main-0.2.23-readme-release-20260823
5
+ date: "2026-08-23"
6
+ workspace: C:/Users/djlov/ciel-runtime
7
+ objective: >-
8
+ Audit every commit after 0.2.22, redesign the project README using
9
+ verified patterns from established CLI repositories, publish grouped
10
+ release notes, bump the version, and promote the result to main.
11
+ status: local-verification-complete
12
+
13
+ evidence:
14
+ release_base:
15
+ branch: origin/main
16
+ commit: b7ea3822a1e401d78d65000504cf02089df1a1fc
17
+ version: 0.2.22
18
+ candidate:
19
+ branch: origin/nightly
20
+ commit_before_release_work: 549e6a65e31e84cf48b68f34cb414c03204f5350
21
+ commits_audited: 41
22
+ files_changed: 110
23
+ insertions: 9990
24
+ deletions: 256
25
+ fast_forward_from_main: true
26
+ npm:
27
+ current_latest: 0.2.22
28
+ target_version: 0.2.23
29
+ target_existed_before_release: false
30
+
31
+ readme_research:
32
+ sources:
33
+ - repository: openai/codex
34
+ url: https://github.com/openai/codex
35
+ observed_structure: concise identity, immediate quickstart, compact documentation routing
36
+ - repository: ollama/ollama
37
+ url: https://github.com/ollama/ollama
38
+ observed_structure: platform installation, get-started examples, API and integration discovery
39
+ - repository: astral-sh/uv
40
+ url: https://github.com/astral-sh/uv
41
+ observed_structure: highlights, installation, grouped feature taxonomy, documentation links
42
+ - repository: cli/cli
43
+ url: https://github.com/cli/cli
44
+ observed_structure: short identity, documentation, installation by platform, contribution routing
45
+ applied_pattern: >-
46
+ Lead with product identity and an installable quickstart, then progressively
47
+ disclose runtime/provider architecture, capability summaries, operations,
48
+ release channels, documentation, development, and security.
49
+
50
+ artifacts:
51
+ readme: README.md
52
+ changelog: CHANGELOG.md
53
+ release_version_files:
54
+ - package.json
55
+ - ciel_runtime_support/runtime_constants.py
56
+
57
+ verification:
58
+ status: local-passed
59
+ documentation_metadata: "passed; 23 Markdown files"
60
+ lint: passed
61
+ diff_check: passed
62
+ complete_test_suite:
63
+ unit: "1164 passed, 44 skipped"
64
+ router: "923 passed"
65
+ channel: "381 passed, 80 skipped"
66
+ runtime: "252 passed, 12 skipped"
67
+ total_passed: 2720
68
+ npm_pack:
69
+ status: passed
70
+ version: 0.2.23
71
+ entries: 413
72
+ changelog_included: true
73
+ local_install:
74
+ status: passed
75
+ path: C:/Users/djlov/.local/share/ciel-runtime
76
+ reported_version: 0.2.23
77
+ source_hash_matches: 5
78
+ remaining:
79
+ - nightly publish and clean registry install
80
+ - main CI and stable npm publish
81
+ - rendered GitHub README screenshot