Before submitting
Problem or opportunity
Since #1299, extensions register usage sources on gentle-pi:usage-source/v1 and gentle-shell meters them like built-ins. But event delivery is fire-and-forget: the owning extension cannot tell "the shell accepted my registration and meters this provider natively" from "nobody consumed my source". Extensions that also ship their own fallback segment (so they work without gentle-shell) must therefore always paint it, which duplicates the native usage next to it and ignores the user's /gentle:customize settings — e.g. visibility.usageCost=false or statusPlacement=hidden hide the native meter while the third-party segment keeps showing. This affects any third-party meter built on the hook (e.g. the Z.ai GLM Coding Plan meter for #687, xAI in #800).
Proposed outcome
gentle-shell emits an acknowledgement on the same bus for every registration it accepts: gentle-pi:usage-source-ack/v1 with { schema: "gentle-pi.usage-source-ack/v1", provider } on pi.events, replacements included (so re-emitting at every session_start renews it). Malformed payloads — which never register anything — are never acknowledged. Consumers can then retire their fallback UI when the shell meters natively and keep it otherwise (older shell, no shell, rejected payload). ~15 lines in lib/shell-usage.ts plus the emit in the existing USAGE_SOURCE_EVENT handler; contract documented in docs/gentle-shell.md next to the registration example.
Alternatives considered
- Extensions reading gentle-shell's
visual-customization.json directly (rejected: couples a third-party package to an internal settings file, and still cannot tell whether the shell actually consumed the registration).
- A presence/global-symbol probe (rejected: undocumented internals, same load-order fragility the event was designed to avoid).
Additional context
Working implementation with tests and docs ready on a local branch (feat/usage-source-ack, commit 36637079), plus a consumer that already retires its standalone segment on the ack (Z.ai GLM Coding Plan meter, danielgap/pi-zai-usage). Happy to open the PR when this gets status:approved.
Before submitting
Problem or opportunity
Since #1299, extensions register usage sources on
gentle-pi:usage-source/v1and gentle-shell meters them like built-ins. But event delivery is fire-and-forget: the owning extension cannot tell "the shell accepted my registration and meters this provider natively" from "nobody consumed my source". Extensions that also ship their own fallback segment (so they work without gentle-shell) must therefore always paint it, which duplicates the native usage next to it and ignores the user's/gentle:customizesettings — e.g.visibility.usageCost=falseorstatusPlacement=hiddenhide the native meter while the third-party segment keeps showing. This affects any third-party meter built on the hook (e.g. the Z.ai GLM Coding Plan meter for #687, xAI in #800).Proposed outcome
gentle-shell emits an acknowledgement on the same bus for every registration it accepts:
gentle-pi:usage-source-ack/v1with{ schema: "gentle-pi.usage-source-ack/v1", provider }onpi.events, replacements included (so re-emitting at everysession_startrenews it). Malformed payloads — which never register anything — are never acknowledged. Consumers can then retire their fallback UI when the shell meters natively and keep it otherwise (older shell, no shell, rejected payload). ~15 lines inlib/shell-usage.tsplus the emit in the existingUSAGE_SOURCE_EVENThandler; contract documented indocs/gentle-shell.mdnext to the registration example.Alternatives considered
visual-customization.jsondirectly (rejected: couples a third-party package to an internal settings file, and still cannot tell whether the shell actually consumed the registration).Additional context
Working implementation with tests and docs ready on a local branch (
feat/usage-source-ack, commit36637079), plus a consumer that already retires its standalone segment on the ack (Z.ai GLM Coding Plan meter, danielgap/pi-zai-usage). Happy to open the PR when this getsstatus:approved.