Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Mark Rushakoff

git rebase vs. git merge: an agile perspective

Mark Rushakoff
Friday, May 17, 2013

At Pivotal Labs, we’ve been using Quandora for about 6 months as an easier way to archive and discover discussions about the hows and whys of consulting and software engineering here. Earlier this week, I asked my colleagues:

There are some git workflows that would have you regularly work in feature branches and then merge back into master only when the feature is ready for acceptance. However, on every project I’ve worked on at Pivotal, we have preferred to rebase and commit to master regularly.

Why prefer rebasing over merging?

I received some excellent answers.

Rasheed explains:

The more code diverges, the more difficult it is to integrate. If you want continuous integration, it’s a lot easier to do so on one branch, not many. It also drives out stories that are small, have the smallest actionable work, and are easy to accept. This leads to tight feedback loops.

Chad had some information to add to Rasheed’s answer:

Tight feedback loops are one of the things that Pivotal values.

We place priority on CI and small stories. This makes it easier to work on master – it’s not a big deal if it is accidentally broken, it’ll be easily fixed or reverted.

In my experience, we still do use topic branches when appropriate. E.g., in the middle of a story at the end of a day, or for a bigger feature that you don’t want to do in one commit, but would break mainline (master) with the intermediate commit. On my project, in this case, we usually merge –squash –no-commit onto master, to squash multiple commits on the topic branch into one commit on master.

Even in git, branching is still painful. The longer a topic branch lives, the harder it is to merge. Yes, you can rebase often, but that means you have to rewrite history to push the rebased changes to the server. This can cause confusion if the branch lives long and is worked on by multiple pairs or on multiple machines. So, it’s usually less net effort to just work on master, because we have good tests and can trust CI to quickly tell us if there’s any glaring logical merge conflicts that were missed. On teams without CI that rely solely on manual QA, this is much more of a risk and more expensive.

And Jacob, the director of our new Boston office, had this to say:

I’ve seen both patterns at Pivotal. Teams that rebase tend to be small and haven’t had a production release. Large teams have a quickly changing repo and feature branches make the history more readable. And teams that have released use feature branches to relegate incomplete code to a future release. They can also (in theory if not practice) easily roll-back an entire feature branch if something goes wrong in production.

Of course, as Rasheed mentions, trying to wrangle large unreleased changes causes all kinds of problems. Better to get faster feedback with smaller releasable features. If your team still feels it needs to have incomplete features in master, or needs to disable misbehaving pieces of the app, read up about feature switches and look into a tool like rollout or flipper.

So, it seems that in general, we tend to prefer rebasing because it helps facilitate some core concepts of agile software development:

  • Continuous deployment
  • Tight feedback loops
  • Small deliverables

Thanks to Rasheed, Chad, and Jacob for helping provide some great content!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Cameron Cundiff

Lunchtime Drawtime!

Cameron Cundiff
Friday, May 17, 2013

Lunchtime Drawtime happens Fridays at lunch in the NYC office, where a handful of folks get together and perform some acts of creation. Sometime we have prompts; today’s was bodies of water.

Here’s what we came up with. Enjoy!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Cameron Cundiff

How To: Use Skip Navigation Links for Better Keyboard Accessibility

Cameron Cundiff
Friday, May 17, 2013

For improved keyboard accessibility, use skip navigation links along with a coherent heading outline, ARIA landmarks, and a javascript polyfill for Webkit based browsers.

Why Use Skip Navigation Links?

It can be frustrating and fatiguing for folks with limited mobility to have to have to repeatedly tab through navigation links to get to the main content of a page. People who use screen readers face similar frustration when the page outline is not well defined. In order to address this issue, version 2.0 of the Web Content Accessibility Guidelines (WCAG 2.0) has specified a guideline for bypassing repetitive blocks of content. One technique recommended by the W3C is to include a skip navigation link at the beginning of the page, that changes focus to the first element after the repeated content.

How do I use Skip Navigation Links?

Add a link at the top of your body content whose href value points to the id of the element that wraps your primary content. Like so:

Disclaimer: The mechanism by which skip navigation links work had been broken  in Webkit based browsers for some time and has only recently been fixed. Until these browsers release the fixes, you may need to use a javascript polyfill to make skip nav links work.

What about ARIA?

