What You Won’t Do Defines You

We often define ourselves by what we strive to build, the markets we want to enter, the customers we want to serve, and the visions we want to pursue. These are of course necessary, but they are not defining. The deeper source of identity is not what an organization chooses to do. It is what it chooses not to do.

This is uncomfortable because possibility feels like power. A capable team can always imagine another feature, another market, another customer segment, another partnership, another product line. The temptation is especially strong for talented founders because talent creates options, and options create the illusion of progress. The more a team believes it can do, the more vulnerable it becomes to doing too much.

But strategy is not the accumulation of possibility. Strategy is the disciplined rejection of most possibilities.

A company does not become distinct merely by having ambition. Ambition is abundant. What makes a company distinct is the courage to refuse attractive alternatives. The refusal to venture off into yet another direction is what gives a company its shape. It tells the team what matters, tells customers what to expect, and tells the market what the company is willing to sacrifice in order to become itself.

Artist are seen as those that are free to chase their every imagination, but making a 2 hour movie work is painstakingly an act of constraint and commitment. Imagine the push back that comes from wanting to represent a seen so badly that you push the a $10M shot that lasts 10 seconds. Could you commit to it when everything inside and outside your world is saying it is falling apart? What makes art such an inspiring form of achievement is the commitment to see a singular vision though to the end for – well – what some would call “just a little piece of expression”.

Apple is known for going big on marketing and charging a lot for their products. What most don’t see is Apple is a hallmark of restraint. Apple is not simply Apple because it builds computers, phones, operating systems, or services. Anyone can have a vision for a great computer or experience. Apple is Apple because it has historically chosen control over ubiquity. Upgrades over legacy. It has preferred integrated experience over maximum openness. That choice requires saying no to many obvious opportunities: software for every device, infinite customization, broad compatibility at any cost, and the short-term revenue that comes from being everywhere. (In fact, their lack of constraint is what almost put them under early in their growth – but that is a story for others to tell. )

Those refusals are not incidental. They are central to the product. That isn’t to say their decisions are required for success, but making those decisions and sticking to their identity is.

Few would say Microsoft is not successful and they are a very different looking company. For most of its history they made an opposite choice. Its power came from not being tied primarily to its own hardware. Windows and Office became dominant because Microsoft chose scale, backwards compatibility, options via licensing and distribution across a vast ecosystem of machines it did not manufacture. That strategic refusal gave Microsoft its own identity. It was not Apple, and that was the point. Both companies are shaped more by what they refused as by what they pursued.

The same pattern appears in many industries.

A company making a fast car is not merely choosing speed. It is often giving up affordability, mass accessibility, or low-maintenance practicality. A luxury brand is not merely choosing premium materials or elevated design. It is refusing accommodate everyone’s requests – in fact – they hope they are not. A great restaurant is not merely choosing a menu. It is refusing to serve every taste, every trend, and every customer expectation. The strength of the experience comes from the boundaries around it.

Most people know it when they see it, but chaos, disorganization, and what can feel like a lack of brand identity is merely the manifestation of a lack of restraint. Picking your lane is not giving up on a grand vision, it is dedicating your time to a specific outcome; it is an example of discipline. It is the difference between a light and a laser. 

Even Costco, which appears on the surface to sell almost everything to everyone, is built on disciplined refusal. Its model depends on giving up selection of a myriad of options for the same product. It carries a limited number of SKUs, uses warehouse-like stores, bulks up on few variation of a product, and optimizes ruthlessly for efficiency and value. It will not take profits that don’t meet within these restraints.

This distinction matters because every “yes” has a cost beyond the immediate work required. Every yes changes the product. Every yes changes the company’s internal logic and dilutes identity.

Yes you can do anything, but no we can’t do everything.

How do we decide that line?

Proving ambition with breadth is how companies lose coherence. Rarely all at once. More often, they lose it through a series of individually reasonable expansions. One more feature. One more customer type. One more exception. One more “strategic” partnership. One more “why not?” One more compromise that seems harmless in isolation but slowly erodes the original center of gravity.

The problem is not that expansion is bad. Growth often requires expansion. The problem is having expansion without a theory of refusal. An investor without a thesis is throwing money around. Even if they make wins it is not a story they can sell, and without that sale there is no fund.

Without a clear understanding of what the company will not do, growth becomes drift. The company may get bigger, but it does not necessarily get stronger. It gains surface area while losing definition.

