feat(frontend): track cfs_sign Plausible event#13144
Draft
sbpublic wants to merge 7 commits into
Draft
Conversation
Add CFS_SIGN to PLAUSIBLE_EVENTS plus the PLAUSIBLE_EVENT_RESULT_SEVERITIES and PLAUSIBLE_EVENT_SUBCONTEXT_CFS enums used to describe each paid chain-fusion-signer call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Detect the chain-fusion signer's payment outage (backend out of cycles) from a thrown error. Every PaymentError variant maps to signer-unavailable, not a user error. Reused by analytics now and the friendly toast later. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
trackCfsSign builds the cfs_sign payload (method, status, duration, token_network, and on error the mapped message, raw text and severity: blocker for the signer payment outage, critical otherwise). withCfsSignTracking times a paid signer call and emits on both success and error, always re-throwing so it never swallows the underlying error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap each exported signer.api function in withCfsSignTracking at the single API chokepoint, so address/balance reads and every signing operation emit a cfs_sign event tagged with the called method. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the cfs_sign subsection to PRODUCT.md Analytics and commit the spec-driven-development spec into the repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 18, 2026
Collaborator
Author
Review — ✅ LGTM (observability half)Faithful to Part B of the spec, pure addition, no behaviour change.
Two minor, non-blocking notes:
|
Collaborator
Author
Follow-up — final design (Part B)Tracking design was refined since the review above — both good calls:
Still ✅ LGTM. |
…fs-sign-event # Conflicts: # src/frontend/src/lib/enums/plausible.ts # src/frontend/src/lib/services/analytics.services.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
A recent support incident: the chain-fusion signer could not sign for any user because OISY's backend ran out of TCycles on the cycles ledger. Every paid signer call attaches a payment, so when the backend account runs dry the signer returns a
PaymentErrorand signing fails wallet-wide. Today this class of incident is invisible on our dashboards until support tickets arrive.This PR (the first of two from the spec) adds the observability half: a
cfs_signPlausible event on every paid chain-fusion-signer call, so the next outage is visible immediately — broken down by method, and flaggedresult_error_severity = blockerwhen it is the backend-out-of-cycles case.It is a pure addition with no behaviour change. The follow-up PR adds the user-facing friendly toast.
Spec:
docs/ai/spec-driven-development/specs/2026-06-18-impr-cfs-signing-error-toast-and-cfs-sign-event.md(Part B).Changes
PLAUSIBLE_EVENTS.CFS_SIGN, and thePLAUSIBLE_EVENT_RESULT_SEVERITIESandPLAUSIBLE_EVENT_SUBCONTEXT_CFSenums.isSignerCanisterPaymentErrorguard insigner.errors.ts— everyPaymentErrorvariant is treated as "signer temporarily unavailable" (reused by the follow-up toast PR).trackCfsSign+withCfsSignTrackinginanalytics.services.ts. The wrapper times the call, emits on both success and error, sets severityblockerfor the payment outage /criticalotherwise, and always re-throws so it never swallows the error or interrupts a send.signer.api.ts(the single chokepoint all paid signer calls pass through) with the matching method subcontext. Covers address/balance reads and all signing operations.token_network(eth/btc/sol) from the method prefix; omitted for chain-agnostic generic ECDSA.PRODUCT.md(Analytics) and commit the spec into the repo.Tests
signer.errors.spec.ts:isSignerCanisterPaymentErrorreturns true for eachPaymentErrorvariant, false forCanisterInternalError/ plainError/ nullish / string.analytics.service.spec.ts: success emitscfs_signwith method/status/duration/token_network; error emitsresult_error*withblockerfor a payment error andcriticalotherwise;token_networkderivation per prefix;withCfsSignTrackingre-throws.npm run format,eslint --max-warnings 0, and the touched unit specs (37 tests) pass.svelte-checkreports no problems in the changed files.Divergence from the spec
withCfsSignTrackingtakes a single object param{ method, fn }instead of the spec's positional(method, fn)signature, to satisfy the repo'slocal-rules/prefer-object-paramslint rule (enforced under--max-warnings 0). Call sites updated accordingly.isSignerCanisterPaymentErrorguard (spec Part A1) is introduced here in PR1 rather than the toast PR, becausetrackCfsSignneeds it; the toast PR will reuse it.🤖 Generated with Claude Code — model: Claude Opus 4.8 (claude-opus-4-8)