Skip nav links are useful for users who use keyboard navigation only, but screen readers now support more sophisticated ways of navigating regions. Specifically, they support heading navigation and ARIA landmarks. You should take advantage of these features by using a clear heading outline and defining page regions.

Note: The last post I authored, Use ARIA Landmarks Instead of Skip Nav Links, presented a strategy that was predicated in part on the fact that skip navigation links have been broken in Webkit for the past three years. This bug has recently been fixed, so I was inspired to revisit the topic.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Robbie Clutton

Stop leaky APIs

Robbie Clutton
Wednesday, May 15, 2013

There are many blogs about how to expose an API for a Rails application and many times I look at this and am concerned about how these examples often leak the application design and the schema out through the API. When this leak occurs a change to the application internals can ripple out and break clients of an API, or force applications to namespace URI paths which I feel is unnecessary and ugly.

When the only consumer of application data models are the views within the same application then the object design can be fluid and malleable. Once an application exposes an API to more than one client, and especially if that client is on a different release cycle to the server, such as iPhone application, data models become rigid. Rails tends discouraged N-tier architecture to the benefit of development speed but APIs are contracts between a server and it’s client and can be difficult to change once they start being used.

Passing an object into the Rails JSON serialisation methods will work for a time, but relying on this will only get you so far. At some point a refactor will take place that will cause a breaking change. It could be something simple such as renaming a column, moving responsibilities from one class to another or adding extra meta-data to a response. Either way, adding this information into your model class starts to place more responsibilities into one place.

There are a few ways out of this potential issue. Let’s take a look at the classic blog application and its Post object. The Rails rendering engine will call as_json on an object if the request has sent the content-type of application\json to the server. Here we override the implementation from ActiveRecord to provide a stable, known version:

def as_json(options={})
    {
        author_id: author.id
        title: title
    }
end

A second option is to model the object explicitly and serialise the internal model into a public representation. We can duck-type the object to respond how ActiveRecord objects behave during a serialisation call. Although this can be seen as a step towards a N-tier architecture, it’s also a step towards service dependent abstraction:

class Api::Post
  attr_reader :post

  def initialize(post)
    @post = post
  end

  def as_json(options={})
    {
      author_id: post.author.id
      title: post.title
    }
  end
end

The benefit of doing this is a separation of concerns between your data model and the data presentation. An application model doesn’t need to know how it’ll be represented by an API, command line interface or any other outside communication mechanism. If an application were tending more towards HATEOAS for instance this separation could help resolve hyperlinks relevant to the interface. You may lose some of the Rails respond_with goodness with this:

respond_to :html, :json

def show
  post = Post.find(params[:id])
  respond_to |format| do
    format.html { @post = post }
    format.json { render json: Api::Post.new(post) }
  end
end

That can be regained with the help of a presenter:

respond_to :html, :json

def show
  post = Post.find(params[:id])
  @presenter = PostPresenter.new(post)
  respond_with @presenter
end

Where PostPresenter may look something like:

class PostPresenter < SimpleDelegator
  def as_json(options={})
    Api::Post.new(self).as_json(options)
  end
end

What’s the difference between this and putting the as_json method into Post directly? More control, separation of concerns with application modeling vs presentation and the big win is when breaking changes occur within the API. Now we can put version relevant information into new objects, or into the serialised class itself.

class Api::Post
  attr_reader :post, :version

  def initialize(post, version)
    @post = post
    @version = version
  end

  def as_json(options={})
    send("v#{:version}")
  end

  private
  def v20130505
    # version specific JSON
  end

  def v20121206
    # version specific JSON
  end
end

Through this we have versioning information in one place and through a request parameter of something like v=20130506 the application can handle multiple versions in one object. For me, this ultimately removes URIs like /v1/posts, but why is that important? The URI is an identifier which points to a resource and having v1 or v2 in the URI muddies the fact that the two identifiers are pointing to the same resource. Using a request parameter, much like pagination is handled, means we can ask for a representation of that resource rather than having to specify different resources. Then we can do away with needing controllers such as Api::V1::PostsController and just deal with Api::PostsController or even just PostsController and deal with the versioning within the object instead of the URI path.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Robbie Clutton

ElementalJS and SimpleBDD open source updates