This is why the question “What are we building?” must be paired with a harder question: “What will we never build?”

What customer will we not serve?

What feature will we not add?

What revenue will we walk away from?

What behavior will we not reward?

What pressure will we not yield to, even when yielding would make the quarter easier?

What do we cut?

As the great quote says: I don’t sculpt stone into what it should look like, I chip away all the stone that isn’t. 

For founders, this discipline is especially important because early companies are fragile systems. A young company has limited time, limited attention, and limited resources. You are ALWAYS stealing from Peter to pay Paul – you can’t pay both.

With AI the lack of constraints required is the very dirt founder can now bury themselves in ten-times over. A product cannot afford to become many things at once – even if it is able to. The founder’s job is not merely to inspire motion. It is to protect the company from compounding motion it can not manage. By being weighed down by its options.

In this sense, refusal is not negativity. It is not small thinking. It is not fear. It is not the lack of vision. It is the architecture of commitment. Vision may be the destination, but focus is not blowing all your travel money on the first stop. It is not getting married on the first date.

To choose anything seriously you must give up many other things. The stronger the choice, the stronger the refusals required to preserve it. This is true for products, brands, companies, and creative lives. You do not become distinct by remaining available to every possibility. You become distinct by rejecting most of them with enough conviction that the few remaining possibilities can be pursued deeply.

The world does not suffer from a shortage of people willing to add more. It suffers from a shortage of people willing to define what must be left out. That is where real strategy begins.

Keep It Right-But-Light

A clearer standard for building well

Most builders have inherited a bad vocabulary for early product work.

We tell people to build an MVP, but the phrase has become so overused that it often clarifies less than it confuses. Some people hear “minimum” and interpret it as permission to ship something brittle, awkward, or barely usable. Others hear “viable” and inflate the work into a miniature production system, complete with abstractions, infrastructure, tests, edge-case handling, and design polish that may never matter.

To balance that out we encourage people to “just hack it together,” which pushes the pendulum into a different problem. Hacky can be useful when it means fast, practical, and unconcerned with unnecessary ceremony. But hacky too often becomes an excuse for bad work. It works in the narrowest technical sense, but some see it as license to create terrible unpleasant use, error laden, difficult to understand, and fragile the moment reality touches it.

This is the gap “right-but-light” is meant to name.

Right-but-light means building something correctly enough that it earns trust, while keeping it light enough that it remains easy to change. It is not about doing less work. It is about refusing to carry more weight than the moment requires. It isn’t minimal or maximal. It is that harmonious balance so many folks have trouble finding. We don’t hack down the scope to get away with a bad implementation, we do it so the one thing we choose to do is done well – while still not evergreen or perfect.

The “right” part matters because users do not experience your product through your intentions. They experience it through the surface area you give them. A button that is twice as large as it should be may not break the system, but it may still signal that your offering is dangerously unkempt. A workflow that technically completes the task but makes the user think too hard won’t get used – at all. A prototype that loses data, hides errors, or makes the user feel unsure doesn’t give you the real signals you are looking for. These things may be excusable in a throwaway 24-hour hack-a-thon demo, but they are not balanced for an initial product seedling. They train the builder, the user, and the team to tolerate roughness where clarity was needed.

The “light” part matters because early certainty is usually fake. At the beginning of a product, most of the important learning still has to happen. The shape of the problem will change. The user may care about a different part of the workflow than expected. The thing you thought was a feature may turn out to be a demo path. The thing you thought was temporary may become the center of the product. In that environment, heavy architecture is often a liability disguised as discipline and thoughfulness.

A right-but-light implementation avoids both forms of waste. It does not ignore usability in the name of speed, and it does not overbuild permanence into something that has not yet earned permanence.

This distinction has become more important with agents. Human teams already struggled with the nuance between fast and sloppy, or thoughtful and overbuilt. Agents amplify that ambiguity. Ask an agent to “build an MVP” and it may produce a sprawling approximation of a real application. Ask it to “make it hacky” and it may skip the very details that make the product usable. The instruction was vague, so the output becomes a coin flip between underbuilt and overbuilt.

“Keep it right-but-light” is a better constraint because it tells both the human and the agent what kind of tradeoff is being made. The work should be correct in the parts that matter. The interface should be understandable. The happy path should feel intentional. The data should not vanish. The user should not have to forgive the product in order to use it.

