The war of privacy is coming in 2014

What will you do when you have the opportunity to trade your privacy as a currency?

Of course, it’s not a sustainable model, but that’s not the point. The point is that as long as we can trade our info for goods and services, we will set new standards for technological boundaries on our lives. And we’ve already seen it coming fast – mobility has been tackled, wearability is next, and embedded/environmentally ubiquitous will come after.

Apple released a phone that knows you by the same way you are identified by if you commit a crime or two. (This is a gross over-generalization, but stick with me.) On the flip-side (read: not the private sector) the NSA can listen in on your conversations. Without a warrant. Endorsed by the president. He doesn’t really want a call made on whether that’s okay.

And what will this bring? With movies like The Fifth Estate coming into mainstream (albeit fairly unsuccessfully) and with technological literacy being pushed with efforts to get everyone to code, there will eventually be a click moment where people understand the seriousness of the NSA’s deal to weaken RSA. Eventually there will be an enlightenment of what “surveillance state” means as it relates to all of these wearable devices and Xbox eyes and webcams and…

We’ve heard about Luddites, and I think this may be their birthplace: a strong, deep-rooted hatred for the corruption and terror of privacy-destroying devices like Apple’s iPhone 6. They reject the need for technology, first as a hipster trend (like leaving Facebook), but evolving into a real movement.

Obviously this is absurdist in many ways. (At least hopefully that’s obvious.) The truth is, the general population will take longer to shift to technological literacy enough to understand the seriousness of the RSA deal. (By the time that click moment happens, RSA will have become obsolete anyway.) But the underlying pattern is emerging: people will start caring more about privacy than ever before. They will understand that their need to be “always-connected” puts that privacy up for crucifixion, and that creates a direct conflict with the rapidly advancing personal device world. And that will be the war of privacy.

How We Adopted an Agency-wide Grunt Workflow

tldr; When adopting tools, do so to eliminate waste. It’s not worth adopting a tool for the sake of the clout of adopting it. For development, automate things you do the same often (or should/could do the same often). Build shareable processes that require little training overhead. Identify pieces of your process that require a common language; these places are usually where tools can be introduced to solidify that common language.

Don’t mess with my flow.

If you are a leader of a development team, you know that it can be hard to adopt any team-wide change in workflow. This is especially true if the new project tools are a significant shift away from the way you already work. The truth is, the overhead of managing the tools (instead of working on the project itself) can bog down your team, make for some confusion, and ultimately cause over-engineering and waste of time.

But the truth is, the evolving tools of web design are rising for a reason. Dependency management tools (or any kind of tool, for that matter) that are rising in fame should be evaluated. But where is the line? How can you know when its time to bite the bullet, buckle down, and learn the details of these tools? I think the answer is ultimately subjective, but I’ll share an anecdote with you about how we decided to move our team to a shared workflow that involves dependency management through Grunt, GitHub-centric code control, etcetera, while generally avoiding overhead.

A Note About Dependency Management

The goal of dependency management is to abstract away the details of manually managing toolsets that a project uses. In the Rails world, this is done in a Gemfile. In Node, it’s in a package.json file. Almost every project has some kind of dependency; it’s your job as a developer to make sure the dependencies are met in a suitable fashion. Furthermore, every project has different “build processes” – for some, this means compiling code. For others, this means setting environment variables or incrementing a “revision” count. Grunt is a highly-configurable tool that does many of these things for web-based projects. Powered by Node.js, Grunt and related projects have gained an enormous amount of support and active development contributions.

At Whiteboard, we are constantly starting new projects. This can happen even on a daily basis. What’s more, the developers are constantly iterating on and reviewing projects. Our work is highly communication-centric, with a focus primarily on a consumption orientation that is driven to develop brand voice. That’s a long way of saying we work more heavily with content publishing platforms than we do “web apps”.

For this reason, we adopted WordPress long ago as our primary project platform, and have made WordPress knowledge a core competency of our agency. We work in other areas (Rails, specifically) as well, but for spinning up a content publishing platform for a client, WordPress is our go-to.

Manual Dependency Management