Robbie Clutton
Tuesday, May 14, 2013

Thanks to the benefits of Open Source software and working with great people, I’m pleased to announce some updates to both ElementalJS and to SimpleBDD.

ElementalJS

Thanks to Ian Zabel who made a performance improvement to ElementalJS after fighting a large DOM in Internet Explorer. Elemental will now load the behaviours much quicker if the document is passed as no filtering will take place. If another node is passed, filtering will be applied but the thought is that DOM will be much smaller so hopefully won’t hit this issue.

SimpleBDD

Thanks to Adam Berlin who made two improvements to SimpleBDD. First was the addition to also to the syntax and second was NoMethodError is replaced by pending if using RSpec.

More improvements were made by Daniel Finnie which allow use of some non alphanumeric characters that get turned into method names.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Gansen and Kunesh on Agile Development in the Obama 2012 Campaign

Paul Davis
Tuesday, May 14, 2013
Juan Camilo Bernal / Shutterstock.com

Juan Camilo Bernal / Shutterstock.com

 

The Obama 2012 campaign has been hailed as the most tech-savvy and data-driven to date, a sophisticated operation led by CTO Harper Reed. Reed had no problem finding developers eager to join the campaign — the challenge was finding people up for the formidable task before them. A Presidential campaign poses unique challenges: an environment where volatility is the only constant, developers must iterate often, yet there is little margin for error. To meet this challenge, Reed and his team placed an emphasis on people who could resolve problems and learn quickly, rather than focusing on a particular skill set.

Within this heady environment, Chris Gansen, the campaign’s Senior Software Engineer, and Jason Kunesh, Director of User Experience and Product, embraced the methodologies of agile software development.

While much attention was paid to the Obama 2012 tech team’s online voter outreach efforts, its on-the-ground campaign was equally impressive, turning information collected by volunteers knocking on their neighbors’ doors into grist for fine-grained data collection and analytics. This was undertaken by roughly “1000 neighborhood teams with tens of thousand of volunteer leaders,” according to Gansen.

A voter outreach campaign of such size and complexity demanded a bi-directional communication and data collection tool. Gansen and Kunesh were deeply involved in building the resulting product, Dashboard, which gave volunteer leaders a way to connect, organize, and report progress. Dashboard became a gold mine of voter-reported data, providing the campaign with insights and strategies to effectively communicate to voters and coordinate volunteers, at both a macro and micro scale. Gansen describes the lauded voter outreach and analytics platform as “the culmination of many years of trying to unify online and offline campaign organizing.”

Dashboard grew to one of the largest projects within the campaign, boasting 40–50 engineers divided between five separate tracks, or “Work Streams,” as they were known within the campaign.

From Agile Skepticism to Proven Success

Comfortable with the proven, tightly managed, topdown management model of campaigns past, veteran politicos were initially skeptical of agile development practices. “We fought really hard to get people in the campaign to embrace iterative development,” says Gansen. “In government, you tend to see technology coming from vendors, and measured by the quarter. When we would say, ‘we’re going to launch this and there are going to be bugs,’ a lot of people in the campaign hesitated. They hadn’t done this before, and we had to be flawlessly representing the brand of the President.”

“Software isn’t like that,” he says. “It can be messy, and so we had to show them through iterating, and being accountable to what we were doing, that things improved over time.” Despite their initial pushback, the clarity and transparency of this approach won converts among the skeptics. “We had great technologists who’d never worked on campaigns, and great campaigners who’d never participated in shaping software,” says Kunesh. “Before we understood each others’ worlds, agile was a way for us to agree on what we were building and how.”

It also allowed them to prioritize high-value goals and milestones, while being able to quickly change course when necessary. “Since the goals of the campaign change depending upon what phase of campaigning you are in, responding dynamically was a requirement,” says Kunesh. “The things that were important in February are meaningless at the end of summer, but they are the features you needed in the spring. Agile helped us stay focused on shipping the most important features.”

The campaign measured every conceivable metric — voter data, usage and performance at every level of the technology stacks, and project velocity, to name a handful of metrics. Gansen, Kunesh, and their teams turned to Pivotal Tracker to collaborate, track progress, and perhaps most importantly, communicate their workload and progress to other stakeholders in the campaign. Tracker’s emphasis on agile development methodology, prioritization and collaboration was well-suited to the environment. For the Dashboard initiative, each of the five work streams were divided into separate Tracker projects. Every feature on the Dashboard project had a corresponding Tracker story, and they used release markers heavily to represent milestones.

