Perverse Incentives

Setting

It is well established that CEO pay has climbed astronomically in the last decades, and that over a similar period inequality has grown throughout the Western world. This period has also been dominated by laissez faire economics, and corporatism to the extent of corporate welfare.

There are some indications that we are swinging away from this setting, with even the IMF saying, “Empirical evidence suggests that it may be possible to increase [personal income tax] progressivity without adversely affecting economic growth” (IMF Fiscal Monitor, October 2017), but it will be some time, if ever, before the mind-set of actors in this economic dance changes.

Right now, you might be wondering whether this is a software blog or some economic philosophy one, but be assured, this relates back to management, and particularly how it impacts high-skill industries such as software development.

Introduction

Our current economic setting has created a system of incentives that is at odds with the goals of good management.

Good management in knowledge industries emphasises an ‘upside-down-pyramid’ of management which supports, rather than directs, the activities of skilled front-line executors. Put another way, it genuinely recognizes that people are the most important asset in a business and the role of management is to create an environment where those people with the skills can excel.

It is also clear that managers can add value in ways that others can’t. They can use their outright authority to connect otherwise separate groups, resolve conflicts, and use their bird’s-eye-view of the business to sponsor change and ensure strategic alignment, a.k.a. ensuring the right work is being done (HBR, 1995).

In our society we equate value with money, and given the greater value managers can add, pay managers more. We also expect more return from more money, so we expect increased responsibility and accountability from said managers. But here we reach the crux of problem: to support skilled staff it is important to empower them with responsibility, so how can the manager be held accountable whilst giving away the responsibility? To readers who (like myself) have been managers this is the “no kidding” moment, so I would ask the question, how have you tried to change that? This is a systemic problem and as far as I can tell our approach has been grudging acceptance of the status-quo.

How strong is that responsibility?

Good managers empower people, and people make mistakes, and it is unfair to hold the manager responsible for those mistakes, otherwise everyone would be too afraid to make mistakes and we’d destroy effectiveness and any hope of innovation. We also read in the media stories of obfuscating CEOs who (quite reasonably) admit they couldn’t have known that X was happening in their organization and so (will make some knee-jerk changed to resolve it, and) can’t really be held responsible.

By highlighting that they’re ‘not really that responsible’ the premise that with increased value comes increased responsibility has been completely undermined. Now this isn’t the only reason managers are paid more: The other commonly held notion is that managers add more value because their decisions have greater (financial) consequences. This I dispute largely because those decisions are never made in a vacuum, and there are a lot of advisors and analysts that effectively determine the decisions in the first place, with the executive being closer to a rubber stamp than a judge. But that would be a digression from the point of this post, which is to focus on the consequences of ‘having responsibility’.

Micromanagement

Responsibility encourages micromanagement. When your head is on the line then your instinct is to get as involved as possible to ensure the outcome you want. There are plenty of good managers out there who manage to overcome this instinct, but the system is very much setup to encourage micromanagement, and that destroys empowerment.

Under micromanagement, instead of having a team who are comfortable to pursue their own direction to achieve the goals, you’ve now got a sort-of team member (the manager) with a much more limited view of the details (after all, the higher up an organization you are the wider but shallower view you’re expected to have) who ironically requires more energy from the team-members to ‘manage’. This also makes the team feel less ownership for their work because accountability becomes blurred between the manager and the team. And instead of being measured by outcomes the team are judged on details; details that the manager is often not as qualified (as they think they are) to judge.

Micromanagers can also become the de-facto communication channel instead of the more effective approach of organizing teams to communicate with each other. This creates a knowledge and communication bottle-neck which is inefficient.

What does an effective manager do? They set a vision and goals, empower people to execute on them, provide cover so they can achieve their goals, resolve conflicts, and then put their feet up or have strategy off-sites or something like that. They should not be required to answer all the questions other people in the organization have – the team is the most capable to do that – but they can filter the questions to ensure the team can focus on the work.