But the implementation should remain light. Maybe the data lives in a JSON file before it earns a database. Maybe the workflow is hardcoded before it earns configurability. Maybe the UI uses an existing design pattern rather than inventing a new system. Maybe the feature does not need role-based permissions, event streams, audit trails, background jobs, and a full settings page on day one. Maybe the right version is simply the smallest version that behaves with taste.

Right-but-light also gives teams a cleaner stopping rule. The question is not “is this complete?” because early products are almost never complete. The better question is: “Is this right enough to learn from, and light enough to change after we learn?”

That question changes the conversation. It moves the team away from false binaries. You are no longer choosing between a disposable hack and a production-grade system. You are choosing the minimum level of correctness required for meaningful use, and the minimum level of structure required for responsible iteration. Yes, that is what MVP and lean startup. It is just that I have tried for YEARS to explain that to people and it either doesn’t land or get me in to trouble with “you said to do the minimum!”

For example, a right-but-light onboarding flow may not need analytics dashboards, branching personalization, enterprise configuration, and a polished admin panel. But it probably does need clear copy, coherent visual hierarchy, a reset path for testing, and enough state handling that the user does not get trapped. A right-but-light internal tool may not need a formal database schema or complex permissions. But it probably does need predictable inputs, readable outputs, and error states that do not require the builder to stand nearby and explain what went wrong.

There are many great product folks out there building things you love, and I am sure you have used a product you loved and realized there was no delete button and wonders “WTF? Why can’t I delete?!”. If you get a req for your unaware peers in different departments they would have died on the sword to put the obviousl “delete” in on v1, but no feature is truly “simple” and without a time cost. So, that product manager says “they need to love what they create before they need to delete.” One less unit of time for one side of the product, one extra unit of time for another. No one has infinite time or infinite money. No one. 

So how do you chose? The point is not to lower standards. It is to place the standard in the right part of the work and be okay with walking away from the other.

Long-lasting applications deserve robustness, scalability, observability, automated tests, security reviews, edge-case handling, and design precision. But not every early feature has earned that full burden yet.

Premature permanence slows learning. It turns every change into a negotiation with yesterday’s assumptions.

Speed without standards is not iteration. It is motion. Wheels spinning fast in the mud.

It asks for seriousness without heaviness. It asks for speed without sloppiness. It asks for taste without vanity. It asks the builder to cut everything that is not required, while doing the remaining things with care.

That is the deeper meaning of the phrase.

Right-but-light is not another way to say MVP. It is a correction to what MVP has become. It restores the part people forgot when “agile” and “MVP” became a household term.

Can You, Did You, and Taste

Three stages separate ideas from products, and products from things people love.

The first stage is capability.

Can it be done? Can the software be written? Can the company be started? Can the product be built? Can the problem be solved?

These questions matter because capability is the foundation upon which everything else rests. Nothing can be executed, adopted, or admired until it is first plausible.

This is where most people rest comfortably.

The surprising thing about capability is that proving something can be done often provides many of the same emotional rewards as actually doing it. Once someone becomes convinced they could build the company, write the book, get in shape, learn the skill, or launch the product, the pressure largely disappears. Potential becomes a source of comfort.

The entrepreneur enjoys imagining the startup. The author enjoys discussing the book. The engineer enjoys architecting the system. The athlete enjoys knowing they could get serious whenever they decide the time is right. People tend to love their own brains and marvel at what it can achieve. Potential is attractive because it is free from accountability. It cannot fail because it does not yet exist.

Did you actually do it?

The second stage is execution. It only lives in the past tense. This is where the conversation changes. Ideas become products. Plans become companies. Discussions become outcomes. Concepts become features available for use and critique to the public domain. The world stops evaluating intentions and starts evaluating evidence.

A customer cannot buy potential. A user cannot interact with ambition. An investor cannot generate returns from possibility alone (though they push this rule as much as possible). The market, unlike our friends and colleagues, is remarkably indifferent to what could have happened. It only responds to what did happen.

People who reach this stage deserve significant credit. The distance between an idea and reality is far larger than most people appreciate. Building something that survives contact with the real world is difficult. Something complete, end-to-end. It accomplishes its intend (big or small) and no hand holding or excuses are needed for it to be used properly. Launching is difficult. Selling is difficult. Maintaining momentum is difficult.

Most people never get there. And I am being generous with “most”.

