惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
雷峰网
雷峰网
S
Secure Thoughts
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
G
GRAHAM CLULEY
MongoDB | Blog
MongoDB | Blog
WordPress大学
WordPress大学
M
MIT News - Artificial intelligence
Martin Fowler
Martin Fowler
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
T
Threatpost
S
Securelist
T
Tenable Blog
博客园_首页
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
美团技术团队
Project Zero
Project Zero
The Cloudflare Blog
L
Lohrmann on Cybersecurity
The Register - Security
The Register - Security
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LINUX DO - 热门话题
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
有赞技术团队
有赞技术团队
IT之家
IT之家
A
Arctic Wolf
Scott Helme
Scott Helme
Latest news
Latest news
T
Tailwind CSS Blog
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
Cyberwarzone
Cyberwarzone
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
S
Schneier on Security
Y
Y Combinator Blog

Graphite blog

Introducing Code Tours: a new way to review Introducing Cursor Cloud Agents in Graphite Building the future of software development with Cursor Reimagining the PR Page: Designing for speed and focus Graphite changelog [11-20-2025] Graphite changelog [11-04-2025] Graphite changelog [10-16-2025] The future of engineering is collaborative (and already here) Meet Graphite Agent: the next evolution of AI code review Introducing frozen branches: A safer way to build on your teammates’ work Graphite changelog [09-17-2025] How we sped up code search for Graphite Chat Introducing Graphite Chat AI is writing code—here's why it also needs to review that code How I got Claude to write code I could actually ship How we built the first stack-aware merge queue (and why it matters) How we organize our monorepo to ship fast Graphite brings stacking to Tower Code review tooling: Should you build or buy? Making AI code review available to everyone Introducing: The new Graphite + Linear integration Graphite raises $52M and launches Diamond to reimagine code review for the age of AI Why AI will never replace human code review How stacked PRs unblock distributed development teams Graphite is going to Developer Week 2025 Beating the end of year code freeze How Graphite’s eng team ships code remarkably fast Why we chose Anthropic's Claude to power Graphite Reviewer AI code generation will remain fragmented How we redesigned Graphite's landing page in-house Introducing Graphite Reviewer: your AI code review companion How AI code review reduces review cycles to improve developer productivity What if you could get instant feedback on your code? The new developer toolchain Not Rocket Science - How Bors and Google’s TAP inspired modern merge queues Graphite's State of code review 2024 How Google migrated billions of lines of code from Perforce to Piper Going from 0 to 1: How to write better unit tests when there are none Speed up your merges: Parallel CI is now generally available for teams using Graphite’s merge queue Down for less than four minutes a month: how AWS deploys code BitKeeper, Linux, and licensing disputes: How Linus wrote Git in 14 days Graphite is now free for startups and open source projects Launch week wrap-up (May 2024) Reduce CI costs for Buildkite and GitHub Actions Cheaper CI & faster merging with batching How Google does code review The technical learning curve at a startup is gentler than you might think Graphite will now automatically rebase your partially-merged stacks Multiple engineers can now seamlessly collaborate on the same stack of PRs Do you ever outgrow GitHub? From the 80's to 2024 - how CI tests were invented and optimized Graphite changelog [4/10/2024] 🎺 Graphite changelog [4/25/2024] 🐸 How Stack Overflow replaced Experts Exchange How GitHub monopolized code hosting Graphite changelog [3/27/2024] 🤝 The core principles of building a good AI feature Graphite changelog [3/13/2024] 🚁 Why Facebook doesn’t use Git How to recreate the Phabricator code review workflow Types of code reviews: Improve performance, velocity, and quality What's the best GitHub pull request merge strategy? Phabricator vs GitHub vs Graphite: How do they stack up? Improving team velocity through better pull request practices Moving fast breaks things: the importance of a staging environment Building trust as a software engineer Keeping code simple: moving fast by avoiding over-engineering What's better than GitHub pull request filters? The Graphite pull request inbox 7 Best Phabricator alternatives for PR stacking + code review [2024] Accurate eng estimations: predicting and negotiating the future Tracking and understanding GitHub PR stats: A step-by-step guide 8 pull request best practices for optimal engineering What’s next for Graphite Graphite Q1 Launch week: Stacking with the tools you love Graphite Q1 Launch week: Making stacking seamless Accelerating code review The Mom Test How to use stacked PRs to unblock your entire team Graphite Q1 launch week 2024 The practical and philosophical problems with AI code review Empirically sup code review best practices Call site attribution: how to pinpoint rogue SQL queries throttling your performance Every engineer should understand git reflog Post mortem: we took 124 seconds from you, here's 378 back Your GitHub pull request workflow is slowing everyone down Optimizing CI/CD workflows for trunk-based development Why we use AWS instead of Vercel to host our Next.js app How large pull requests slow down development 3 key lessons in application server optimization Trunk-based development: why you should stop using feature branches Git was built in 5 days Why large companies and fast-moving startups are banning merge commits How long should your CI take? Experimenting with AI code review CRA to AppRouter in 5 Steps: A case study with Graphite Graphite Changelog [10/18/2023] The comprehensive guide to writing the best PR title of all time How 10,000 Developers All Contribute to the same Repo
Onboarding roulette: deleting our employee accounts daily
Greg Foster · 2024-03-14 · via Graphite blog

I’m a strong believer in automated tests - and a moderately disciplined author of them. Software engineering is exceptionally hard to get functionally correct, and even harder to avoid regressing later. As author Michael Feathers says, “Legacy code is any code that doesn’t have a test.”

Some things, such as server endpoints, database schemas, and UI library components, are straightforward to test.