But if your organization insists on you knowing everything because you are ‘responsible’ because you are expensive, then how can you be an effective manager?

Solution

So how do we fix this?

Essentially, be realistic with managers roles. If their roles are seen to be closer to text-book roles of planning, leadership, organization, and control rather than a know-it-all of everything in their fiefdom, then responsibility is going to fall closer to where it is held, with the executing team.

With this reduction in perceived responsibility and expectation there should be a reduction in compensation.

This will also improve empowerment among the teams which will give them a greater sense of ownership and satisfaction, meaning they’re less likely to turn-over.

Aurelia return to URL after login

When a user accesses a URL without being authenticated we want to take them to the authentication page and then automatically redirect them to their requested URL after successful login. This is particularly important for following URLs from emails or other notifications, and for browser bookmarking.

Aurelia has a navigation pipeline which includes an authorization step and is executed for any navigation action. As part of an authorize step we can check whether the route is configured to require authentication and redirect the user to a login page (” in my case) if they are not.

class AuthorizeStep {
    protected run(navigationInstruction, next) {

        // determine if the route requires authorization
        // i.e. { route: '...', module: '...', setting: { auth: ... }}
        let authConfig = navigationInstruction.getAllInstructions().find(i => i.config.settings.auth);
        if (!authConfig)
            return next();

        let isLoggedIn = checkIfLoggedIn();
        if (!isLoggedIn)
            return next.cancel(new Redirect("")); // redirect to login page
        return next();
    }
}

To redirect after login we need to save the navigation instruction from the failed login and use it following the next successful login. To save it I introduced a NotAuthorizedRedirect class.

import { autoinject } from "aurelia-framework";
import { Router, Redirect, NavigationInstruction } from "aurelia-router";

// singleton by virtue of aurelia's default DI
@autoinject
export class NotAuthorizedRedirect {
    private navigationInstruction: NavigationInstruction;

    constructor(private router: Router) { }

    public notAuthorized(from: NavigationInstruction) {
        this.navigationInstruction = from;
        return new Redirect("");
    }

    public get redirecting() {
        return !!this.navigationInstruction;
    }

    public tryReturnTo(): string {
        if (!this.navigationInstruction)
            return "";

        let uri = this.navigationInstruction.router.generate(
            this.navigationInstruction.config.name,
            Object.assign(this.navigationInstruction.params, this.navigationInstruction.queryParams),
            { replace: true });

        this.navigationInstruction = null; // single use
        return uri;
    }
}

We use this class by first calling the notAuthorized method which saves the navigation instruction and returns a redirect to use. Once the user is known to be authorized we call tryReturnTo to generate a new url.

One issue I had was that some parameters come in via the query string. Thankfully the router generate method has a feature that any parameters given which are not in the route definition (i.e. the id in a route-name/:id) are applied as query string parameters, so tryReturnTo is able to copy the query string parameters (.queryParams) onto the other parameters to re-generate the query string.

We can now use these methods from the AuthorizeStep as follows:

class AuthorizeStep {
    constructor(private redirect: NotAuthorizedRedirect) { }

    protected run(navigationInstruction, next) {

        let authConfig = navigationInstruction.getAllInstructions().find(i => i.config.settings.auth);
        if (!authConfig)
            return next();

        let isLoggedIn = checkIfLoggedIn();
        if (!isLoggedIn)
            return next.cancel(this.redirect.notAuthorized(navigationInstruction));

        let redirectUri = this.redirect.tryReturnTo(); 
        if (redirectUri)
            return next.cancel(new Redirect(redirectUri)); // return to url from before login attempt

        return next();
    }
}

A minor limitation of this approach is that the original URL applied by the user disappears from the address bar when they are redirected to log in. To remedy this NotAuthorizedRedirect also has a little helper property, redirecting, which can be used to indicate to the user that they are being redirected, and could easily be extended to show the user the original url.

The workings of this were originally posted in an aurelia discourse thread.