“With very constrained time, we had to decide quickly whether to improve a feature or axe it,” says Gansen. “In campaigns, you never make a decision that isn’t backed up with data, so being able to pair data-driven development with agile delivery helped build products that people actually used.”

Gansen found that Tracker and agile development practices helped the team make the case for decisions, clearly demonstrate what milestones had been reached, and accurately predict when upcoming milestones would be hit. “From a product perspective,” he says, “the two things that were most successful was the transparency and the accountability of quick, weekly releases. We were able to say, ‘this is what we’re going to do,’ and then a week later come back and say, ‘we did what we said we would do, and if we didn’t, here’s what came up.’”

It also eased the process of onboarding new developers, Kunesh says. “It gave us a common platform and methodology to follow,” he says. “We were building our team as we were building our products. Pivotal Tracker offered a built-in workflow that let us move engineers from team to team while still having a common process.”

Battle-tested and Unbowed

The members of that team have gone their separate ways, like the tech industry equivalent of a pack of sage cowboys riding off into the sunset. Products such as Dashboard now lay in hibernation until the next election season. Fortunately, the likes of Gansen and Kunesh are sharing the hard-learned lessons they learned during those intense 18 months.

Gansen, who now consults for the civic technology organization Smart Chicago Collaborative, has developed a healthy obsession with collecting and analyzing all the data one might have available. “Measurement is key because you can’t make decisions on information you don’t have,” he says. “Measure everything, and do it early on, because even with a small amount of data, you can make decisions. Over time, the data only grows more and more valuable.”

Both Gansen and Kunesh evangelize for the value of developing and deploying transparently within an organization, and using that openness to engage nontechnical stakeholders. It’s a matter of “Communication and building trust,” Kunesh says. “Operate openly and transparently with what you’re doing with the people involved in the process,” Gansen adds. “When a technical team is interacting with a nontechnical team,” he says, such clarity and transparency “is essential.”

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Trace Wax

On asking for help

Trace Wax
Monday, May 13, 2013

Years ago in college, I took part in “The Game”: a 24-long scavenger hunt, driving all over the Bay Area, decoding clues that would lead us to the next location, each clue nerdier than the next.  If we ever got stuck, we could call Game Control and they’d help us to the next clue.  One clue was a matrix.  We figured out if we took the eigenvalues down the diagonal, it was a 10-digit phone number.  It didn’t come out right, and we spent 5 hours trying to recode and decode it.  No dice, so we finally called Game Control.  They apologized for their mistake; there was an error in the matrix, and they gave us the phone number.  It was for a bowling alley, which had just closed.  All the teams had been there a couple hours before, bowling for their next clue after having called Game Control much sooner.  Our stubbornness caused us to miss out on bowling and we had to call Game Control again to get the location of the next clue.

Fast forward to last month.  I drink a lot of water and found myself often the one who took the last drop of water from the water cooler.  So I’d fetch and hoist the 5 gallon replacement jug from down the hall, sometimes several times per week.  I could have asked for help, but had thought, why be a bother when I can do it myself?  I didn’t really mind…until I found myself with a hernia from the lifting.  A minor outpatient surgery later, things are pretty well back to normal, but there will be no more carrying of the water jugs.

Fast forward to last week.  We were deep in someone else’s code and far down a rabbit hole of investigating things we didn’t quite yet understand.  There were many avenues we could explore, and we could have kept on down that rabbit hole for a long time.  But then my hernia scar twinged.  So my pair and I got up and asked the original dev, and we were on our way in minutes.

While the thrill of solving everything alone is tempting, we pair and share a team for a reason.  And if we need anything else, we can ask an entire office of Pivots every morning in the ‘helps’ part of our daily standup.  Whether in a scavenger hunt, in transporting water, or in a sea of unfamiliar code, I’m looking forward to asking for help when I need it.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Ward Penney

A SASS with Bootstrap Workflow

Ward Penney
Monday, May 13, 2013

