From c061cfea717267084ddc46a0bbe7b6928e05d071 Mon Sep 17 00:00:00 2001 From: NiveditJain Date: Tue, 9 Jun 2026 06:21:41 -0700 Subject: [PATCH] fix(ci): avoid SIGPIPE in bump-platform-submodule first-line extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `printf '%s\n' "$COMMIT_SUBJECT" | head -n 1` races under `set -o pipefail`: on a long commit body, `head` closes the pipe after the first line, `printf` dies with SIGPIPE on the next write, and the pipeline propagates the non-zero exit. The merge of #397 (squash body several KB) triggered it and blocked the platform-submodule bump (run 27208748580). Replace the pipe with pure bash parameter expansion — no subprocess, no pipe, nothing for pipefail to fail on. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/bump-platform-submodule.yml | 8 +++++++- CHANGELOG.md | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bump-platform-submodule.yml b/.github/workflows/bump-platform-submodule.yml index 6cde1cb6..67bf4661 100644 --- a/.github/workflows/bump-platform-submodule.yml +++ b/.github/workflows/bump-platform-submodule.yml @@ -65,7 +65,13 @@ jobs: # needing the submodule contents on disk. git update-index --add --cacheinfo "160000,$NEW_SHA,failproofai/oss" - SUBJECT_LINE=$(printf '%s\n' "${COMMIT_SUBJECT:-Manual trigger}" | head -n 1) + # Extract the first line via pure bash parameter expansion — piping + # printf into `head -n 1` raced under `set -o pipefail`: head closes + # the pipe after the first line, printf dies with SIGPIPE, and the + # pipeline exits non-zero. The squash-merge commit body that broke + # run 27208748580 was several KB, easily triggering it. + SUBJECT_LINE=${COMMIT_SUBJECT:-Manual trigger} + SUBJECT_LINE=${SUBJECT_LINE%%$'\n'*} SHORT_SHA=${NEW_SHA:0:7} git commit -m "Bump failproofai/oss to $SHORT_SHA" \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 27cfa6eb..1bb5d088 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Stamp `product: "failproofai-oss"` on every PostHog event across all four telemetry channels — hooks/audit (`trackHookEvent`), server (`trackEvent`), web UI (`captureClientEvent`), and npm-lifecycle install/uninstall (`trackInstallEvent`) — so OSS events stay distinguishable from any future hosted surface. The value lives in a single `POSTHOG_PRODUCT` constant in `src/posthog-key.ts`, reused by the three TypeScript channels; the standalone `scripts/install-telemetry.mjs` inlines the same literal because it can't import the TS module at install time. Honors `FAILPROOFAI_TELEMETRY_DISABLED=1` like all other telemetry (#380). ### Fixes +- Fix the `bump-platform-submodule.yml` workflow's `Bump failproofai/oss gitlink and push` step, which failed on the merge of #397 with `printf: write error: Broken pipe`. The step's `SUBJECT_LINE=$(printf '%s\n' "${COMMIT_SUBJECT:-Manual trigger}" | head -n 1)` raced under `set -o pipefail`: `head -n 1` closed the pipe after the first line of the squash-merge commit body, `printf` died with SIGPIPE on the next write, and the pipeline propagated the non-zero exit. Replace the pipe with pure bash parameter expansion (`SUBJECT_LINE=${COMMIT_SUBJECT:-Manual trigger}; SUBJECT_LINE=${SUBJECT_LINE%%$'\n'*}`) so no subprocess pipe is involved and `pipefail` has nothing to fail on. - Drop the literal `━━` escape sequences that were rendering as visible text inside the three `.stat-cell` eyebrow labels on the `/policies` activity tab (`app/policies/hooks-client.tsx:297,302,307`). JSX text content doesn't interpret `\uXXXX` escapes — those only work inside JS string literals — so the railroad-track glyph was painting as eight raw characters. The eyebrow rule + green accent color already give the captions enough visual weight; the decorative glyph was net negative. - Tier-C polish + efficiency pass from the deferred-review plan. **`app/audit/_components/audit-dashboard.tsx`** — `detectorsTriggered` + `missing` were two independent O(N) scans over `result.results` per render; merged into a single `useMemo` keyed on `result`. The scroll handler now coalesces events through `requestAnimationFrame` so reading `scrollHeight` (a layout-reflow trigger) fires at most once per frame instead of dozens per second during a fast scroll. **`app/audit/_components/policies-section.tsx`** — wrapped `buildPolicyCards(result)` in `useMemo`; previously it rebuilt a `Map + Set + sort` aggregation on every parent re-render. **`app/audit/_components/identity-section.tsx`** — wrapped `pickArchetypeVariant(archetypeKey, seed)` in `useMemo`; previously re-hashed the seed string and ran four `xmur3` mix passes per axis on every IdentitySection state change (the share buttons toggle `downloadState` which rerenders us 4× per click). **`app/audit/_components/return-section.tsx`** — added a 5s throttle to the focus + visibilitychange handlers' `refreshStatus()` calls so rapid alt-tabbing doesn't thrash `/api/auth/status` (two disk reads each); also extracted a `` helper that takes a `showSetReminder` slot so the authed and anon branches stop duplicating the `[ re-audit now ]` + `[ install policies ]` buttons (they had already drifted on `marginTop` styling). **`bin/failproofai.mjs`** — `policy remove ` no longer threads `--beta` into the manager call as `betaOnly`; the manager only used `betaOnly` for telemetry tagging (`removal_mode: "beta_policies"`), so passing `--beta` to `policy remove` was a mislabel that produced ghost "beta removal" events in PostHog without affecting which policy was actually removed. The flag is dropped from this path so `beta_only: false` is emitted unconditionally — match the actual semantics. No tests changed; 1769 still pass.