A year ago, our processes were very slim. I like to think of this as a Good Thing™. We worked quickly, and used tools as they popped up. In the WordPress world, we found a few base themes (like Bones), and then threw our own self-brewed stuff on top. The development team is experienced enough to adopt a wide variety of tools, and this worked fine. But we started to notice problems creeping into our system: our tools were all quite similar amongst a set of projects, but none of them were dependably exactly the same. We also knew that the tools could be unified – we used the same basic types of tools/libraries/themes/structure on every single project.

We had adopted LESS, but were using CodeKit on our private machines without any global configuration. (CodeKit is awesome, and has these types of project-level options available, but we weren’t using them.) After a few accidental overwrites and other issues, we realized that everyone’s process, like our toolsets, were very similar, but just off enough to show cracks in our system.

Makefiles

Our first step towards a solution was to adopt a Bootstrap-inspired approach to compilation and project builds. Before Bootstrap 3, the process for compiling assets primarily revolved around a Makefile. We brewed up our own makefile, and created the first version of a theme we called Launchframe. This unified a lot of our tools, and immediately this increased our ability to communicate about projects to one another, without much hassle. The powerful element here is that our code started looking and feeling exactly the same (rather than relatively the same). We also all adopted native (Mac OS)AMP + phpMyAdmin stacks on our Mac OS machines, using Homebrew to get everything installed. This makes for predictable and very easily executable PHP-based projects. (There are quite a few guides for how to do this, including this Homebrew-specific one.)

Moving to Grunt

The Makefile approach eventually started showing its flaws. Most specifically, some of the error reporting and watch scripts didn’t quite work as expected. While Make is certainly a powerful way to handle problems, we realized that people in our field were handling these same problems in a much more actively supported way through Grunt (and associated CLI tools). When Bootstrap 3 moved to Grunt, we made the move to Grunt, and once again adopted a lot of the techniques in the Bootstrap build process.

The Trick

The best way to reduce overhead for any kind of development process is to first find your consistencies and near-consistencies, and commit to them. Once you’ve made this commitment, build your tools to automate these consistencies. For us, we always use jQuery, we always use LESS, we always start with our base theme, and we always use a particular file structure. To make the process as easy as possible, we chose to commit to these consistencies, and build our workflow so that our developers need to only know the basic overview of the process. To start a new project at Whiteboard, you install WordPress, change into that directory and type npm install. This will install all dependencies for the Grunt tasks to work properly. Then, run grunt watch. Develop on the project like you always do, and push live.

A Step Further

Who wants to install WordPress? Wouldn’t it be nice if we could automate the whole process from front to back, and have a few prompts with configuration options along the way? Of course it would. So I made this script. Running this on a configured machine with the right tools does everything to open up the project, watching and ready to be edited. It’s also a lot of fun to run it, considering the colors lolcat provides. 🙂 It utilizes a few tools here and there, particularly wpcli, to get things going. This could probably be grunt-ified, but ask yourself: why would that be valuable?