So you’ve decided to start a project with Twitter Bootstrap, but you want to use SASS (SCSS)? Well, this is the post for you. Here are some tips from my current workflow for starting a SASS with Bootstrap project. DISCLAIMER: there many ways to slice this cake. So please, take what you like and leave what you don’t!

A Typical File Structure

In the stylesheets source folder, I generally only have one primary SASS file, that imports all others. If you are using a Rack app, do not use sprockets directives here, just SASS.

Depending on your stack, you will have some place where you have a stylesheets/ folder. Within that folder, I typically set up a basic folder structure that looks like this:

  • application.sass
    • /libraries
      • _variables.sass
      • _mixins.sass
    • /vendor
      • _bootstrap.scss
      • _bootstrap-responsive.scss
      • bootstrap/
        • _accordion.scss
        • _alerts.sass
        • _breadcrumbs.sass
        • etc…
    • /components
      • _tables.sass
      • _forms.sass
      • etc…
    • /sections
      • _homepage.sass
      • _product_detail.sass
      • _style_guide.sass
      • etc…

./libraries/: contains only variables and mixins: SASS that does not render any actual CSS, but is used later. Why? You’ll find out later!

./vendor/: Vendor framework libraries. In this case, only Bootstrap is here.

./components/: SASS patterns intended to be used across the site. Pretty much everything in here will be devoted a section in the live style guide.

./sections/: Layouts and other page-specific stylings. Anything that is not intended to be used in multiple places in a versatile way.

Bootstrap Source

I like the Bootstrap source SASS not hidden in a gem because I can want to control exactly which features are included. You don’t want to be in a situation where it feels like you can’t deprecate or evolve away from Bootstrap because you don’t control it. So, here is what I do:

  1. Go to Thomas MacDonald’s amazingly well-maintained Bootstrap port to SCSS at https://github.com/thomas-mcdonald/bootstrap-sass

  2. Copy the contents of https://github.com/thomas-mcdonald/bootstrap-sass/tree/master/vendor/assets/stylesheets to your vendor folder described above

  3. Open up the bootstrap/bootstrap.scsss and comment out NEARLY EVERYTHING. Even the grid if you want to use a different grid. Uncomment features as you need them, when your user stories demand the functionality.

  4. Include the vendor/bootstrap file in your ./style.sass file, and BOOM you’ve got a full controllable Bootstrap source.

  5. When you need buttons, uncomment buttons. When you need wells, uncomment wells. Rinse and repeat.

  6. Replicate this process for the javascript also, only including what you need when you need it.

(Note, this method also works if you don’t have Rails, or a rack app that can use gems, this still works for you. Yes, you can compile SASS with Bower and Grunt. Check out Sam Richard’s style guide prototyping stack)

Extending the Grid

With Bootstrap, you may typically insert its class selectors and elements into your markup to compose the, but some peepz do not desire this for semantic, SEO and other reasons.

SASS offers an attractive way to remove the clutter with the SASS @extend directive, however it has two performance pitfalls:

  • In Development: Using it in SASS nesting (more than two levels) may significantly slow down your compilation time, especially if that element is being @extend-ed a lot.
  • In Production, overuse can can create so many selectors on one element that it can lag the browser significantly.

In Bootstrap in particular, it becomes tricky because you have to extend the grid class, as well as the wildcard class that applies the padding. For example, a Bootstrap element classed with .span3 will receive stylings from the .span3 selector, as well as a funky selector [class*=’span’]. For example, you can’t just do this:


.advertising-sponsor
  @extend .span3

This misses the [class*='span'] wildcard selector because @extend only scours literal selectors, not searching for anything that MAY apply. Therefore, you have to do this:


.advertising-sponsor
  @extend .span3
  @extend [class*='span']

The downside is the second @extend adds an extension to that target selector every time you use it, and a really long one if it is nested. Those hit the performance issues I described above, hard.

So, my process now is to create my own mixin that allows me to quickly pseudo-extend the grid class by calling the Bootstrap mixin that prints their styling. I place the following into my ./variables/_mixins.sass:

=bs-extend-span($spanNum)
  +grid-core-span($spanNum, $gridColumnWidth, $gridGutterWidth)
  float: left
  min-height: 1px
  margin-left: $gridGutterWidth