Yet many who do arrive at execution mistakenly believe they have reached the finish line. They assume that because something works, people will care. They assume that because a solution is objectively better, adoption will naturally follow. They assume that utility alone is enough. They believe a logical use case exists and therefore usage will follow. A good plan and execution is all that is needed.

History suggests otherwise.

The graveyard of technology is filled with products that worked. Many were faster than their competitors. Many were technically superior. Some were years ahead of their time. Their failure was not one of engineering. Their failure was assuming that human beings make decisions primarily through logic.

Taste.

Taste is one of the most misunderstood concepts in business because it is often reduced to aesthetics. People hear the word and think about typography, color palettes, industrial design, architecture, or fashion. Those things matter, but they are only symptoms of something deeper.

Taste is the ability to understand how another human being will experience what you have created.

It is the recognition that people do not merely consume functionality. They consume stories, emotions, identity, aspiration, status, trust, culture, and delight. A chair is not simply somewhere to sit. A restaurant is not merely a place to eat. A home is not simply shelter. A product is not just a collection of features. Even a purposefully poort taste for those that are tasteless is, in fact, a taste. The trickle down story line of decisions and focused intent lead to those that have the same test to become interested. Taste is not being fashionable, it is knowing people need clothes and certain groups of people like cheap clothes, some like expensive clothes, and some like expensive clothes that are on sale – but they know which group of tasters they want to have.

Every meaningful creation eventually becomes an experience.

This is why two products with nearly identical functionality can produce radically different outcomes. One becomes beloved while the other is forgotten. One creates a movement while the other creates a user base. One becomes part of a person’s identity while the other remains a tool.

The difference is often explained by taste.

The creators who understand taste recognize that presentation is part of the product. Storytelling is part of the product. Culture is part of the product. The emotional experience surrounding something is not separate from what is being built. It is one of the things being built.

Most people spend their lives asking whether something can be done. A much smaller group proves that it can. The rarest creators understand that neither capability nor execution guarantees significance.

The first stage asks whether something is possible.

The second proves that it is.

The third determines whether anyone cares.

Socratic AI: The debate-based Writing Method to create better content

When asking AI to write articles, I think most people prompt apps to “Write about this…”. They provide some details about what to write, more or less, and then use AI to help with the editing. It’s a kin to having an editor or ghost writer.

I started in the same way, but always felt like I was battling the AI instead of working with it. I’ve come to use it very differently. Not do I love this new method but I learn a lot from the experience each time.

Instead of asking AI to write for me, I use it to think through concepts with me. To have it debate or question my thoughts. To specifically “not write an article” for quite some time until I think we are on the same page. This can sometimes take weeks strewn with small chats with long breaks in between until a new thought spark up again.

This whole approach started by accident when I discovered more personality with GPT 4. One day I got riled up from reading some shallow post. It sparked a mental argument with myself to try and see how “the other side” could come to such a different conclusion. On a whim I gave ChatGPT a chance to give me the other side and it surprised me. It not only delicately agreed with my POV, but it gave another potential position followed by “if you could change the circumstance how would you do it?”

It didn’t just echo my points. It pushed back. It made counterarguments. It sharpened the conversation. I ended up having a long conversation with the AI. By the end of it, I understood my own idea better. I felt like I had a smart, patient thought partner who genuinely got what I was trying to work through. It was mind blowing.

That’s when it hit me. If GPT can do this with abstract ideas, why not use the same kind of back-and-forth to help me write?

That’s how this process was born. I’m not starting with a goal to create a draft. I’m starting with a goal to think through a conversation and see where it leads.

What I’ve found feels like a modern revival of the Socratic dialectic. It gives me a space where I can toss out half-formed thoughts, question assumptions, test ideas, and refine them through dialogue. Some go nowhere, but all end with a better grasp of my original thought or counter thoughts.

I keep all my writing in a single project so GPT has context from everything I’ve written or said before. When I want to explore something new, I open a fresh thread and say:

“I don’t want anything created yet. I want to jot thoughts down and then I’ll let you know if I’m ready to create something or if I want to dig deeper.”

Then I just post whatever comes to mind. No outline. No goal. Just the original vapor of a concept. Sometimes I ramble. Sometimes I loop back or take side paths. Sometimes I ask:

“What do you think?” or “Is there a counterpoint I’m missing?”

And it responds. Not with a final draft, but with friction. With momentum. With more angles to explore.

I think best in conversation. I rarely find clarity in a vacuum. Often I will argue a point with someone and walk away with a whole new version or perspective on my belief. Often, I push on ideas, debate myself, and churn.