#!/bin/bash
command -v lolcat >/dev/null 2>&1 || { echo >&2 "I require lolcat but it's not installed. Run gem install lolcat."; exit 1; }
command -v wp >/dev/null 2>&1 || { echo >&2 "I require WordPress CLI but it's not installed. \n Run the following:\n curl https://raw.github.com/wp-cli/wp-cli.github.com/master/installer.sh | bash
."; exit 1; }
command -v git >/dev/null 2>&1 || { echo >&2 "I require git. For more information, visit: http://git-scm.com/book/en/Getting-Started-Installing-Git "; exit 1; }

purple='\x1B[0;35m'
NC='\x1B[0m' # No Color


echo '

LAUNCHFRAME 0.1 #########
####### A WHITEBOARD TOOL

       !
       !
       ^
      / \
     /___\
    |=   =|
    |     |
    |     |
    |     |
    |     |
    |     |
    |     |
    |     |
    |     |
    |     |
   /|##|##|\
  / |##|##| \
 /  |##|##|  \
|  / ^ | ^ \  |
| /  ( | )  \ |
|/   ( | )   \|
    ((   ))
   ((  :  ))
   ((  :  ))
    ((   ))
     (( ))
      ( )
       .
       .
       .
' | lolcat

if [[ $1 == "" ]]; then
    read -p "Enter the site folder you want to create for installation: " sitefolder
else
    sitefolder=$1
fi

echo -e "${purple}Downloading WordPress... Please wait a moment.${NC}"

mkdir -p "${sitefolder}" && cd "${sitefolder}"

wp core download

echo -n "Enter database name (press enter for wp_${sitefolder}) "
read dbname
if [[ $dbname == "" ]]; then
    dbname="wp_$sitefolder"
fi

echo -n "Enter database username (press enter for root) "
read dbuser
if [[ $dbuser == "" ]]; then
    dbuser="root"
fi
read -p "Enter database password (required): " dbpass
while [[ $dbpass = "" ]]; do
    read -p "You cannot continue without entering a database password (required): " dbpass
done

echo -n "Enter site url (press enter for http://localhost/${sitefolder}) "
read siteurl
if [[ $siteurl == "" ]]; then
    siteurl="http://localhost/${sitefolder}"
fi

echo -n "Enter site title (press enter for ${sitefolder}) "
read sitetitle
if [[ $sitetitle == "" ]]; then
    sitetitle="${sitefolder}"
fi
echo -n "Enter admin email (press enter for admin@example.com) "
read adminemail
if [[ $adminemail == "" ]]; then
    adminemail="admin@example.com"
fi

echo -e "\n"
echo -e "${purple}Creating the wp-config file.${NC}"
echo -e "\n"

wp core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass

echo -e "\n"
echo -e "${purple}Creating the database.${NC}"
echo -e "\n"

adminpw='[filtered]'
adminun='admin'
wp db create
wp core install --url=$siteurl --title=$sitetitle --admin_name=$adminun --admin_password=$adminpw --admin_email="$adminemail"

echo -n "Install Multiple Post Thumbnails? (y/N) "
read a
if [[ ${a:0:1} == "Y" || ${a:0:1} == "y" ]]; then
    wp plugin install multiple-post-thumbnails
    wp plugin activate multiple-post-thumbnails
else
    echo -e "\n"
    echo -e "${purple}Run wp plugin install multiple-post-thumbnails to install later.${NC}"
    echo -e "\n"
fi

echo -n "Install Yoast SEO? (y/N)"
read a
if [[ ${a:0:1} == "Y" || ${a:0:1} == "y" ]]; then
    wp plugin install wordpress-seo
    wp plugin activate wordpress-seo
else
    echo -e "\n"
    echo -e "${purple}Run wp plugin install wordpress-seo to install later.${NC}"
    echo -e "\n"
fi

echo -e "\n"
echo -e "${purple}Downloading Launchframe...${NC}"
echo -e "\n"

wp theme install https://github.com/Whiteboard/launchframe/archive/master.zip

echo -e "\n"
echo -e "${purple}Activating Launchframe...${NC}"
echo -e "\n"

mv wp-content/themes/launchframe-master wp-content/themes/launchframe
wp theme activate launchframe
echo -n "Install Custom Meta Boxes? (y/N)"
read a
if [[ ${a:0:1} == "Y" || ${a:0:1} == "y" ]]; then
  git clone git@github.com:jaredatch/Custom-Metaboxes-and-Fields-for-WordPress.git wp-content/themes/launchframe/inc/cmb
  echo "Custom Meta Boxes requires a manual include and setup - be sure to add this in functions.php or somewhere similar."
fi

cd wp-content/themes/launchframe
npm install


echo -e "\n"
echo -e "${purple}Opening the site install...${NC}"
echo -e "\n"

open $siteurl

echo "Done!"
echo '
  ______   _______  _______  _______  _______ 
(  ___ \ (  ___  )(  ___  )(  ___  )(       )
| (   ) )| (   ) || (   ) || (   ) || () () |
| (__/ / | |   | || |   | || |   | || || || |
|  __ (  | |   | || |   | || |   | || |(_)| |
| (  \ \ | |   | || |   | || |   | || |   | |
| )___) )| (___) || (___) || (___) || )   ( |
|/ \___/ (_______)(_______)(_______)|/     \|


 ' | lolcat
subl ../../..
grunt watch

Do What Keeps You Moving

The thing we’ve learned about learning new tools is to find ways of constantly doing something new. This means stop doing the same things over and over. Wasting your time doing the same things over and over means you aren’t innovating, and you aren’t creating change. Don’t stop learning, but learn, implement, and move on to learning more and doing more. This is perhaps an opinionated understanding of the purpose of learning as it applies to development, but it certainly offers a strong method for balancing intellectual progress and business-oriented productivity.

My Solution for Quantified Self: Prompted Data Aggregation

The quantified self is really quite a hot topic. Ivan Kirigin talks about it in his post here as a potential startup idea. I’ve created something simple I’d like to share with all of you.

It is really quite simple, but also very flexible. Before I explain what it is, I’ll cover some of the conceptual reasoning behind the solution.

I believe that to do lists are generally quite hard to deal with, and overall don’t help my productivity. They require me to return to them over and over throughout the day, managing them, and often only serve as a place to mark things as done (rather than a place to ensure that I am being productive).

However, I don’t mind prompts. I don’t mind alerts. Certainly too many of irrelevant alerts can be annoying. But if I am motivated to use the alerts, I will.

As a developer, I am used to constant feedback. I am used to my machine telling me when I have compile errors. I’m used to having reports. These reports are what I take action on. To-do lists stay dormant until I put effort into them. The same can be said for calorie tracking applications. The same can be said for most tracking applications.

So, I created a small script to ask me a random question. I set up a YAML file to track my answers and the dates of my answers. I then created a simple plist file to load the script every 8 minutes via launchctl. This will give me about 50 data points per workday.

While they may be simple data points, and while the questions will repeat, the concept is simple: my computer asks me a question, and tracks my answer for me. My answers can be arbitrary; I also have two types of questions. One is directly actionable, the other is subjective. (“Tell your wife you love her.” vs “What have you eaten today?”)

Here is the Ruby code:

#!/Users/jonathancutrell/.rvm/rubies/ruby-2.0.0-p247/bin/ruby
require 'yaml'
y = YAML::load_file(File.join(__dir__, "stretchr.yml"))
if (rand(10).to_f/10.0).round == 1
    @msgs = y["msgs"]
    @msg = @msgs.sample
    ret = `osascript -e 'set question to display dialog "#{@msg}" buttons {"Nope", "Did it"}'`
    ans = ret.split(":")[1]
else
    @questions = y["questions"]
    @msg = @questions.sample
    ret=`osascript -e 'set question to display dialog "#{@msg}" default answer ""' -e 'text returned of result' 2>/dev/null`
    ans = ret
end
@answers = y["answers"]
@answers[@msg] ||= []
@answers[@msg]<< [ ans, Time.now ]
File.open('stretchr.yml', 'w+') do |file|
  puts file.write(y.to_yaml)
end

And here’s the yaml file.

---
msgs:
- Stand up and stretch.
- Live healthy, think healthy
- Tell your wife you love her.
- Do something to show appreciation to your coworkers and employees.
- Text a family member.
- Value, now. Stop doing things that don't matter.
- Have you kissed your wife today?
questions:
- Is your desk clean?
- Have you had 10 minutes of quiet thinking time today?
- What word are you thinking of right now?
- Who was the last person you spoke to?
- Is Hacker News open?
- What are you building now for tomorrow?
- Text a family member.
- What have you eaten today?
- On a scale from 1 to 10, how energetic are you?
- On a scale from 1 to 10, how productive do you feel today?
- How many hours did you sleep last night?
answers: {}

And finally the plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>org.jcutrell.stretchr</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/jonathancutrell/stretchr.sh</string>
    </array>
    <key>StartInterval</key>
    <integer>480</integer>
</dict>
</plist>

Some of these you can clearly see come from personal goals. Some of them, though, are much more related to aggregating some sort of arbitrary data. Later, I hope to gain some kind of insights from this into very specific areas of my life.

Notice the name stretchr.sh – this was originally built to be a simple reminder to stand up and stretch at my desk. I would go hours on end without stretching simply because it wasn’t on my mind. So many things we should, could, and want to do go undone because we simply let them slip our mind. I’m interested to see how much of an impact these more consistent reminders will have.

It’s obviously very easy to add new data points. Of course, as you add more questions or imperative messages, it’s more likely that you will have more time between data points on average, assuming an even distribution of the random range generator over time.

It would be easy to take this YAML data somewhere else, like for instance to JSON to be fed into something like D3:

require 'yaml'
require 'json'
y = YAML::load_file(File.join(__dir__, "stretchr.yml")) # I think this may be v>=2.0
puts y.to_json

Interested in doing something similar? Or interested in making this more than it is? Let me know. I’d love to let this grow.