This essentially renders what bootstrap does for it’s span classes. This does duplicate CSS in the compiled result, but I have found that the performance impact of downloading more CSS pales in comparison to the pains suffered by @extend in development time, or in a more severe case, crashing or lagging the users’ browser.

Styling Bootstrap with Variables

Take a look at the ./vendor/bootstrap/_variables.sass. Notice how all the variables have !default after them? That means that SASS will NOT overwrite this variable if it is already defined. This allows you to create your own ./libraries/_variables.sass file, and include it in the load order before Bootstrap and effectively control those variables. This will be your primary way to style Bootstrap colors and such.

Using Compass or Bourbon with Bootstrap

Some people prefer Compass’ mixins. Some people like Bootstrap’s. Some like Bourbon’s. IMO, they are all good and I don’t mind using any, but it is a good idea to commit to one. For example, Bootstrap’s =Opacity() mixin takes a value from 0-100, while Compass’ function takes a value from 0-1. There is a variable order conflict with =transition(). I sometimes import pieces of compass, instead of the whole thing. For example, I like the ever-handy Compass =experimental() function. You can choose to import only specific files from Compass:

@import compass/css3/shared

Conclusion and Upcoming Topics

That’s it for now! Let me know if you have any topics you want me to expand on, or ideas for posts you want to see. I am currently doing a style guide using Groundwork-CSS, and hope to do a similar post later! Follow me on twitter for various nonsensical ramblings.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Graham Siener

Storyation Workshop: How to get business stakeholders to create stories

Graham Siener
Monday, May 13, 2013

I read Lean From the Trenches last weekend and it was great.  Not because it provided black and white protocols for running an agile product development team, but rather because it showed how a real team operates under real conditions.

I want to focus this post on a quote from the book:

The definition of “ready for development” can be achieved only if all specialties work together to estimate features, break them into small enough deliverables without losing too much customer value, and to agree on acceptance tests.

Ready for development is an interesting concept — it implies that every business stakeholder that has input knows what the product owner needs to ensure a developer can deliver an acceptable story.  In my experience, this is usually not the case once a product is out in the marketplace and people from non-product teams (marketing, support, executives) have specific product needs.  This could look like promo code tracking to support a marketing campaign, or a data export to support your “data science” team.  Without a good process for getting these stories into the backlog, the result is an unhealthy IPM where the PM and developers have to divine what exactly the intent of a story is.

At one of my last companies, we had this problem in spades.  Even after introducing a Pre-IPM meeting, we still felt like the quality of the stories we presented to developers in IPM didn’t represent the time we had spent discussing them.  To add insult to injury, getting the story requester to accept a delivered story was like pulling teeth.  Once we did sit them down to walk through a story, rejection was often the result!

After reflection (and seeing this come up as a theme in several retros) we created a new weekly meeting called “Storyation Workshop.”  This session felt a lot like office hours, and we made clear the intent to only let high-quality stories into the backlog.  We (PM and Tech Lead) would do our best to interpret the needs for a feature and turn it into actionable stories.  We would also break out the necessary pieces from the nice-to-haves.  Make no mistake, though — the business owners were on the hook to bring justification for a feature and if it didn’t pass muster it lived in the Icebox for another sprint.

We were fortunate (as a company) to have support for keeping a healthy backlog and not jumping stories in the priority queue.  I saw many benefits to this new process:

  • All the other teams — marketing, professional services, customer support, data science — paid closer attention in IPMs and made sure that their needs were well represented
  • Acceptance happened more quickly after a story was delivered, and expectation alignment meant rejections went way down
  • Everyone got better at story writing as they started to grok how we broke down features and the logic behind it
  • More greenfield thinking popped up and made it into the backlog as actionable work

The first three were proof to me that we were missing a critical process in the arc of a story.  The last bullet (greenfield thinking) was a pleasant surprise.  It turned out that people were afraid of bringing a half-baked idea to IPM (rightfully so) but didn’t feel like they had the right forum to finish baking an idea.

Maybe this all sounds like common sense; if that’s the case congrats on having a healthy product development process!  For anyone struggling to deal with symptoms like these I suggest you try introducing a safe space for new ideas to come to light.  A Storyation Workshop could come in many forms, but you’ll know it’s working when you see more buy in from non-product team stakeholders and a faster cycle-team for their stories through the backlog.

