Skip to content

docs: product telemetry taxonomy (#341)#741

Merged
Chris0Jeky merged 3 commits intomainfrom
docs/341-telemetry-taxonomy
Apr 4, 2026
Merged

docs: product telemetry taxonomy (#341)#741
Chris0Jeky merged 3 commits intomainfrom
docs/341-telemetry-taxonomy

Conversation

@Chris0Jeky
Copy link
Copy Markdown
Owner

Summary

  • Defines event naming convention (noun.verb), 7 event categories, per-event property contracts, and hard privacy guardrails for Taskdeck product telemetry
  • Documents what to collect (counts, durations, enums, opaque IDs), what to avoid (PII, user content, card/board names, email), and opt-in stance (disabled by default)
  • Adds R1/R2/R3 launch-gate telemetry anchors: minimum signal coverage required before promoting each release gate
  • Closes TST-23: Add product telemetry taxonomy and R1/R2/R3 launch-gate follow-through #341

Test plan

  • Docs are clear and consistent with GOLDEN_PRINCIPLES.md (GP-06 review-first, GP-08 product legibility, GP-09 traceable agent expansion)
  • No PII collection described anywhere in event definitions
  • Event names follow noun.verb convention throughout
  • All 7 categories covered: Capture, Proposal/Review, Board, Auth, Navigation, Agent, Error
  • Launch gates R1/R2/R3 have explicit telemetry signal requirements
  • Implementation notes are practical and reuse existing anchors

Define event naming convention (noun.verb), categories, per-event
property contracts, privacy guardrails, and R1/R2/R3 launch-gate
telemetry anchors. Telemetry is opt-in and disabled by default.
Copilot AI review requested due to automatic review settings April 4, 2026 01:06
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive telemetry taxonomy for Taskdeck, establishing strict privacy guardrails and standardized event naming conventions. The feedback focuses on improving consistency across the document, specifically recommending the use of bucketing for item counts to enhance privacy, standardizing duration units to milliseconds, and ensuring HTTP status codes are consistently represented as numeric types.

Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
### `proposal.list_loaded`
Review/proposals list loaded successfully.

Required: `pending_count: number`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Inconsistency in count collection. While capture.inbox_loaded (line 115) and board.loaded (line 181) use bucketing (e.g., item_count_bucket) to protect user privacy, proposal.list_loaded uses a raw number. To align with the "privacy-first" stance and prevent potential fingerprinting via exact item counts, this should also be bucketed. This recommendation also applies to approved_count (line 165), rejected_count (line 170), and proposals_created (line 322).

Suggested change
Required: `pending_count: number`
Required: pending_count_bucket: string — bucketed: empty, small (1–10), medium (11–50), large (>50)

Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
User explicitly approved a proposal.

Required: `proposal_id: string`, `proposal_risk_level: string`
Optional: `time_to_decision_seconds: number` — seconds from `proposal.opened` to approval
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Inconsistency in duration units. Most events in this taxonomy use _ms (milliseconds), but proposal.approved and proposal.rejected use seconds. Standardizing on milliseconds across all events ensures consistency in the telemetry pipeline and avoids unit conversion errors during analysis. Please update line 149 as well for consistency.

Suggested change
Optional: `time_to_decision_seconds: number`seconds from `proposal.opened` to approval
Optional: time_to_decision_ms: number — milliseconds from proposal.opened to approval

Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
### `auth.login_failed`
Login attempt failed.

Required: `error_code: string` — use HTTP status code as string (e.g. `401`, `429`). Do not include credential content.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Inconsistency in HTTP status code representation. auth.login_failed uses error_code as a string, while error.api_request_failed (line 354) uses status_code as a number. It is recommended to use status_code: number for HTTP status codes to maintain consistency with the rest of the taxonomy and reserve error_code: string for application-specific error identifiers.

Suggested change
Required: `error_code: string`use HTTP status code as string (e.g. `401`, `429`). Do not include credential content.
Required: status_code: number — HTTP status code (e.g. 401, 429). Do not include credential content.

Clarify that capture.triage_clicked item_id is opaque UUID only.
Enumerate surface values for error.unhandled to match page.loaded enum
plus component-level values, closing adversarial review gaps.
@Chris0Jeky
Copy link
Copy Markdown
Owner Author

Adversarial self-review

PII protection: All event properties are opaque UUIDs, counts, durations, booleans, or fixed-enum values. No card/board names, usernames, email addresses, or free-text fields appear anywhere. The `input_length_bucket` pattern avoids exact-length inference. The "What NOT to Collect" table is concrete with examples. Pass.

Naming convention consistency: All 35+ events follow `noun.verb` with lowercase underscores for multi-word nouns. No abbreviations. Consistent throughout. Pass.

Core flow coverage: The primary Taskdeck loop (capture → proposal → approve → execute → board) is fully instrumented. The R1 launch gate explicitly calls out the `capture.submitted → proposal.approved → proposal.executed` funnel as a required observable signal. Pass.

Gaps identified and fixed (follow-up commit f4f40fe):

  • `capture.triage_clicked.item_id`: Added explicit note that this is opaque UUID only, not content-derived.
  • `error.unhandled.surface`: Enumerated the valid values to match `page.loaded` enum plus component-level values. Previously vague.

Governance checks: `check-docs-governance.mjs` and `check-github-ops-governance.mjs` both pass.

No further issues found.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new canonical documentation spec for Taskdeck’s product telemetry taxonomy, aiming to standardize event naming, property contracts, and privacy guardrails to support later implementation and release-gate validation.

Changes:

  • Defines a noun.verb telemetry naming convention plus universal envelope fields and privacy “never collect” rules.
  • Documents 7 telemetry event categories (Capture, Proposal/Review, Board, Auth, Navigation, Agent, Error) with required/optional properties.
  • Introduces R1/R2/R3 launch-gate “minimum signal coverage” anchors tied to specific telemetry signals.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
Comment on lines +30 to +40
- **Verb**: the action or state transition (e.g. `created`, `approved`, `loaded`, `failed`)

Examples:
- `card.created`
- `proposal.approved`
- `session.started`
- `agent_run.completed`

Rules:
- All names are lowercase with underscores for multi-word nouns (e.g. `agent_run`, `first_run`).
- Verbs use past tense for completed actions (`created`, `approved`, `failed`) and present tense for states (`loaded`, `opened`).
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming rules here don’t match the event list below: many verbs use underscores (e.g. modal_opened, inbox_loaded, login_failed) even though the rule only mentions underscores for multi-word nouns, and the “present tense for states” examples (loaded, opened) are not present tense. Please tighten the convention to reflect the actual intended grammar/format (e.g., explicitly allow underscores in both segments and clarify tense/voice for state events).

Suggested change
- **Verb**: the action or state transition (e.g. `created`, `approved`, `loaded`, `failed`)
Examples:
- `card.created`
- `proposal.approved`
- `session.started`
- `agent_run.completed`
Rules:
- All names are lowercase with underscores for multi-word nouns (e.g. `agent_run`, `first_run`).
- Verbs use past tense for completed actions (`created`, `approved`, `failed`) and present tense for states (`loaded`, `opened`).
- **Verb**: the action, outcome, or resulting state transition (e.g. `created`, `approved`, `loaded`, `failed`)
Examples:
- `card.created`
- `proposal.approved`
- `session.started`
- `agent_run.completed`
- `inbox.marked_read`
Rules:
- Event names consist of two dot-separated segments: `noun.verb`.
- All segments are lowercase. Use underscores within any multi-word segment for legibility (e.g. `agent_run`, `first_run`, `marked_read`).
- Use action/outcome names in past tense or past-participle form for completed actions and resulting state events (e.g. `created`, `approved`, `loaded`, `opened`, `failed`).

Copilot uses AI. Check for mistakes.
Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
### `capture.submitted`
User submitted a capture item.

Required: `has_attachment: boolean`
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capture.submitted doesn’t include any source/channel field, but the R3 launch-gate anchors later require measuring capture.submitted from inbound/import paths (source: import). Add a property contract that makes this measurable (e.g., optional/required source with an explicit enum) or adjust the R3 anchor to use an event that actually carries that distinction.

Suggested change
Required: `has_attachment: boolean`
Required: `has_attachment: boolean`, `source: string` — submission origin: `manual`, `import`

Copilot uses AI. Check for mistakes.
Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
### `page.loaded`
A route-level page loaded successfully.

Required: `page: string` — enumerated: `home`, `today`, `inbox`, `review`, `board`, `metrics`, `agents`, `agent_run_detail`, `knowledge`, `settings`, `help`
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The page.loaded page enum includes values that don’t currently exist as route-level pages in the web app (e.g. agents, agent_run_detail, knowledge, help). This can lead to inconsistent instrumentation and dashboards. Consider either aligning the enum to current router surfaces (or route.name values), or explicitly marking these as reserved/future values with a pointer to the owning issue/PR.

Suggested change
Required: `page: string`enumerated: `home`, `today`, `inbox`, `review`, `board`, `metrics`, `agents`, `agent_run_detail`, `knowledge`, `settings`, `help`
Required: `page: string`current route-level values: `home`, `today`, `inbox`, `review`, `board`, `metrics`, `settings`
Reserved/future values (do not emit until corresponding router surfaces exist and instrumentation is added; tracked via Related: #341, #77): `agents`, `agent_run_detail`, `knowledge`, `help`

Copilot uses AI. Check for mistakes.
Comment thread docs/product/TELEMETRY_TAXONOMY.md Outdated
Comment on lines +235 to +245
### `session.started`
User started a new authenticated session.

Required: `auth_method: string` — `password`, `oauth_google`, `oauth_github`

### `session.ended`
User explicitly signed out.

Required: *(envelope only)*

### `session.expired`
Copy link

Copilot AI Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The session.* event namespace is easy to confuse with the universal envelope’s session_id (app session) since both use “session” terminology but refer to different concepts here (auth session lifecycle vs app session identifier). Consider renaming the auth events to something less ambiguous (e.g. auth_session.started / auth_session.ended or login.succeeded / logout.completed).

Suggested change
### `session.started`
User started a new authenticated session.
Required: `auth_method: string``password`, `oauth_google`, `oauth_github`
### `session.ended`
User explicitly signed out.
Required: *(envelope only)*
### `session.expired`
### `auth_session.started`
User started a new authenticated session.
Required: `auth_method: string``password`, `oauth_google`, `oauth_github`
### `auth_session.ended`
User explicitly signed out.
Required: *(envelope only)*
### `auth_session.expired`

Copilot uses AI. Check for mistakes.
- Fix naming convention rules: clarify underscores allowed in verb
  segments, standardize on past-tense/past-participle (not "present
  tense for states"), update examples to match
- Add `source` field to `capture.submitted` to satisfy R3 anchor which
  requires measuring import-path submissions
- Bucket `pending_count`, `approved_count`, `rejected_count`, and
  `proposals_created` to match privacy stance applied elsewhere
- Standardize duration units: rename `time_to_decision_seconds` to
  `time_to_decision_ms` across proposal.approved and proposal.rejected
- Fix `auth.login_failed` HTTP status type: use `status_code: number`
  to match `error.api_request_failed` (was `error_code: string`)
- Rename `session.*` auth events to `auth_session.*` to avoid semantic
  clash with the universal envelope's `session_id`
- Mark `agents`, `agent_run_detail`, `knowledge`, `help` as
  reserved/future in page.loaded enum (routes not yet shipped)
- Add `mcp_tool.invoked` and `mcp_tool.failed` events for shipped MCP
  server (PR #739)
- Document that `settings.telemetry.enabled` and the telemetry service
  are not yet implemented; taxonomy must precede instrumentation
@Chris0Jeky Chris0Jeky merged commit 702c227 into main Apr 4, 2026
12 of 14 checks passed
@github-project-automation github-project-automation bot moved this from Pending to Done in Taskdeck Execution Apr 4, 2026
@Chris0Jeky Chris0Jeky deleted the docs/341-telemetry-taxonomy branch April 4, 2026 01:55
Chris0Jeky added a commit that referenced this pull request Apr 4, 2026
Updates STATUS.md, TESTING_GUIDE.md, MANUAL_TEST_CHECKLIST.md, and
IMPLEMENTATION_MASTERPLAN.md to reflect the 9 PRs merged in the
2026-04-04 post-adversarial-review hardening wave.

- STATUS.md: adds new wave entry for PRs #741#756 covering product
  telemetry taxonomy, two bug fixes (#683/#744, #680/#754), six
  frontend regression test additions, and two backend webhook test
  additions; updates Last Updated date
- TESTING_GUIDE.md: updates frontend count from 1496 to 1592, backend
  estimate to ~3010+, combined total to ~4600+; marks #710 and #726 as
  delivered in wave table; adds resolved entries to Key Gaps section;
  updates telemetry taxonomy note to delivered; appends three new
  coverage sections for webhook HMAC, SSRF/delivery reliability, and
  frontend regression wave
- MANUAL_TEST_CHECKLIST.md: adds auth-flow toast check (Section A),
  WIP-limit dedup check (Section B), manual card provenance empty
  state check (Section B), board header presence label check (Section
  B), and D2 router auth guard and workspace state section
- IMPLEMENTATION_MASTERPLAN.md: adds item 128 for the post-adversarial
  hardening wave with all 9 issues, fixes, and wave progress update
Chris0Jeky added a commit that referenced this pull request Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

TST-23: Add product telemetry taxonomy and R1/R2/R3 launch-gate follow-through

2 participants