So when GPT became more conversational, it clicked. It felt like I finally had a thinking partner who didn’t judge, remembered everything, and has no distinct side. The result isn’t just better writing. It’s better thinking.

Once the idea has been explored enough, I ask GPT to turn the thread into an article. Since it has been there for the full conversation and already knows my tone from past articles, the first draft usually comes back pretty close to what I want.

It is never final, but far more inline and final than anything I have ever tried to create with AI before.

Once I am done I end the thread with my final post in my project:

“Here’s the one I actually used. Save this to memory. No more feedback or follow up needed.”

Over time, it learns me. My tone. My rhythm. The kinds of lines I keep, the ones I cut, and the ones I repeat for emphasis. It becomes both a mirror and a co-writer.

So no, I don’t start by asking GPT to write something. I start by asking it to listen. To push back. To help me think through things better. This isn’t AI-assisted writing, it is AI-assisted dialectic.

Updated Review of LLM Based Development

I tried developing using GPT mid-2022. While I was amazed by the potential, I was not impressed enough to add it to my daily development workflow. It fell off my radar as a development tool, outpaced by a far more impactful use of text generation and image creation. A toolset that has significantly changed my day-to-day productivity.

Recently, a group of peers convinced me to give coding with LLM another shot. They loved using A.I. to develop code in languages they were not comfortable with. Or, as a manager, a way to better explain what they wanted to see in a project from their team. What convinced me to try it again was their highlighting of how well the results were formatted, syntactically correct, and well documented from the get-go. While they admitted the development of code may not be faster, the prospect of all those benefits culminating into a cleaner, well formatted final product convinced me to develop with GPT again in earnest.

I began my reexamination of the tooling via demos, as we often do. I was very impressed. I converted code into PowerShell (which I don’t know well) and re-created functionality I came across in weeks prior. I was so impressed, I showed my team examples of how the work they completed in the past could’ve been done with the help of GPT instead.

After those successes, I committed to using GPT to develop. Over the next few weeks I made sure to use it on projects I was working on.

While the technology showed incredible advancements since I tried it last year, it still hasn’t become my go-to in the same way using ChatGPT has for writing content.

Here are some areas I was both impressed with but left wanting:

  1. Code completion
    • Pro: Impressive. The look-ahead came in handy similarly to code-completion functionality of the past, with the added benefit of more contextual relevance that was not just a “cookie cutter” snippet.
    • Con: It gave me a useless hint quite a bit and I found myself typing almost as much as before with the incumbent “dumb completion”. I think it is because my mind is moving ahead to what I want the code to do, not necessarily what it is doing on the console at the moment. In the end, it is using patterns to make predictions. So, any new code that is a result of changes to my approach, or my on-the-fly reworking to fix a bug (that was not due to syntax issues) took as much time to develop as non-GPT-based code completion.
  2. Testing
    • Pro: When it comes to testing an existing application, the A.I. hits it out of the park. Ask it to “write a test for myFunction() using Jest” it creates an awesome base test case that I would have hated to write for each function.
    • Con: Some of the same issues outlined in the “Code Completion” and Functional Development” can be problematic here. It doesn’t always create a great test for code I haven’t written yet. (i.e. TDD) However, if the code is already there, it uses that context I’ve provided and its LLM to unpack what it the function is suppose to do and generate all the mocks and assertions needed to create a well written unit test.
  3. Functional Development
    • Pro: Much like helping me get past the dreaded blank page in text generation, I found it more useful than Google searches and StackOverflow reviews to develop a series of functions I wanted, without developing entirely from scratch. Better than code snippets, the snippets A.I. gave were pre-filled based on my prompts, variables, and existing object definitions. That was appreciated. I didn’t have to review the documentation to tweeze out the result I wanted. The A.I. pulled it all together for me.
      Additionally, the fact that it almost always has an answer goes under appreciated in other reviews I’ve read. The part that makes it so advanced, is it fills in a lot of grey area even if I (as a stupid human) carelessly leave out an instruction that is critical in generating a solution. If I were to get the response, “could not understand your request” due to my laziness, I would never use it. The assumptions it makes are close enough to my intent that I am either using the solution, learn a new path, or see what my explanation is missing so I can improve how I communicate with it.
    • Con: The end result did not work out of the gate most of the time. Sometimes it never got it correct and I had to Google the documentation to figure the issue. This was due to what I think was more than one documentation existing for various versions of the library I was using. I’m not sure. While the syntax was correct, the parameters it assumed I needed, or the way the calls were made to interface with a library/API led to errors.
  4. Debugging
    • Pro: Per the “functional development” points above, I was impressed at how I could respond to a prompt result with “I got this error when using the code above: [error]”. It recognized where it went wrong, and attempted to rewrite the code based on that feedback.
    • Con: Each response had a different result than the original. So, instead of fixing what I found was wrong (like a param missing) it also added or removed other features from the code that were correct. This made the generated result difficult to utilize. In some cases, it could never understand the issue well enough to generate working code.