As always, I’d love to hear if you’ve incorporated a similar technique into your agile product development process.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Jonathan Berger

7 Best Practices for Facilitating Agile Retrospectives

Jonathan Berger
Monday, May 13, 2013

Facilitating a retro is a very powerful role; it’s almost akin to being a courthouse judge (and stenographer). By asking questions, recording testimony, and shaping the debate, you mold and influence your teammates’ feedback in a very vulnerable and trusting space. If the Product team sets goals (like a Legislature) and Development and Design teams implement them (like an Executive Branch), a retro is a chance to reflect, interpret, and set future direction—not unlike a Judiciary. In practice, that means it’s important to be especially honest and impartial, and to double-check that you’re doing justice to the team’s best interest and the speakers’ intent. Here’re a few patterns I’ve observed that help make the difference between a good retro and a bad one.

1. Explain and Enforce format

At the beginning of a retro, take a minute to explain what’s going on—even for a seasoned team, but especially for a team with new members. “We’re here to reflect and improve on process—this is a safe space, and we’re oriented towards exposing issues and taking action.” If the team isn’t explicitly aligned on why they’re in the room, they can’t get the job done. Speaking up is high value (it ensures the retro is properly oriented) and low-risk (it only takes a minute).

2. Write Everything Down Verbatim

A retro is about listening. Whoever takes notes ought to be respectful of the speakers voice. That means recording their thoughts as faithfully as possible, without interjecting opinion or commentary. If you do need to paraphrase for brevity, be as faithful to the original comment as possible—don’t insert your view, you’ll get your own turn—and confirm that your version does justice to the original. “You said ‘INSERT COMMENT HERE’ and I wrote ‘INSERT PARAPHRASE HERE’. Is that right? “

3. Categorize carefully

If you choose to categorize items, be very conservative about pre-judging what it is you’re talking about. Sure, you’ve spent the last 25 minutes talking about a few categories, but don’t jump to putting names on the buckets—that’s prejudice, and it shapes opinions. Group like items (“Are these two frownies related?”), branch out from there, and labels will emerge. Be careful that the buckets aren’t too broad to be useful; it can be tempting to draw connections among almost everything, but ideally you’ll be slicing things a little thinner, facilitating more focused action items.

4. Action Items Should Have Intent

Unclear Action Items are worse than useless. One trick is to ensure a verb is the first word of every Action Item. By definition, every action includes a verb, but sometimes the verb is glossed-over or shorthanded in the retro. Everyone in the room understands what’s meant, but afterwards that may no longer be the case. Make sure that Action Items remain actionable when viewed later.

5. Action Items Should Be Falsifiable

Be sure to frame Action Items in terms that can be assessed as “done” or not. “Refactor more” isn’t useful a useful task, because there’s no way to meaningfully tell whether it’s done. “Improve the User model’s Code Climate grade from an F to a D” is actionable, and lets the team take small, achievable steps towards improvement. Also: use Code Climate, Errplane, New Relic, Airbrake or other instrumentation services to help put objective measures on code quality, performance, etc.

6. Action Items Need a Single Responsible Party

Not two people. Not “team” or “all”. One person. When an action item involves the whole team, find a volunteer to be the cop and enforce compliance. If one person isn’t responsible, then no one’s responsible. Addendum: review Action Items. Print them up and put them on the team stand-up board. Cross them off as completed. Review the list at the next retro.

7. What Happens In Retro, Stays In Retro

The retro should be a safe place. Active members of the team should the be ones in the room; sometimes it’s helpful to include stakeholders that aren’t present for most of the week (but that’s a judgement call). Action Items may be displayed publicly, but it’s preferable to only share the raw notes with the people present.

These practices aren’t laws chiseled in stone; they’re hacks and ideas borne of observations of patterns and anti-patterns witnessed in many, many retros. Do you agree? Disagree? Have juicy, anonymized stories supporting or contradicting? Let us know (and share your best retro stories) in the comments.

 

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (86)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (53)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • mobile (21)
  • cucumber (20)
  • bloggerdome (19)
  • process (19)
  • pivotal tracker (19)
  • design (18)
  • jasmine (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • gem (13)
  • bdd (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • tdd (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • rubygems (9)
Subscribe to Labs Feed
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. ...
  9. 122
  10. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >