<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[polarizertech - Medium]]></title>
        <description><![CDATA[Polarizer Technologies - Medium]]></description>
        <link>https://medium.com/polarizertech?source=rss----406fe06f35c3---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>polarizertech - Medium</title>
            <link>https://medium.com/polarizertech?source=rss----406fe06f35c3---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 13:49:57 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/polarizertech" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[OpenSpec Release 1.0]]></title>
            <link>https://medium.com/polarizertech/openspec-release-1-0-66c6df08ad2f?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/66c6df08ad2f</guid>
            <category><![CDATA[spec-driven-development]]></category>
            <category><![CDATA[ai-coding-agent]]></category>
            <category><![CDATA[ai-coding]]></category>
            <category><![CDATA[openspec]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Sat, 14 Feb 2026 13:58:06 GMT</pubDate>
            <atom:updated>2026-02-14T13:58:06.448Z</atom:updated>
            <content:encoded><![CDATA[<h4>Changes in workflow, new commands and more</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3GNJExPCrt4aZQwt.jpg" /></figure><p><a href="https://intent-driven.dev/assets/blog/openspec-1-0-release/openspec-1-0-release-workflow.jpg">View the full-size workflow diagram →</a></p><p>OpenSpec 1.0 is <a href="https://github.com/Fission-AI/OpenSpec/releases/tag/v1.0.0">officially released</a>.</p><p>In an earlier post, I wrote about how the <a href="https://intent-driven.dev/blog/2025/11/09/spec-driven-development-openspec-source-truth/">OpenSpec workflow anchors development to specs as the source of truth</a>, ensuring that what gets built stays aligned with what was intended. This spec-anchored approach has been central to OpenSpec from the beginning.</p><p>In this post, let us look at some of the major changes that come with the 1.0 release.</p><h3>Explore Before You Build</h3><p>One of the most significant additions is the <strong>Explore Mode</strong>. Before diving into implementation, you can now use OpenSpec to think through ideas which require more clarity, investigate problems, and clarify requirements.</p><h3>Step-by-Step Generation</h3><p>OpenSpec 1.0 introduces a more deliberate artifact creation process. Instead of generating everything at once, you can now step through each artifact such as proposal.md, design.md, etc. one at a time.</p><p>This step-by-step approach helps improve the review process as each artifact can be checked before the next one is generated.</p><h3>Intent Verification</h3><p>Before archiving a completed change, OpenSpec now includes a verification step. This checks that the implementation actually matches what was specified in the change artifacts. It’s a final checkpoint that catches any intent alignment issues.</p><h3>Noteworthy mentions in 1.0 release</h3><p>The config.yaml file in OpenSpec 1.0 looks really interesting.</p><h3>Seamless Integrations</h3><p>OpenSpec’s config system makes it straightforward to integrate with external tools. For example, you can connect OpenSpec with Linear using MCP to automatically sync issues and track progress. I had <a href="https://intent-driven.dev/blog/2026/01/11/linear-mcp-openspec-sdd-workflow/">earlier achieved this by forking and modifying OpenSpec</a>, that may not be necessary anymore.</p><h3>Customizable Workflows</h3><p>Beyond integrations, config.yaml lets you tailor the OpenSpec workflow to your team&#39;s needs.</p><h3>Video Walkthrough</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FJrI-P64y7H8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DJrI-P64y7H8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FJrI-P64y7H8%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7e421d374e1b40ad7c4eaa3884d813d7/href">https://medium.com/media/7e421d374e1b40ad7c4eaa3884d813d7/href</a></iframe><p><em>Originally published at </em><a href="https://intent-driven.dev/blog/2026/01/26/openspec-1-0-release/"><em>https://intent-driven.dev</em></a><em> on January 26, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=66c6df08ad2f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/openspec-release-1-0-66c6df08ad2f">OpenSpec Release 1.0</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Which Spec-Driven Development Tool Should You Choose?]]></title>
            <link>https://medium.com/polarizertech/which-spec-driven-development-tool-should-you-choose-f8f65dc8ab9a?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/f8f65dc8ab9a</guid>
            <category><![CDATA[kiro]]></category>
            <category><![CDATA[openspec]]></category>
            <category><![CDATA[ai-coding]]></category>
            <category><![CDATA[spec-driven-development]]></category>
            <category><![CDATA[spec-kit]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Sat, 14 Feb 2026 13:51:31 GMT</pubDate>
            <atom:updated>2026-02-14T13:51:31.828Z</atom:updated>
            <content:encoded><![CDATA[<h4>The factors to consider before selecting an SDD tool</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GZ4V-05vIKy_vZjT.jpg" /></figure><p>Before selecting a tool for Spec-Driven Development (SDD) it is good to get a bearing on our workflow and the level of rigor our project demands. This post intends to provide a practical way of thinking through which tool to use.</p><h3>Context Engineering Approaches</h3><p>Before we jump into Spec-Driven Development, itself let us quickly look at how it differs from “Plan Mode”. This is a question I often get asked and thought I will start with that first. There are two ways to look at Context Engineering.</p><h3>Tactical (Plan-Mode)</h3><p><strong>What it is:</strong> Best for rapid problem-solving. We create a plan or to-do list to think through the solution, build it, and then discard the plan. The code is the only long-term asset. Now based on our preference for CLI vs IDE based tools, there are several choices. Here are some examples that I have used.</p><p><strong>Tools:</strong></p><ul><li><a href="https://claude.com/product/claude-code"><strong>Claude Code</strong></a><strong> (CLI)</strong>: Plan mode creates temporary implementation plans</li><li><a href="https://antigravity.google/"><strong>Antigravity</strong></a><strong> (IDE)</strong>: Implementation plans that guide development. Even though the plan appears in your IDE window it is not part of your repo.</li></ul><h3>Strategic (Spec-Driven)</h3><p><strong>What it is:</strong> Here the specification is a first-class citizen. It is as important as the implementation itself. Maybe even more important in comparison to the code itself (Theoretically, we can generate the code all over again if we have the spec). These specs are persistent and version controlled or stored through other means.</p><p>Again here, based on our preference for CLI vs IDE based approaches we have several choices.</p><p><strong>IDE</strong></p><ul><li><a href="https://kiro.dev/">Kiro</a></li></ul><p><strong>CLI</strong></p><ul><li><a href="https://openspec.dev/">OpenSpec</a></li><li><a href="https://github.com/github/spec-kit">SpecKit</a></li><li><a href="https://github.com/bmad-code-org/BMAD-METHOD">BMAD-Method</a></li></ul><h3>Other Considerations</h3><h3>1. Levels of “Spec-Driven”</h3><p>Not all of the above tools handle the relationship between spec and code the same way.</p><p><strong>Spec-First:</strong></p><ul><li><strong>Tools</strong>: <a href="https://kiro.dev/">Kiro</a>, <a href="https://github.com/github/spec-kit">SpecKit</a></li><li><strong>Philosophy</strong>: The purpose of the spec is to articulate intent. Over time, the code and spec might not be aligned.</li></ul><p><strong>Spec-Anchored:</strong></p><ul><li><strong>Tool</strong>: <a href="https://openspec.dev/">OpenSpec</a></li><li><strong>Philosophy</strong>: In addition to articulating intent, the spec remains aligned at all times with the implementation.</li></ul><p>For a deeper dive into the spec-anchored philosophy, see my LinkedIn post on <a href="https://www.linkedin.com/pulse/spec-driven-development-openspec-source-truth-hari-krishnan--obrfc/">Spec-Driven Development with OpenSpec: Source of Truth Specification</a>.</p><h3>2. Rigor vs. Speed</h3><p>How many steps do you actually want to follow?</p><p>More rigor is not always better, it depends on how much groundwork we have already done. If we already have stories in our familiar tools like Linear, GitHub boards, Jira, etc. then maybe better to choose a tool that works with smaller features. If we want to think through a solution from an overall nebulous idea, BMAD may be necessary.</p><h3>3. Legacy Code and Lock-in</h3><p><strong>Compatibility: Greenfield vs. Legacy</strong></p><ul><li><strong>Greenfield-friendly</strong>: Most tools work well with new projects where you can establish patterns from day one</li><li><strong>Legacy-specialized</strong>: <a href="https://openspec.dev/">OpenSpec</a> claims to be specifically designed to handle the complexity of existing codebases (brownfield and 0 to 1 projects)</li></ul><p><strong>Exit Strategy: Portability and Lock-in</strong> Since most of us are evaluating these tools, it may be a good idea to see if the approach allows being able to switch from one tool to another without context loss when we switch spec formats.</p><h3>Video Walkthrough</h3><p>For a visual explanation of this decision framework and tool landscape, watch this walkthrough:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FI0x01WZq1Zw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DI0x01WZq1Zw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FI0x01WZq1Zw%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/f5008bf3294daa4dcab334c85769f238/href">https://medium.com/media/f5008bf3294daa4dcab334c85769f238/href</a></iframe><h3>Conclusion</h3><p>Better not to overthink it, start with the tool that feels most aligned with your workflow, and adjust as you learn what works for your team.</p><p>Want to dive deeper into spec-driven development practices? Explore the <a href="https://intent-driven.dev/knowledge/">Knowledge Hub</a> on <a href="https://intent-driven.dev/">https://intent-driven.dev</a> for detailed guides on <a href="https://intent-driven.dev/knowledge/workflows/">workflows</a>, <a href="https://intent-driven.dev/knowledge/best-practices/">best practices</a>, and <a href="https://intent-driven.dev/knowledge/openspec/">OpenSpec</a>.</p><p><em>Originally published at </em><a href="https://intent-driven.dev/blog/2025/12/26/choosing-spec-driven-development-tool/"><em>https://intent-driven.dev</em></a><em> on December 26, 2025.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8f65dc8ab9a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/which-spec-driven-development-tool-should-you-choose-f8f65dc8ab9a">Which Spec-Driven Development Tool Should You Choose?</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Vibe Coding vs Spec-Driven Development]]></title>
            <link>https://medium.com/polarizertech/vibe-coding-vs-spec-driven-development-74e6ecc52092?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/74e6ecc52092</guid>
            <category><![CDATA[spec-driven-development]]></category>
            <category><![CDATA[ai-coding]]></category>
            <category><![CDATA[harness-engineering]]></category>
            <category><![CDATA[vibe-coding]]></category>
            <category><![CDATA[context-engineering]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Wed, 17 Dec 2025 03:20:56 GMT</pubDate>
            <atom:updated>2025-12-17T03:20:52.937Z</atom:updated>
            <content:encoded><![CDATA[<h4>Implementation Deviation and Context Engineering</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7QJQByv2t_5XVZVWbqvy6A.jpeg" /><figcaption>Context-Engineering — Spec-Driven Development Workflow</figcaption></figure><h3>Introduction</h3><p>One of the most common ways to critique vibe coding is by pointing to technical limitations such as context length, token limits, or LLM “amnesia.” While those are real constraints, the deeper issue IMHO is the workflow.</p><p>In real life, we rarely expect a human counterpart to take a single-line request or a short PRD and return a perfectly working solution. We expect clarifying questions, intermediate artifacts, reviews, and course correction which can be expensive. Over time, engineering practices such as Behaviour-Driven Development emerged precisely to help teams articulate intent clearly before implementation by promoting better dialogue between stakeholders.</p><p>When working with AI coding agents, the same principle applies. If we cannot articulate our intent clearly to ourselves first, what eventually gets built will almost certainly deviate from what we originally wanted, regardless of how capable the model is.</p><p>This article looks at the fundamental workflow differences between vibe coding and spec-driven development, and how those workflows either amplify or reduce intent-to-implementation deviation.</p><h3>The Vibe Coding Lifecycle</h3><p>In a typical vibe coding flow, we describe what we want in a single prompt, review the generated code, provide feedback, and iterate until we are satisfied. It is fast, flexible, and requires very little upfront planning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n2kwgRwohTj-tQQRyvtRyw.jpeg" /><figcaption>Vibe Coding Workflow — <em>Iterative prompt-feedback cycles with growing intent deviation</em></figcaption></figure><h3>How Vibe Coding Works</h3><p>The vibe coding workflow usually follows a linear loop:</p><ol><li><strong>Single-line prompt</strong> describing what needs to be built</li><li><strong>General-purpose agent</strong> that interprets the prompt and fills in gaps</li><li><strong>Code generation</strong> based on those assumptions</li><li><strong>Review and feedback</strong> from the human</li><li><strong>Iteration</strong> using the updated prompt or follow-up instructions</li></ol><p>This feels natural, especially because chat-based interfaces encourage getting something working quickly and using that output as the basis for further refinement. The workflow optimizes for speed and momentum.</p><h3>Implicit Assumptions Accumulate</h3><p>The core problem emerges as iterations progress.</p><p>Each prompt and correction focuses on the <em>current</em> concern. To satisfy new feedback, the agent often revises or overrides earlier decisions. Constraints that were previously implied or loosely stated are weakened or forgotten.</p><p>Initially, intent deviation may reduce as obvious gaps are fixed based on feedback. Over time, however, corrections become fragile. Changes in one area introduce regressions in another. The human ends up in a sustained negotiation loop with the agent, repeatedly restating intent in different ways to keep the output on track.</p><p>This is not a model failure, it is a workflow limitation where context is not managed effectively.</p><h3>The Spec-Driven Development Workflow</h3><p>Spec-driven development takes a fundamentally different approach. Instead of starting with implementation, it focuses on establishing clear intent <em>before</em> asking the agent to write code.</p><p>By breaking work into explicit phases with review gates, the spec-driven workflow makes intent articulation deliberate and verifiable, significantly reducing downstream deviation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7QJQByv2t_5XVZVWbqvy6A.jpeg" /><figcaption><em>Spec-Driven Development: Four-phase workflow with review gates maintaining intent alignment</em></figcaption></figure><h3>The Four Phases of Spec-Driven Development</h3><p>Each tool may have a few more or a few less, however overall these aspects are usually covered.</p><h4>Phase 1: What (Specify / Propose / Requirements)</h4><p>This phase focuses on defining <strong>what</strong> needs to be built:</p><ul><li>Feature requirements and acceptance criteria</li><li>User needs and business goals</li><li>Scope, boundaries, and non-goals</li><li>Success metriccs</li></ul><h4>Phase 2: How (Design / Plan)</h4><p>Once intent is clear, the next phase addresses <strong>how</strong> it will be implemented:</p><ul><li>Architecture and technical approach</li><li>Technology and pattern choices</li><li>Data models, APIs, and interfaces</li><li>Risks and dependencies</li></ul><h4>Phase 3: Task (Granular Steps with Checks)</h4><p>With design approved, work is decomposed into concrete tasks:</p><ul><li>Small, verifiable work items</li><li>Clear validation criteria per task</li><li>Explicit dependencies and ordering</li><li>Testing and verification strategy</li></ul><p>At this point, task ordering and parallelization opportunities can be reviewed. Tasks may also be delegated to sub-agents, reducing context burden in the primary thread while keeping intent anchored.</p><h4>Phase 4: Build (Implementation)</h4><p>Only after intent, design, and tasks are validated does implementation begin:</p><ul><li>Tasks executed sequentially or in parallel</li><li>Validation against acceptance criteria</li><li>Automated tests run</li><li>Implementation reviewed against specs</li></ul><p><strong>Output:</strong> Working code that matches documented intent.</p><h3>Conversation Matters</h3><p>Spec-Driven Development is sometimes criticized as an anti-pattern because it appears to conflict with <em>“Working software over comprehensive documentation”</em> from the Agile Manifesto. This criticism often stems from viewing specs as artifacts rather than as a mechanism for intent negotiation.</p><p>To give you an analogy, Behaviour-Driven Development was never about Gherkin syntax for its own sake. It was about enabling collaboration between business and technology through structured conversation. That aligns with <em>“Collaboration over contract negotiation.”</em></p><p>Similarly, SDD facilitates structured conversation between humans and coding agents. Specs and plans are not the goal, they are scaffolding that helps clarify and stabilize intent.</p><p>Tooling quality and verbosity vary, but the underlying purpose remains the same, ensuring that intent is explicit, reviewable, and durable across iterations.</p><h3>Watch: Deeper Dive into Vibe Coding vs Spec-Driven Development</h3><p>For a comprehensive walkthrough of these workflows and their practical implications, watch this video:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FVvzoAgtjF6w%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DVvzoAgtjF6w&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVvzoAgtjF6w%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/22e0f029194b9250d3c1b22f19c356f7/href">https://medium.com/media/22e0f029194b9250d3c1b22f19c356f7/href</a></iframe><h3>Conclusion</h3><p>Vibe coding and spec-driven development represent two fundamentally different philosophies for working with AI coding agents.</p><p><strong>Vibe coding optimizes for speed.</strong> It favors rapid iteration, minimal planning, and flexibility. It works well for prototypes, scripts, and exploratory work.</p><p><strong>Spec-driven development optimizes for intent alignment.</strong> It emphasizes clarity, validation, and verifiable outcomes. This makes it better suited for production systems, team environments, and long-lived codebases, and, over time, even for smaller prototypes.</p><p>The critical differentiator is <strong>intent management</strong>.</p><p>Vibe coding accepts deviation as a cost of speed. Spec-driven development reduces deviation by introducing structure, review gates, and explicit intent articulation.</p><p>If intent matters beyond the next prompt, structure wins.</p><h3>Ready to Learn More?</h3><p>Explore our <a href="https://intent-driven.dev/knowledge/">Knowledge Hub</a> for in-depth guides on:</p><ul><li><a href="https://intent-driven.dev/knowledge/">Spec-Driven Development fundamentals</a></li><li><a href="https://intent-driven.dev/knowledge/openspec/">OpenSpec framework</a></li><li><a href="https://intent-driven.dev/knowledge/workflows/">Workflow best practices</a></li><li><a href="https://intent-driven.dev/knowledge/best-practices/">Tool ecosystem</a></li></ul><p><strong>Related viewing:</strong> <a href="https://www.youtube.com/watch?v=rmvDxxNubIg">No Vibes Allowed: Solving Hard Problems in Complex Codebases — Dex Horthy, HumanLayer</a></p><p><a href="https://intent-driven.dev/blog/2025/12/15/vibe-coding-vs-spec-driven-development/"><strong>Originally published on intent-driven.dev</strong></a></p><p>Learn more about Spec-Driven Development on <a href="https://intent-driven.dev/"><strong>intent-driven.dev</strong></a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74e6ecc52092" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/vibe-coding-vs-spec-driven-development-74e6ecc52092">Vibe Coding vs Spec-Driven Development</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spec-Driven Development: OpenSpec]]></title>
            <link>https://medium.com/polarizertech/spec-driven-development-openspec-dbc5efe1d8ce?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/dbc5efe1d8ce</guid>
            <category><![CDATA[openspec]]></category>
            <category><![CDATA[kiro]]></category>
            <category><![CDATA[spec-driven-development]]></category>
            <category><![CDATA[spec-kit]]></category>
            <category><![CDATA[intent-driven-development]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Fri, 21 Nov 2025 15:52:36 GMT</pubDate>
            <atom:updated>2026-02-22T12:51:35.155Z</atom:updated>
            <content:encoded><![CDATA[<h4>OpenSpec Workflow Diagram with source of truth specification</h4><p>In one of my <a href="https://blog.harikrishnan.io/2025-10-22/spec-driven-development-tools">previous articles</a> I mentioned that I have been experimenting with several Spec-Driven Development (SDD) tools, both to evaluate them and to use them in my own work. Among these, <a href="https://openspec.dev/">OpenSpec</a> has increasingly become one of my preferred SDD tools. It introduces an interesting idea of having a single top level “source of truth” spec. In this article I will look at the workflow, advantages of the “source of truth” spec and other observations about OpenSpec.</p><h4>OpenSpec — Change Workflow</h4><figure><img alt="OpenSpec Change Workflow Diagram for Spec-Driven Development" src="https://cdn-images-1.medium.com/max/1024/0*4hWOCz0zveAdAqOR.jpg" /><figcaption>OpenSpec Change Workflow • harikrishnan.io • CC BY 4.0 • <a href="https://creativecommons.org/licenses/by/4.0/">https://creativecommons.org/licenses/by/4.0/</a></figcaption></figure><h4>Why the “Source of Truth” Spec Matters?</h4><p>To understand its importance, it helps to reflect on some of the difficulties I faced with tools like <a href="https://github.com/github/spec-kit">Spec-Kit</a> and <a href="https://kiro.dev/">Kiro</a> in this context.</p><p>Without a top-level spec, feature-level specs are often fragmented across subfolders within the “specs” directory. This fragmentation introduces below issues:</p><ol><li><strong>Fragmented Understanding</strong> — The overall intent of the system becomes scattered across multiple files, making it difficult to maintain a cohesive picture.</li><li><strong>Evolving specs</strong> — There are several questions and confusions that seem to arise in the context of spec evolution which has been well discussed here — <a href="https://github.com/github/spec-kit/discussions/152">Evolving specs #152</a>.</li><li><strong>Unintended Interactions</strong> — Every new feature added risks unintentionally affecting existing behaviour, since there is no unified view for validation. (I had attempted to address this to an extent with an optional “/cross-feature” command to <a href="https://www.linkedin.com/pulse/spec-driven-development-analysing-across-features-hari-krishnan--8cryc">analyse across features</a>).</li></ol><p><a href="https://intent-driven.dev/blog/2025/11/09/spec-driven-development-openspec-source-truth/"><strong>Originally published on intent-driven.dev.</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dbc5efe1d8ce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/spec-driven-development-openspec-dbc5efe1d8ce">Spec-Driven Development: OpenSpec</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Specmatic vs WireMock]]></title>
            <link>https://medium.com/polarizertech/specmatic-vs-wiremock-bff74c68498f?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/bff74c68498f</guid>
            <category><![CDATA[wiremock]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[mock]]></category>
            <category><![CDATA[open-api]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Wed, 30 Nov 2022 06:03:35 GMT</pubDate>
            <atom:updated>2022-11-30T06:16:46.065Z</atom:updated>
            <content:encoded><![CDATA[<p>This is the second post in our <a href="https://specmatic.in/category/blog/comparisons/#gsc.tab=0">series</a> where we compare Specmatic with tools that have some overlap in terms of capabilities. In our <a href="https://medium.com/polarizertech/specmatic-vs-pact-io-and-pactflow-io-572c7cc22212">previous post</a> we compared Specmatic and Pact. In this post we will be looking at <a href="https://wiremock.org/">WireMock</a>.</p><p>We often need to mock APIs (both internal and external) to isolate the system under test or development so that we can make progress independent of dependencies. <a href="https://wiremock.org/">WireMock</a> is a great tool if your goal is to just mock APIs. However API mocking is only effective if the mocks are truly representative of the provider / services they are emulating. Deviations between mocks and providers can lead to integration issues much later in the development cycle. In order to avoid such issues it is important to keep in mind that selecting an API mocking tool is not an isolated decision. It has to be in line with your overall microservices development, testing and deployment goals.</p><p><a href="https://wiremock.org/">WireMock</a> is an <a href="https://wiremock.org/docs/">API Mocking</a> tool and <a href="https://specmatic.in/">Specmatic</a> is a <a href="https://specmatic.in/contract_driven_development.html">Contract Driven Development</a> tool that leverages API mocking (<a href="https://specmatic.in/#contract-as-stub">Smart Mocks)</a> to identify contract compatibility issues in Consumers of an API. So <strong>this is not an apples to apples comparison</strong>. We are only going to look at a subset of capabilities where there are overlaps between Specmatic and WireMock. However if you believe we have missed any aspects in this comparison, please do leave us a comment.</p><p>Here is my blog post comparing <a href="https://specmatic.in/">Specmatic</a> with <a href="https://wiremock.org/">WireMock</a> in detail.</p><p><a href="https://specmatic.in/blog/comparisons/comparison-specmatic-vs-wiremock">Comparison: Specmatic vs WireMock - Specmatic</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bff74c68498f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/specmatic-vs-wiremock-bff74c68498f">Specmatic vs WireMock</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Specmatic vs Pact and Pactflow]]></title>
            <link>https://medium.com/polarizertech/specmatic-vs-pact-io-and-pactflow-io-572c7cc22212?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/572c7cc22212</guid>
            <category><![CDATA[contract-test]]></category>
            <category><![CDATA[contract-testing]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[pact]]></category>
            <category><![CDATA[open-api]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Fri, 25 Nov 2022 09:28:54 GMT</pubDate>
            <atom:updated>2022-11-28T04:45:20.746Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<p>We set out to build <a href="https://specmatic.in/">Specmatic</a> which embodies Contract Driven Development (CDD) because we were unable to find a tool that fits our bill (leveraging <a href="https://specmatic.in/#executable-contracts">API Specifications as Executable Contracts</a>). The goal of <a href="https://www.linkedin.com/feed/hashtag/?keywords=contractdrivendevelopment&amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6999630990260269056">#ContractDrivenDevelopment</a> and <a href="https://specmatic.in/">Specmatic</a> is to remove the pain of integration testing while building #microservices.</p><p>The key point here being API Specifications (such as <a href="https://www.openapis.org/">OpenApi</a>) themselves are leveraged as API Contracts with <a href="https://specmatic.in/">Specmatic</a>. This is significantly different from Consumer Driven Contract Testing (Example: <a href="https://pact.io/">Pact.io</a>) where the API Contracts and API Specifications serve separate purposes. This difference in approach (CDD vs Consumer Driven Contract Testing, etc.) is quite a deep topic. So we put together a comprehensive comparison chart.</p><p>Here is my blog post comparing <a href="https://specmatic.in/">Specmatic</a> with <a href="https://pact.io/">Pact.io</a> and <a href="https://pactflow.io/">Pactflow.io</a> in detail.</p><p><a href="https://specmatic.in/blog/comparisons/specmatic-vs-pact-io-and-pactflow-io/#gsc.tab=0">Comparison: Specmatic vs Pact.io and Pactflow.io - Specmatic</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=572c7cc22212" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/specmatic-vs-pact-io-and-pactflow-io-572c7cc22212">Specmatic vs Pact and Pactflow</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Refactoring if-else: Either and FlatMap]]></title>
            <link>https://medium.com/polarizertech/refactoring-if-else-either-and-flatmap-4f1ca9076664?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/4f1ca9076664</guid>
            <category><![CDATA[monads]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Tue, 30 Jun 2020 04:16:38 GMT</pubDate>
            <atom:updated>2020-06-30T04:16:18.786Z</atom:updated>
            <content:encoded><![CDATA[<h4>Railway Oriented Programming with Kotlin and Arrow</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rxabsGdDF_HhzsP6KpfGzg.jpeg" /><figcaption>Attribution: <a href="https://commons.wikimedia.org/wiki/File:Thomas_%26_Friends_at_Drusillas_Park.jpg">Dzp / CC BY-SA (https://creativecommons.org/licenses/by-sa/3.0)</a></figcaption></figure><p>This post expands on the concepts I had covered in my earlier post about <a href="https://medium.com/polarizertech/railway-oriented-programming-dd74dbf0dfae">“Refactoring to Railway Oriented Programming”</a>. Other than being a great approach to handling errors, in my experience, <a href="https://fsharpforfunandprofit.com/rop/">Railway Oriented Programming</a> also serves as a great use case for explaining the need for Monads to first timers. While understanding Monads is hard enough, trying to <a href="https://arrow-kt.io/docs/0.10/patterns/monads/#the-fallacy-of-monad-tutorials">explain it to others is a lot harder</a>. However, this post is not a tutorial on Monads, instead it just explains the concepts in the context of ROP.</p><p>We will be leveraging <a href="https://arrow-kt.io/">Arrow-kt</a> library and specifically the Either monad, FlatMap and Fold operators to refactor below snippet.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8a943ebaf533d8c0f8825b21305c5e8b/href">https://medium.com/media/8a943ebaf533d8c0f8825b21305c5e8b/href</a></iframe><h3>Step-1: The “Either” Monad</h3><p>All we are going to do in this step is to extract the code in each “if ” condition to methods. More importantly these methods should return an “Either.Right” or “Either.Left”. Right is returned on success and Left is returned on Error.</p><pre>fun matchUrl(anotherRequest: HttpRequest): Either&lt;String, HttpRequest&gt; {<br>    if (this.url != anotherRequest.url)<br>        return <strong>Either.Left</strong>(&quot;URL did not match. ${this.url} not equal to ${anotherRequest.url}&quot;)<br>    return <strong>Either.Right</strong>(anotherRequest)<br>}<br><br>fun matchMethod(anotherRequest: HttpRequest): Either&lt;String, HttpRequest&gt; {<br>    if (this.method != anotherRequest.method)<br>        return <strong>Either.Left</strong>(&quot;Method did not match. ${this.method} not equal to ${anotherRequest.method}&quot;)<br>    return <strong>Either.Right</strong>(anotherRequest)<br>}<br><br>fun matchBody(anotherRequest: HttpRequest): Either&lt;String, HttpRequest&gt; {<br>    if (this.body != anotherRequest.body)<br>        return <strong>Either.Left</strong>(&quot;Body did not match. ${this.method} not equal to ${anotherRequest.method}&quot;)<br>    return <strong>Either.Right</strong>(anotherRequest)<br>}</pre><h3>Step-2: The “FlatMap” Operator</h3><p>Either is a Monad, or in over simplified terms a <strong>wrapper around raw values</strong> that allows a <strong>bind transformation</strong>. Let us understand this in detail.</p><ol><li><strong>Wrapper around raw values</strong>. Example: In the above step, we are wrapping the error message String in “Either.Left” and the HttpRequest in “Either.Right” respectively.</li><li><strong>Bind transformation</strong>. The bind operator that we will be leveraging on Either monad is <strong>FlatMap</strong>. FlatMap takes a function as an argument and applies it on the wrapped value of the Either Monad and returns a Monad. The function that FlatMap takes as the argument, should accept the unwrapped value of the the Either Monad as the argument and return another Monad. Example: We have written such functions in Step 1.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9Hjvspp6-1xGcGP_Oc751g.png" /></figure><p>Why all these rules? Because now we will be able to sequence method calls as shown below.</p><pre>matchUrl(request).flatMap { matchBody(it) }.flatMap { match... }...</pre><p>The matchUrl method returns an Either monad. The flatMap applies matchBody to the unwrapped value (“it”) if the Either monad. Now matchBody returns and Either monad and flatMap applies the next function and so on.</p><p>This all sounds good when the matchUrl returns “Either.Right” and then matchBody also returns an “Either.Right” and so on because the wrapped value in “Either.Right” is the HttpRequest which each of the subsequent functions take as argument. However what if matchUrl returns “Eight.Left”? The wrapped value is a String. What do we do?</p><p><strong>Either Monad is </strong><a href="https://arrow-kt.io/docs/0.10/apidocs/arrow-core-data/arrow.core/-either/#either-vs-validated"><strong>“Right-Biased”</strong></a></p><p><strong>What is right bias?</strong> I earlier mentioned that the bind operator applies the function on the wrapped value. However, Either can have two possible values (Classified as Sum Type in <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">ADT</a>). Which value should we apply the function on? This is why flatMap in Either only applies the function on the Right.</p><p><strong>What about the errors</strong>? We still need to stop the execution of other functions when a function returns error. On Left, the flatMap in Either short circuits the execution and does not continue. Example: When matchUrl returns Left, matchMethod and matchBody are not invoked.</p><p>I now need to be able to extract the error message when there is a problem and I want the HttpRequest when it is successfully matched.</p><p>This is where <strong>“Fold”</strong> operator is necessary. “Either.Fold” takes two functions, ifLeft to apply when the overall result is “Either.Left”, ifRight to apply when the overall result is “Either.Right”. It is also able to access the wrapped value, error String when “Either.Left” and HttpRequest when “Either.Right”.</p><p>With <strong>flatMap</strong> and <strong>fold</strong> we can now solve this refactoring.</p><pre>private fun matchAnotherRequest(anotherRequest: HttpRequest) =<br>    matchUrl(anotherRequest).flatMap {<br>        matchMethod(it)<br>    }.flatMap {<br>        matchBody(it)<br>    }.fold({ Failure(it) }, { Success(it) })</pre><h3>Step-3: Extracting “then” and “handleError”</h3><p>This step is optional. To improve readability I have formatted above code to keep all the method names on the left. All the machinery has been moved to the right.</p><pre>matchUrl(anotherRequest)    .<em>flatMap </em><strong>{<br></strong>matchMethod(<strong>it</strong>)             <strong>}</strong>.<em>flatMap </em><strong>{<br></strong>matchBody(<strong>it</strong>)               <strong>}</strong>.fold(<br>                                <strong>{ </strong>Failure(<strong>it</strong>) <strong>}</strong>, <strong>{ </strong>Success(<strong>it</strong>) <strong>}<br>                            </strong>)</pre><p>This code on the right can be moved to its own place. The flatmap related code can move to “then” and fold related code can move to “handleError”.</p><p>Putting it all together.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cea7691182cbabb0eca39968b2e99027/href">https://medium.com/media/cea7691182cbabb0eca39968b2e99027/href</a></iframe><p>The code is available on <a href="https://github.com/harikrishnan83/RailwayOrientedProgramming">GitHub</a>.</p><p>Related Reading List:</p><ol><li><a href="https://hackernoon.com/kotlin-functors-applicatives-and-monads-in-pictures-part-1-3-c47a1b1ce251">Kotlin Functors, Applicatives, And Monads in Pictures</a></li><li><a href="https://fsharpforfunandprofit.com/posts/monoids-without-tears/">Monoids without Tears</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4f1ca9076664" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/refactoring-if-else-either-and-flatmap-4f1ca9076664">Refactoring if-else: Either and FlatMap</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Railway Oriented Programming]]></title>
            <link>https://medium.com/polarizertech/railway-oriented-programming-dd74dbf0dfae?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/dd74dbf0dfae</guid>
            <category><![CDATA[refactoring]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[procedural-programming]]></category>
            <category><![CDATA[function-composition]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Wed, 26 Feb 2020 05:05:14 GMT</pubDate>
            <atom:updated>2020-06-20T14:23:25.934Z</atom:updated>
            <content:encoded><![CDATA[<h4>Refactoring procedural code to ROP in Kotlin</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ldiLIsZRQX4yW-GaJKPxLw.jpeg" /><figcaption>Attribution: I, Daniel Schwen / CC BY-SA (<a href="http://creativecommons.org/licenses/by-sa/3.0/">http://creativecommons.org/licenses/by-sa/3.0/</a>)</figcaption></figure><p>Procedural code can become hard to read, hard to test and more importantly hard to maintain. Sometimes error conditions and “not so happy path”s tend to govern the codebase to a large extent. We are left searching for the happy path in such applications. The usual approach I may have taken to refactoring long and highly conditional code would be to go with OOP to decompose it into classes and leverage polymorphism or patterns to remove if conditions. However, are there other approaches?</p><p><a href="https://fsharpforfunandprofit.com/rop/">Railway Oriented Programming</a> (highly recommended article) is an approach that applies functional programming techniques to keep code focused on the happy path without sacrificing error handling. This post is about the steps I took to refactor procedural code to functional paradigm.</p><p>It may not help to show procedural code and directly jump to the functional equivalent. What will be interesting is to trace the steps we need to take to refactor our code. So we will be going over each incremental step to refactor a method written in procedural style to ROP.</p><p>This post assumes little to no Functional Programming knowledge. We will only briefly touch function composition.</p><h3>Sample Problem</h3><p><strong>Requirement:</strong> Write a “matches” function in HttpRequest which allows us to verify if it matches another instance.</p><ol><li>Input: HttpRequest A and Http Request B</li><li>Output: Whether A and B match and if they do not match, return error message that mentions which part did not match.</li></ol><p>The request parts should be matched in the order given below</p><blockquote>matchUrl -&gt; matchMethod -&gt; matchBody</blockquote><p>Example: If the method did not match, it should return below error immediately. The body should not be matched.</p><blockquote>Method did not match. GET not equal to POST</blockquote><p>If everything matches we should get a success result.</p><h4>Procedural</h4><p>Good old procedural code with a generous serving of “if” conditions.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8a943ebaf533d8c0f8825b21305c5e8b/href">https://medium.com/media/8a943ebaf533d8c0f8825b21305c5e8b/href</a></iframe><p><strong>Observations</strong></p><ol><li>Even with the “guard clause” style programming the error handling code is becoming quite a distraction.</li><li>At this point it takes some time and effort to glean out the happy path of this code which we mentioned earlier.</li><li>Such code easily decays into chaos if we need to add exception handling and more if conditions.</li></ol><h3>Refactoring to ROP</h3><h4>Step 1: Method Extraction</h4><p>The code is currently just a long list of “if”conditions. Let us start by extracting methods that embody major parts of this code, matching url, matching method and matching body.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b88400b74830b8f75ba017ce72c9c133/href">https://medium.com/media/b88400b74830b8f75ba017ce72c9c133/href</a></iframe><p><strong>Observations</strong></p><p>While this code looks a little nicer, it is hardly a picture of the happy path.</p><ol><li>The when blocks are more or less just if conditions. We are also having to check the result of each step.</li><li>Repetition of returning on Failure.</li></ol><h4>Step 2: Setting up the pipeline</h4><p>If you stare at the code long enough, you would have noticed that all these functions (matchUrl, matchMethod, matchBody) are very similar in what they accept as parameters and what they return as result.</p><ol><li>Argument: HttpRequest</li><li>Return: Result.Success or Failure</li></ol><p>We will be able to build a pipeline of methods if we return the HttpRequest on Success so that it can be passed as argument to the next method.</p><p>So going by this requirement (highlighted in bold) we need to make matchUrl, matchMethod etc. return the HttpRequest when the matching is successful, so that we can pass it to the next function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1dd21fca49ff6aed89001c0ad12530ca/href">https://medium.com/media/1dd21fca49ff6aed89001c0ad12530ca/href</a></iframe><p><strong>Observations</strong></p><p>The code is hard to read because we have to deal with “return on failure”. The HttpRequest inside Success has to be extracted and passed to next method.</p><h4>Step 3: Extracting the Error Handling</h4><p>We need a way to extract “return on failure” and on success, the code that extracts HttpRequest from Result.Success to a separate function to avoid repeating ourselves.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/db8efbbe05e0afdf9b88e7333673aede/href">https://medium.com/media/db8efbbe05e0afdf9b88e7333673aede/href</a></iframe><p><strong>Explanation</strong></p><ol><li><strong>“then”</strong> is handling “return on Failure” — In line number 9 when the result is Success, we are calling “f” with this.message (HttpRequest). Here “f” is function that needs to be called next. Example: matchMethod is the “f” to the result of matchUrl. On error we just wrap the errorMessage in a Failure and return.</li><li><strong>“pipeTo”</strong> is starting the series of functions by passing the Http request to matchUrl. To begin the pipe we call pipeTo which wraps the “anotherHttpRequest” as a Success and sends it to “then”. “then” realises that this is a Success, extracts the httpRequest inside the Success and calls matchUrl with it.</li><li><strong>“error”</strong> is called when any of the functions matchUrl, matchMethod or matchBody (these functions can be thought of as junctions) return Failure. This behaves like the switch in the railway track and immediately moves execution to error when any of the junctions return Failure.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rea3_0Dr2_WxKzzPP8piow.png" /></figure><p>Kotlin infix helps us call the functions without “.” or parentheses.</p><h3>Recap</h3><ol><li>Method Extraction — extract major code sections as functions</li><li>Setting up the pipeline — refactor these functions to return the parameter that they take in as input</li><li>Extracting the Error Handling — compose these functions such that error handling is extracted to the ROP code</li></ol><p>There are more ROP constructs that you can experiment with once you have got the basics.</p><p>The code is available on <a href="https://github.com/harikrishnan83/RailwayOrientedProgramming">GitHub</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd74dbf0dfae" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/railway-oriented-programming-dd74dbf0dfae">Railway Oriented Programming</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Blue-Green Deployment Nuances]]></title>
            <link>https://medium.com/polarizertech/blue-green-deployment-nuances-38cf52318814?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/38cf52318814</guid>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Fri, 19 Jul 2019 04:21:51 GMT</pubDate>
            <atom:updated>2019-07-19T04:15:54.986Z</atom:updated>
            <content:encoded><![CDATA[<h4>MicroServices and Polyglot deployments</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uoQhO2lKiAh9q1d_yw_XNQ.jpeg" /><figcaption>Attribution: Stephen Goodwin [CC BY-SA 4.0 (<a href="https://creativecommons.org/licenses/by-sa/4.0">https://creativecommons.org/licenses/by-sa/4.0</a>)]</figcaption></figure><p>If we already have a mature Blue Green deployment setup, it is better to stick with it. However if we are going from having downtime based deployments to zero downtime deployment then it may be important to consider below points before you decide if Blue-Green is the right fit.</p><h3>Cost</h3><p>It is expensive to maintain two complete production environments. In its most basic version your infrastructure cost is double.</p><p>We can save cost by standing up green infrastructure just in time for a release and then tear down the blue after you switch to green. If you can do this you will also avoid <a href="https://martinfowler.com/bliki/SnowflakeServer.html">Snowflake</a> servers in the process. However consider additional infra automation cost.</p><p>An application has to be loosing significant business during downtimes to justify the cost.</p><h3>Zero downtime</h3><p>It depends. Even under the best scenarios, we will only have read availability. In any OLTP system we have to put the application in read only mode for some time to allow data to migrate over to green infrastructure before we can commence testing and then switch.</p><p>So technically it is a good idea to still plan a release when there is low traffic. Sometimes this may not sit well with business stakeholders when there is a blip in availability after all the spending.</p><h3>Database</h3><p>Strictly speaking we need to have two Database instances, a blue and a green. Even here we have put the application in readonly mode as mentioned above. There are some teams that perform Blue-Green deployments with a single logical database unit. In these cases we may even have to take a write availability downtime when we are applying DDLs on the shared DB.</p><h3>Rollback</h3><p>This can happen. Not all verifications result in a green signal to switch. Any errors caught in the verification phase is still good. You will not have accumulated any data or exposed your features to users. Just call off switching.</p><p>However once we switch to Green instances, then the switch back to the Blue environment may not be as simple as it appears.</p><p>Any data accumulated in the new release should be retained even after the flip. Also after a rollback when we deploy another release with the fixes this data that was collected by the erroneous release may need some correction.</p><p>In such scenarios, Roll-forward (Deploy another release with the fixes to Blue environment and switch over. Even if you cannot fix it, disable any broken features and cut a release) may be a better option.</p><p>In a Monolithic application or an application with a small number of Monolithic services, we usually have to stick with a uniform deployment strategy and have to think long and hard to choose the best fit.</p><p>With MicroServices, just like how we can choose language and stack for each service, we can also choose deployment strategies. Expensive strategies such as Blue-Green can be reserved for critical services. Less important services can still take a downtime and deploy.</p><p>Features which need to be released based on user cohorts can go through Canary releases. We can limit sticky sessions only to those services.</p><p>Rolling deployments are handy when you may want to deploy without any perceived downtime in a cost effective manner.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=38cf52318814" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/blue-green-deployment-nuances-38cf52318814">Blue-Green Deployment Nuances</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Inside Out vs Outside In]]></title>
            <link>https://medium.com/polarizertech/inside-out-vs-outside-in-fcf56919a512?source=rss----406fe06f35c3---4</link>
            <guid isPermaLink="false">https://medium.com/p/fcf56919a512</guid>
            <category><![CDATA[kanban]]></category>
            <category><![CDATA[application-development]]></category>
            <category><![CDATA[lean]]></category>
            <category><![CDATA[programming-paradigms]]></category>
            <category><![CDATA[clean-code]]></category>
            <dc:creator><![CDATA[Hari Krishnan]]></dc:creator>
            <pubDate>Tue, 02 Jul 2019 04:57:20 GMT</pubDate>
            <atom:updated>2019-07-13T21:08:36.354Z</atom:updated>
            <content:encoded><![CDATA[<h4>Starting with the DB/Backend vs Starting with the UI/User</h4><p>As a Developer, it is useful to have a repertoire of <a href="https://opensource.com/life/16/6/what-cognitive-linguistics-can-teach-developers">metaphors</a> to better articulate our thoughts. This post is about a parallel in supply chain management I thought was useful to me in explaining my approach to implementing features both to myself and to others.</p><p>At a high level there are two ways you could implement a feature.</p><p><strong>Inside Out/Backend First approach</strong> — Begin with database design. And then the backend classes (read domain) and services. UI is usually the last bit to get built.</p><p><strong>Outside In/UI first approach</strong> — Like the name suggests, we start with UI, then build the APIs and then the DB schema.</p><p>This can look like a matter of preference at the surface. However we can try and explain which approach is better with some theoretical backing.</p><p>Let us look at how each approach sequences the tasks.</p><p><strong>Inside Out/Database First approach</strong></p><ol><li>Database — Build schema based on the feature.</li><li>Domain — Build abstraction over schema</li><li>Services — Build functionality on domain</li><li>API — Expose functionality</li><li>UI- Build UI with API</li></ol><p>This is typical of a “Push Strategy” where we forecast demand (read demand as in “Demand and Supply”). The demand here being what the UI needs.</p><p><strong>Outside In/UI first approach</strong></p><ol><li>UI — Build UI with API stub</li><li>API — Build API that satisfies the stub in above step. API itself now depends on Stubbed out Services.</li><li>Services — Build Services that satisfy the stub in above step. Stub out Domain and DB</li><li>Domain and DB — Build Domain and DB to satisfy the stub in above step</li></ol><p>This is a “Pull Strategy” where we generate demand. See how UI creates the demand for what it needs from the API. And the API does just enough to satisfy the demand of the UI.</p><h3>Push vs Pull</h3><p>A complete comparison is out of scope of this post.</p><p>In short, push strategy is suitable when the problem at hand is well known and so is easily predictable. If you have already built the same feature a 100 times over, you have historical data and you know exactly what fields to include in the DB, what domain objects are involved etc. However this is hardly the case in Software. If you are building a feature more than twice, you extract a re-usable component.</p><p>Pull strategy is suitable when there is no historical data. So prediction errors can be large. UX is evolving fast and the experiences we are building requires a complete re-thinking of how we build backends.</p><h3>Inventory and shortage</h3><p>Inside Out approach, as already mentioned requires us to forecast/predict what we will need. For example: We are architecting the DB schema to fit the overall feature at a point in time when we have not built the UI.</p><p>With no historical data, forecasting errors can occur.</p><ol><li><strong>Shortage:</strong> The schema does have all the necessary fields the UI needs. This leads to rework. While rework is bad, shortage is a visible problem and we know how much time and effort was wasted. What is worse is how we usually handle shortage.</li><li><strong>Inventory:</strong> To overcompensate shortage scenario we may include additional fields in the schema (<a href="http://leanmanufacturingtools.org/114/waste-of-overproduction-causes-symptoms-examples-and-solutions/">Overproduction</a>). So when UI does not consume it, there will be inventory or dead code. Inventory in manufacturing actually consumes warehouse space. Since that is visible and measurable it is monitored closely. In Software, inventory problem is not as visible as shortage. Dead code does not take up physical space, it only consumes valuable cognitive space in the Developers mind. So there may not be a measurable loss. Only an inkling that we are lugging some unnecessary weight.</li></ol><p>I personally prefer “Outside In” approach. Starting with components that are close to end consumer helps us build features with minimum design errors. This goes for “API First” approach also. While being API Centric is good, it does not mean we design APIs in a void without actual demand. If an API has more than one client, they can all generate the demand.</p><p>With network style architecture like MicroServices, it is easier to go with “Outside In” approach to trace changes.</p><p>I have only scratched the surface of Push and Pull strategies in this post to justify my preference of approaching feature implementation. Once you get past the initial theory this topic can get immersive.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fcf56919a512" width="1" height="1" alt=""><hr><p><a href="https://medium.com/polarizertech/inside-out-vs-outside-in-fcf56919a512">Inside Out vs Outside In</a> was originally published in <a href="https://medium.com/polarizertech">polarizertech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>