One limitation I am not too surprised about, and am hopeful to see evolve in the future, is the AI’s understanding of a project in its entirety. Done so in a way that context is used in its function creation, making the solutions it provides “full stack”. Imagine a Serverless.com config, for an AWS deployment, that generates files and code that creates and deploys workflows using Lambda, DynamoDB, S3 and so on, all being developed based on prompts. With the yearly (and more recently) weekly leaps, I don’t think we are to far away.

As of today, I find myself going to GPT when filling in starter templates for a new project. I find it’s a much better starting point than starting from cookie cutter function as I set up my core, early, “re-inventing the wheel”-type, skeleton.

For example, I will use a Gitlab template for my infrastructure (be it GL Pages, Serverless, React, nodejs or Python and on and on), then fill in the starter code an tests via a few GPT prompts, and copying them over. Beyond that copy, I find myself detaching from GPT for the most part, and returning to occasionally “rubber duck” new framework functions.

Examples referenced above

Here I asked for a non-3rd-party use of promises (only await/async) which worked. Then I asked to modify the code by adding a zip task, and it re-introduced the promisify utility when it added the zip process.

I finally mastered my reading list!

Over the years, I’ve tried a number of ways to plow through the never ending suggestions of books that I “need to read”. I’ve kept lists in paper notebooks, Facebook books, Goodreads, my iOS Notepad, and even as a Reminders list. The list keeps getting longer. I buy books I don’t end up liking or reading, or just forget to place one in the barrel next time a get some free time to read.

Recently I discovered a way to automatically manage my list and get the book in my hands in almost any format or device — for free! Here’s how:

First, download the Libby app.

Libby is an app by Overdrive that helps make checking out books from the library easy. No, don’t worry, it’s not a way to checkout paper books. Libby is focused on helping you download audiobooks and digital books and allows you to push them to your Kindle, iBooks or whatever works for you.

Now, before you disregard the power of your local library (the institution your tax dollars pay for) let’s flip the script. Libby allows you to grab books you’re interested in.

So, think of how it plays out: You hear about a book that “you need to read.” You search for it on your Libby app, and you place a hold on it. Yes, there is a wait list for your book, and popular ones often have longer wait lists. But, guess what? You don’t care!

This is your reading list!

When books are available, they pop onto you phone or Kindle. If you don’t have time to read it, just put it back into the hold lists for the next go around. If you want to read a few chapters and put it away, that works too. The hold queue isn’t just some arbitrary list you keep that is disconnected from the act of reading — they are one and the same.

I have been doing this for the past year and love the fact that I don’t need to feel bad about falling behind on my reading. I know I’ll just read the next book that becomes available, and not think twice about my queue.

It took a while to get to “reading zen”, so I thought I’d share it. Hope it works for you too!

How this Google Home app helped my father after his stroke

About a year ago my father had a stroke. After 70 years of work as a salesman, 6 days-a-week for 12 hours-a-day, this deficiency forced him into retirement. Hoping to get back to work, he received speech therapy but never fully recovered.

Now in retirement, his typical quiet demeanor at home has kept him from exercising his neural network to reroute his audio connections. He is not tech savvy, so my attempts to get him using games on Luminosity have been unsuccessful.  

This Thanksgiving, during my visit to my parents house, I decided to see how he would fair with a Google Home. So far it has been great! Even practicing the wake word “Hey, Google” was a challenge at first, but he is improving dramatically.

Excited, I went through all the games I could find. I quickly realized just how unintuitive and disorganized the App side of Google Home still is. Some apps worked, and some didn’t. Either an app was “Not Found” or “Not Responding” when I tried to activate it. Sometimes an app would unexpectedly quit mid use. Even more frustrating were the multiple steps needed to try the above search for a working app over and over again after hitting a dead end. For example:

