fix(navigation): remove pinnedByDefault sidebar auto-pin#73020
Conversation
Teams should not be able to force their product into a user's sidebar. Removes the pinnedByDefault concept entirely: the auto-pin injection in getCustomProductTreeItems, the FileSystemImport type field, and its use by Engineering analytics, Replay vision, and Tasks. Regenerated schema.json and posthog/schema.py. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
😎 This pull request was merged. |
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
👀 Auto-assigned reviewersThese soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:
Soft owners come from each directory's |
|
Reviews (1): Last reviewed commit: "fix(navigation): remove pinnedByDefault ..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pure subtractive change (no additions) removing a nav auto-pin field consistently across all its call sites and generated schema; author discloses the cross-team visibility impact explicitly rather than hiding it, and the change is trivially reversible. Not in risky territory (no data models, auth, billing, deps, CI, or ingestion touched), so no independent assurance is required despite the author being off the owning teams.
- Author wrote 0% of the modified lines and has 372 merged PRs in these paths (familiarity MODERATE).
- 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
- No sign-off from the three affected teams (devex, replay, self-driving) whose products lose auto-pin visibility — worth a heads-up even though not a code-safety blocker.
- No tests added/updated for the removed auto-pin behavior, though the change is purely subtractive.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 31L, 7F substantive, 33L/8F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (33L, 8F, cross-cutting, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ b954a44 · reviewed head 98cf3b4 |
🤖 CI report✅ Bundle size — 🟢 -619 B (-0.0%)Uncompressed size of every built Total: 64.66 MiB · 🟢 -619 B (-0.0%) No file changed by more than 1000 B. Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report ✅ Eager graph — within budgetHow much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy
🟢 Largest files eagerly shipped from
|
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.3 KiB | ../node_modules/.pnpm/posthog-js@1.406.2/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 236.0 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 224.7 KiB | ../node_modules/.pnpm/posthog-js@1.406.2/node_modules/posthog-js/dist/module.js |
| 167.1 KiB | src/queries/validators.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.8 KiB | src/lib/api.ts |
| 94.0 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.18 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.18 MiB · 17 files | no change | ████░░░░░░ 38.1% of 5.72 MiB |
| Deferred (lazy) | 2.07 MiB · 33 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 713.8 KiB | dist/toolbar/toolbar-app-HY7HJI4V.css |
| 543.6 KiB | dist/toolbar/chunk-chunk-UG3THN3N.js |
| 484.2 KiB | dist/toolbar/chunk-chunk-QS5AHYGW.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-MCXISDMN.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-UDDFB6JG.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-XVKSNBZ7.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-CS7W2KTV.js |
| 12.2 KiB | dist/toolbar/chunk-chunk-PIK3PADE.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🟢 -5.4 KiB (-0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1357.18 MiB · 🟢 -5.4 KiB (-0.0%)
Merge activity
|

Problem
Any product could set
pinnedByDefaulton its nav manifest entry and get force-injected into every user's sidebar whenever its feature flag was on, whether or not the user ever chose it. Teams should not be able to force their product into a user's sidebar, and we don't want them controlling what a person sees there. That's the user's call.It also produced a visible bug. The sidebar render path honored
pinnedByDefaultbut the "edit list" toggle view did not, so an auto-pinned product showed up in the sidebar while reading as un-toggled in the customize view. And un-toggling it never stuck, because the render path re-added it on every render while the flag was on.Changes
Removed the
pinnedByDefaultconcept entirely:getCustomProductTreeItems(projectTreeDataLogic.tsx)pinnedByDefaultfield on theFileSystemImporttype (schema-general.ts)products.tsxand each product manifest)frontend/src/queries/schema.jsonandposthog/schema.pyThe sidebar now renders only the products a user has actually added to their list.
Note
This touches three other teams' products (Replay vision, Engineering analytics, Tasks). They relied on this to stay visible during their beta/launch push and will lose that auto-promotion. Flagging so it's not a surprise.
How did you test this code?
Ran the frontend TypeScript check (clean for this change; the only error is a pre-existing missing-module in an unrelated
early_access_featurestest) and lint/format. I (the agent) did not do manual UI testing.Automatic notifications
Docs update
n/a
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Rafa directed this: he noticed Tasks and Engineering analytics showing in his sidebar despite being un-toggled in the edit view, and asked me (Claude Fable 5, in Claude Code) to find the cause and then remove the mechanism. I traced it to the
pinnedByDefaultauto-pin, confirmed the render vs edit-list selector mismatch, and removed the concept end to end.products.tsxis generated from the product manifests, so the pre-commit hook regenerated it from my manifest edits. I reverted a handful of unrelated files that the lint/format run touched (oxfmt/oxlint drift already on master) to keep the diff focused.