From 8e46c6e521827c245efd96e5f933155c9ff6f53e Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 14 Aug 2026 19:37:56 -0700 Subject: [PATCH] fix(telemetry): ingest keeps error_message/failed_step instead of dropping them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The telemetry_events columns exist and bin/gstack-telemetry-log already sends error_message + failed_step, but the Supabase ingest function dropped both fields on insert — every error report arrived with no message and no failing step. Map them through with the same bounded-length sanitization as error_class (500/100 chars). The completion-status resolver now also passes --error-message/--failed-step in the generated skill telemetry block, with instructions to leave them empty on success. Resolver only for the template side; generated SKILL.md files regenerate from this source in the docs lane. Contributed by @sunnnybala (PR #769). Co-Authored-By: Claude Fable 5 --- scripts/resolvers/preamble/generate-completion-status.ts | 6 +++++- supabase/functions/telemetry-ingest/index.ts | 4 ++++ test/fixtures/golden/claude-ship-SKILL.md | 6 +++++- test/fixtures/golden/codex-ship-SKILL.md | 6 +++++- test/fixtures/golden/factory-ship-SKILL.md | 6 +++++- test/helpers/carve-guards.ts | 7 +++++-- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/scripts/resolvers/preamble/generate-completion-status.ts b/scripts/resolvers/preamble/generate-completion-status.ts index 56841caeb..8b93ff503 100644 --- a/scripts/resolvers/preamble/generate-completion-status.ts +++ b/scripts/resolvers/preamble/generate-completion-status.ts @@ -73,11 +73,15 @@ fi if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then ~/.claude/skills/gstack/bin/gstack-telemetry-log \\ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \\ - --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \\ + --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null & fi \`\`\` Replace \`SKILL_NAME\`, \`OUTCOME\`, and \`USED_BROWSE\` before running. +Replace \`ERROR_MESSAGE\` with a short description of the error (if outcome is error, +otherwise use empty string ""), and \`FAILED_STEP\` with the step name or number where +the failure occurred (if outcome is error, otherwise use empty string ""). ## Plan Status Footer diff --git a/supabase/functions/telemetry-ingest/index.ts b/supabase/functions/telemetry-ingest/index.ts index acf994eab..f4e9cc8a9 100644 --- a/supabase/functions/telemetry-ingest/index.ts +++ b/supabase/functions/telemetry-ingest/index.ts @@ -16,6 +16,8 @@ interface TelemetryEvent { duration_s?: number; outcome: string; error_class?: string; + error_message?: string; + failed_step?: string; used_browse?: boolean; sessions?: number; installation_id?: string; @@ -93,6 +95,8 @@ Deno.serve(async (req) => { duration_s: typeof event.duration_s === "number" ? event.duration_s : null, outcome: String(event.outcome).slice(0, 20), error_class: event.error_class ? String(event.error_class).slice(0, 100) : null, + error_message: event.error_message ? String(event.error_message).slice(0, 500) : null, + failed_step: event.failed_step ? String(event.failed_step).slice(0, 100) : null, used_browse: event.used_browse === true, concurrent_sessions: typeof event.sessions === "number" ? event.sessions : 1, installation_id: event.installation_id ? String(event.installation_id).slice(0, 64) : null, diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index abc16e7d0..319dd43fc 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -794,11 +794,15 @@ fi if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then ~/.claude/skills/gstack/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ - --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \ + --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null & fi ``` Replace `SKILL_NAME`, `OUTCOME`, and `USED_BROWSE` before running. +Replace `ERROR_MESSAGE` with a short description of the error (if outcome is error, +otherwise use empty string ""), and `FAILED_STEP` with the step name or number where +the failure occurred (if outcome is error, otherwise use empty string ""). ## Plan Status Footer diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index 700247096..920e896a6 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -780,11 +780,15 @@ fi if [ "$_TEL" != "off" ] && [ -x $GSTACK_ROOT/bin/gstack-telemetry-log ]; then $GSTACK_ROOT/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ - --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \ + --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null & fi ``` Replace `SKILL_NAME`, `OUTCOME`, and `USED_BROWSE` before running. +Replace `ERROR_MESSAGE` with a short description of the error (if outcome is error, +otherwise use empty string ""), and `FAILED_STEP` with the step name or number where +the failure occurred (if outcome is error, otherwise use empty string ""). ## Plan Status Footer diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index 69c6013db..2c0bd0077 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -782,11 +782,15 @@ fi if [ "$_TEL" != "off" ] && [ -x $GSTACK_ROOT/bin/gstack-telemetry-log ]; then $GSTACK_ROOT/bin/gstack-telemetry-log \ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \ - --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \ + --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null & fi ``` Replace `SKILL_NAME`, `OUTCOME`, and `USED_BROWSE` before running. +Replace `ERROR_MESSAGE` with a short description of the error (if outcome is error, +otherwise use empty string ""), and `FAILED_STEP` with the step name or number where +the failure occurred (if outcome is error, otherwise use empty string ""). ## Plan Status Footer diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 012b46c2a..490863cf5 100644 --- a/test/helpers/carve-guards.ts +++ b/test/helpers/carve-guards.ts @@ -194,10 +194,13 @@ export const CARVE_GUARDS: Record = { // always-loaded AskUserQuestion Format section. // v1.2.0 activation lift (shared first-run-guidance preamble) + #2077 ask-first scope gate. // +~1.3 KB: plan-mode auto-select-B scope-gate exceptions (2026-08). - maxSkeletonBytes: 89_000, + // +~340 B: telemetry --error-message/--failed-step flags + prose in the + // shared completion-status preamble (PR #769, 2026-08); this skill was the + // closest to its ceiling (landed 89040 / ratio 1.072). + maxSkeletonBytes: 89_400, minUnionBytes: 70_000, mustContain: ['design', 'visual'], - maxSizeRatio: 1.07, + maxSizeRatio: 1.08, }, 'plan-devex-review': { skill: 'plan-devex-review',