Me: “Hey Google” (Google Lights up)

Me: “Talk to X Game” (Wait)

Google: “Sorry, I could not find X Game” (wait for light to go off)

….Start over with another game name”

Navigation through the voice-UI was frustrating as well, and for my Dad it was impossible. To work around the issue, I went through all the games I could find online, and wrote down the ones that worked from the ones that did not. Then, I wrote our an old-school paper cheat-sheet that listed each game and its commands.

“Hey Google, – Let’s play a game”

“Hey Google, – Play 1-2-3 game”

….

What made it more complicated was that some trigger words required the user to say “Play” while others required the words “Talk to”. There is no reasoning I could find as to why there was a differences. What I realized is that these nuances were terrible difficult to retain for my non-tech savvy Dad. So, listing them out distinctly, on paper, and placing the paper next to the Google Home Device, was the best way I could provide the info to him.

One thing my Dad has retained since coming to the US is his keen memory of the US Presidents. I imagine he studied american history proudly and tirelessly when he moved here and sought his citizenship. Unfortunately, the Presidents Quiz, which I found listed in Google Home’s marketplace, and one I was sure he would like, was one of the games that was “Not Responding”.

At first I was disappointed, but then realized this was the perfect opportunity to try and build a Home App! I set out to create a US Presidents Quiz on Google Home for my Dad. 🙂