Other things are hard to test, such as endpoints that call third-party APIs, react web pages with complex states, and async jobs that require detailed DB records. At Airbnb, I found testing password reset emails hard because of the outsourced email sending that takes place.

Such functionality still deserves tests - for two reasons. One, it still matters that they don’t regress - and their complexity makes them all the more likely to. Secondly, testing complex features often forces engineers to architect the feature in such a way that it can be tested. The early establishment of tests can motivate narrower interfaces and less coupling, leading to a better long-term codebase.

To test or not to test?

The world’s not perfect - sometimes you have time to write a feature, but not time to establish automated tests on that feature. Why does this happen? Like a reverse P=NP problem, many features are much easier to create than they are to test. Consider a react to-do list app with swipe-to-delete. It can take 30 minutes to create, but might take hours or days to establish automated UI tests that verify “swipe-to-delete”. These imbalances, along with business-driven urgency, lead teams to code features and skip adding expensive tests.

Is that bad? Not necessarily if you’re pragmatic - there are cases where it’s worthwhile taking on debt by creating functionality without tests. The benefit of the untested feature may be high, the cost of testing high, and your resources low. Maybe you’re on a short-staffed team or an evening side project. If you force yourself to add automated unit tests to your to-do list app, you might never launch it to 10 early adopters. (However, if you still don’t test swipe-to-delete after a million users, you might be asking for an incident.)

Delaying automated tests is a slippery slope, but product creation requires the art of strategically taking on debt. The “loan” allows teams to validate quickly, and discovered value can later be spent paying down the tech debt (with interest). This is true for startups raising venture, and it’s true for teams building MVPs. Spend too much time building expensive tests up front, and you may run out of time to ship, learn and pivot.

https://xkcd.com/2730/

Getting creative

Keep in mind that “no automated tests” doesn’t mean “no testing at all.” By default, not having tests means you’re quietly forcing users to find bugs for you. Production traffic and thorough alerting can serve as a weak replacement for automated testing, but you better have rapid rollbacks or flags in place with your finger on the trigger. Frustrated users won’t stick around for long.

Better than production traffic is a subset of production traffic - you often don’t need all your users to hit a bug to find a regression, just a few. This is where canary rollouts and beta cohorts can become useful. But there’s still the issue of real users hitting real regressions, and it requires good monitoring to know when users are having a bad time.

Better than beta cohorts is dogfooding. Send real users through the feature that you don’t want to test automatically, but have those users be you. You can’t rage quit your own product, and your eyeballs make for a great dynamic alerting service (just remember to close them for eight hours every night).

The onboarding struggle

There you have it—automated tests, canary releases, beta cohorts, and dogfooding—a spectrum of ways to test features. Graphite’s engineering team uses all these techniques, yet there remain blind spots in our functionality.

One of the hardest blind spots for us to test is product onboarding. It’s a doozie involving an OAuth loop with GitHub, async loading of repository metadata, queries against our own databases, and custom UI elements not reused elsewhere in the app. Despite these challenges onboarding is critical, and we need to test it somehow.

Classic synthetic tests are rendered flakier than normal due to GitHub login bot detection. Canary traffic testing doesn’t help much here, because production users who fail to onboard rarely report it - and can sometimes appear in logs as indecisive rather than blocked. Beta cohorts rarely catch anything because they only onboard once - the same is true for traditional dogfooding.

Spinning the wheel

Our solution at Graphite has been to run a roulette script, randomly deleting one of our engineers' Graphite accounts every day at 9 a.m. We don’t just reset onboarding—we delete their account, tokens, configured filters, uploaded gifs, and more.

Isn’t that frustrating? Sure. Folks on our team come to work to code new features, not to find themselves logged out and forced to recreate their accounts from scratch. We were cautious when first trying the technique, but the benefits became clear immediately. Note: this is only their Graphite product account - they still have access to GitHub and all other company accounts.

Like most products, Graphite aims for fast, bug-free, and painless onboarding. The best way for us to ensure this is to suffer through onboarding once every day ourselves. Across our full Eng-product-design team, any individual only gets deleted once a month on average. But one teammate a day hitting a sharp edge has proven enough to find and motivate fixing issues.

Deleting employee accounts has created dogfooding on one of our most critical and hard to test surfaces. We’ve caught tens of bugs, and created user empathy in a traditional blindspot. I’d strongly recommend other product teams consider automatically deleting employee accounts for the same benefits.

Current limitations

Is it perfect? No. Deleted employees recreate accounts in the existing Graphite org. That means they still skip some aspects of onboarding that real users hit when they’re the first to set Graphite up in a new organization, such as long initial sync times. In the future, I’d like to explore deleting the entire Graphite company account once a month to increase the dogfooding - though I’m wary of the bigger obstruction to the team’s morning code changes.

Can every product afford to delete employee accounts as much as we do? Possibly not - some accounts accumulate not just configuration, but troves of meaningful user-created content. Instagram and Google Docs for example, might not be able to get away with such a heavy-handed approach. But many services, especially ones where user created data survives individual account deletion, serve to benefit. Products like Datadog, Vercel, Hex, and Superhuman however, could get away with deleting employee accounts once a month. Sure, those people will need to recreate personal dashboards and filters - but that’s the point.

Feeding the future

Will we keep deleting employee accounts forever at Graphite? I suspect so. Dogfooding onboarding is not better than automated testing however - we are continuously making expensive investments to establish real unit and e2e tests here. But dogfooding is sufficiently different than automated testing, and together they compound. Dogfooding catches unknown unknowns in a way that automated tests fail to. It builds user empathy among the creators - as well as deep product opinions that folks can incorporate into future updates. If it’s not easy to recreate your account, then is it easy enough for a new user to get started in the first place?