There are many ways to build a Google Home app. The two I explored were DialogFlow (https://console.dialogflow.com – formerly app.ai) and the “Actions” console (https://console.actions.google.com/u/0/). Dialog Flow had a great UI that made it seems like it would be simple to set up an interaction, but the concept of Intents, Events, Entities, Training Phrases and Responses was complex. What fed into what, and where I was suppose to handle requests from users and deliver responses did not come easily.

Google Actions is amazingly simple and perfect for those looking to build a game or quiz. WhileDialogFlow has many samples (https://developers.google.com/actions/samples/github) and plenty of docs, I decided Actions made the most sense, and I would leave DioalogFlow for another project; by using Actions, I could spin up an entire game in a single night. Interested in creating your own? Just follow this extremly simpley one-pager: https://developers.google.com/actions/templates/trivia. No code required!

The more labor intensive part of this project was listing out the hundreds of questions, correct answers, and purposefully wrong answers for multiple choice, I needed to seed the game.

You can check it our yourself, by saying:

“Hey Google, Talk to US Presidents Quiz”
Or by opening it in the directory here.

UPDATE:

Here is a print out for commands if you have a similar situation.

Firebase is 🔥

I’ve had the pleasure to watch the Firebase product grow from an idea our office buddies had as a startup, into a formidable product, and then to a suite of products at Google. I’ve been really impressed with what the founders have done. Hats off to them.

This is not a fluff piece for a friend though. To be honest, and for whatever reason, I never really used the platform until about a year ago; just didn’t have a need.

That has all changed, and, today, I see firebase as more than just a cool product, but one that I truly love and have received tremendous value from. Here is how I got there and why I feel that way.

Remember Parse? Facebook acquired the DB as a service in April 2013, and shut them down in Jan 2017. If I remember correctly, Firebase served as Google’s way to address that chasm and provide a novel, cloud-based, data platform that was especially friendly to mobile developers.

A lot  has changed since, on the Firebase platform. Their systems is more than just a websocket based, real-time, hash database. It is a veneer to the plethora of services that sit locked away in Google’s not-so-friendly-to-use ecosystem.

It was very unlikely that I move from what I know in AWS, to what I do not know, and can not easily navigate, Google Cloud Platform. My initial need for a database that handled live-reloads on data update, grew into me using their storage, auth, hosting, serverless/functions, and logging services. In fact, it didn’t hit me that they were just tapping into GCP until I had to edit some auth/keys in the system; that’s just how seamless it is.

Out of curiosity, I tried to copy the same functionality of my Firebase system by setting up a GCP-only clone. It was a crappy experience! One I would never have taken the time to ramp up  on otherwise.

With firebase, if you want storage, boom you got it. Want to right some serverless functions, easy. Checkout logs and crash analytics, yup you’re covered. Create a key to allow access to your system? No problem. In just a few click or a few lines of code, you can get up and running easily, and have the power of Google (without the admin overhead) behind you.

When it comes to filler features to help keep moving quickly, Firebase is there for you. Whether it is a beautiful auth flow (without a bias to only using Google auth), an invite system, or “who is logged in now”, Firebase does not say “that is not core – go some place else or build it yourself”. I have found myself coming back to them, even when a live-db is not a requirement for the ease in implementing those filler features alone.

If there was a critique, it would be that their use of storage for video is not top notch. They lag behind AWS for their ability to pull content seamlessly. Not much else.

GitLab and My Transition from GitHub

I was a heavy Github user. That is to say, I used them exclusively for my code projects. For a long time, there was no question in my mind of who to give my projects to. Even when Gitlab entered the market, my first thought was, these guys are just copying GH, why would I convert? Not to mention, hearing the rumors  that the CEO is was a jerk didn’t entice me to rush to adopt.

A few crucial moments, and Gitlab releases, changed that way of thinking within a year. 

The Conversion

Initially, it was sheer curiosity that got me clicking around on their product.  That and the very low barrier to entertain that curiosity.

I had reached my “private repo” limit on Github, and of my private repos few were businesses and mostly projects that I experimented ideas with and/or coded up prototypes. So, I had reached that limit right when I had another idea I wanted to flesh out, and upgrading for a cost didn’t seem worth it. Out of curiosity, I went to GitLab and logged in.

As the name implies, GitLab did not shy away from their copy-cat beginnings as a GH clone. Because of that, I was able to login using GH credentials and import all my private repos for free. The conversions was instant and easy, and my access to an unlimited store of private repos sure did help. The copy-cat look and feel played to my advantage since there was no ramp-up required. What was different about the site were things I hated about GH. Like the wording on PRs (“MRs” in GitLab), or how I could create new files from within the UI.

All in all, an unexpectedly pleasurable experience.

Top of the Hill

My first experience was my gateway drug. Each new idea/project I started, I started in GitLab. It wasn’t too long after that I used them almost exclusively. Gradually, feature after feature, GitLab took that initial win with me and solidified it with feature I really loved having all in once place, like CI and CD.

Successful startups typically take one of two approaches: innovating on one thing and the rest is copy and paste, or, finding innovation as a combination of many non-innovations and putting them together in a beautiful way. For example, the first utensil was not a spork, and sliced bread did nothing more than combine bread and a knife in a novel, simple, and less expensive way.

GitLab is like sliced bread in that, they took a few things I already used (docker, git, CI/CD), and combined them seemlesless, and cost effectively,  as their innovation.

I can very easily go from a concept-project, into a full blown production sized deployment suite in a matter of minutes. In its most basic form, GitLab is very easy to use and can be entirely free.

What keeps me happy is that they keep pumping useful improvements out; and I emphasize useful. It is not getting cluttered with features that get in the way, or as a way to prove they are hard at work. Rather, they seem to have a pulse on the dev community.

Where are they Still Losing?

One thing that has yet to change is the stronghold GitHub has on the community driven aspects of development. Their attention to open-source, from links to NPM package repos, to issues for projects, all keep me returning to GH on my google searches.

 

Will GitLab take that on next? We will have to wait and see!

 

 

Digging into the Monte Carlo Algorithm

After hearing about the Monte Carlo Algorithm over beers with friends one night, I decided to get a better understanding of how it works and learn a bit more about poker along the way. For me, there is no better way to understand a problem than coding up  and launching a product around it.

Have you ever watched a Texas Hold ’em Poker Champion on T.V.? Every time a set of cards are laid out on the table the odds of each player’s hands is provided to the audience (for example, Lindh has a 75% chance of winning with his K and 9 of clubs above). Advanced poker players have become quite good at predicting the odds as a gut instinct and is partly why mathematicians enjoy the game so much.

In order to practice my ability to develop a second-sense for poker odds, I figured repetition was the key. The game I set out to create would lay out a set of cards and allow the user to predict the percentage probability of converting that to a winning hand, quickly, over and over again.

Of couse, there are far fewer total combinations of game-plays for a poker game as compared to a game of chess; so it isn’t rocket science. However, the variation in the number of players combined with a 52 card deck does create enough variation to make things interesting.

In order to make the solution robust, I used a Monte Carlo algorithm to generate thousands of possible outcomes randomly and recorded the statistical output for “player 1” to win.  Once the algorithm was completed in Python, I built a Google Polymer app to present the probability guessing game.

You can test your ability to guess your probability of winning a text hold ’em hand in the  game here.