<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: J.P. Solano</title>
    <description>The latest articles on Forem by J.P. Solano (@jsolano).</description>
    <link>https://forem.com/jsolano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F496073%2F8207bb95-bc7f-4425-bd6e-f5eb07977d56.png</url>
      <title>Forem: J.P. Solano</title>
      <link>https://forem.com/jsolano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jsolano"/>
    <language>en</language>
    <item>
      <title>Plans Are the New Code</title>
      <dc:creator>J.P. Solano</dc:creator>
      <pubDate>Thu, 07 May 2026 15:53:26 +0000</pubDate>
      <link>https://forem.com/jsolano/plans-are-the-new-code-4i8i</link>
      <guid>https://forem.com/jsolano/plans-are-the-new-code-4i8i</guid>
      <description>&lt;p&gt;&lt;em&gt;Why I went anti-agile to run an agent team — and the four shifts I would make sooner if I did this again.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;There is a reason that Boris Cherny — the engineer who built Claude Code at Anthropic — opens his official thirty-minute walkthrough not with a coding demo, but with a long detour through CLAUDE.md, shared project context, and "think before you code." There is a reason the same tool ships a built-in &lt;strong&gt;plan mode&lt;/strong&gt; as a first-class feature, and that Anthropic's own best-practices guide tells you, in plain language, to write your project plan &lt;em&gt;before&lt;/em&gt; your first plan-mode session — because the thirty minutes you spend writing it saves hours of plan corrections downstream.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;sup id="fnref2"&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;That habit looks small. It isn't. It is the visible tip of a much larger shift in where the leverage actually lives in software now: not in writing the code, but in writing the document the agent reads before it does.&lt;/p&gt;

&lt;p&gt;I run a small dev team that has been AI-driven from day one, and we are now shifting toward a hybrid model where humans and agents work side by side. After a year of this, here is the lesson I wish someone had handed me on day one: AI make typing cheaper, not thinking. The work that used to live inside the implementation has migrated upstream — into the spec, the contract, the gate, the checklist. And the discipline that catches it up there is not the agile playbook I was raised on. It is the slower, more boring, more rigorous one I was taught to mock.&lt;/p&gt;

&lt;p&gt;Here are the four shifts I wish I had made from the beginning.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Plans are the new code
&lt;/h2&gt;

&lt;p&gt;The first thing to internalise: &lt;strong&gt;agents amplify whatever specification you hand them.&lt;/strong&gt; Hand them a one-line ticket and you will get N divergent interpretations at LLM speed and LLM cost. Hand them a fifty-line spec that pins down the contract, the error envelope, the integration points, and one or two concrete examples, and you will get convergent parallel work from an entire team in a single afternoon.&lt;/p&gt;

&lt;p&gt;Velocity without a contract is just faster drift.&lt;/p&gt;

&lt;p&gt;The "plan" I am talking about is not a two-hundred-page Word doc. It is a small constellation of artefacts that, between them, leave no ambiguity about the seams of the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Numbered, modular spec sections&lt;/strong&gt; that other documents — and other agents — can link to by ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture decision records&lt;/strong&gt; for the forks where reasonable engineers would disagree, so that the choice and its consequences are durable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-package readmes&lt;/strong&gt; for the constraints local to one corner of the codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code comments&lt;/strong&gt; for the genuinely surprising — the workaround, the invariant, the thing the next reader will assume is wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each layer answers a different question — &lt;em&gt;what / why this over that / how to work here / why this loop exists&lt;/em&gt; — and conflating them is what makes plans rot. The pattern is the layering, not the volume.&lt;/p&gt;

&lt;p&gt;And one detail that sounds trivial until you have felt the pain: &lt;strong&gt;the plan lives in the repo, in Markdown.&lt;/strong&gt; Not in OneDrive. Not in a shared Word document. Not in Confluence behind an SSO redirect. The artefact has to sit on disk in the same checkout the agent reads from, in a format the agent can parse without an integration. The moment your plan lives somewhere the agent cannot reach without a human mediator, you are back to a human manually pasting context into prompts — and you have quietly given up the leverage the plan was supposed to provide. Markdown is the lingua franca: text, diff-able, reviewable, version-controlled alongside the code it specifies, and trivially digestible by every model on the market. If your plan is a &lt;code&gt;.docx&lt;/code&gt; your agents are working from a worse copy of it than your humans are.&lt;/p&gt;

&lt;p&gt;What goes into the plan is everything that has to be &lt;strong&gt;consistent across implementers&lt;/strong&gt; — schemas, interface boundaries, error shapes, role and permission matrices, observability contracts, deployment sequencing. What stays out is everything that lives inside one implementation — internal algorithms, private helpers, exact pixel layouts. The seams are pinned; the inside of the seams is exploratory.&lt;/p&gt;

&lt;p&gt;Crucially: &lt;strong&gt;this is not waterfall.&lt;/strong&gt; The plan evolves. But the &lt;em&gt;contracts&lt;/em&gt; in the plan are stable, and that is what lets parallel work stay convergent. You are not specifying the world up front. You are specifying the interfaces, so the work behind the interfaces can move at LLM speed without colliding.&lt;/p&gt;

&lt;p&gt;The cost is real — days to weeks of writing, before the first agent runs a single command. It is paid back in the first week the team works in parallel without stomping on one another's assumptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The "anti-agile" foundation
&lt;/h2&gt;

&lt;p&gt;Now the provocation. The classical project-management artefacts you were taught to mock — the work breakdown structure, the dependency graph, the acceptance-criteria-first ticket, the change board — are not the past. In an agentic team, they are the &lt;em&gt;foundation&lt;/em&gt; that makes autonomy safe.&lt;/p&gt;

&lt;p&gt;This sounds reactionary. It isn't. Agile didn't die. It just stopped being the bottom of the stack.&lt;/p&gt;

&lt;p&gt;The reason is mechanical, not ideological. Human teammates absorb ambient context — the standup, the Slack thread, the "you remember when" in the kitchen — and recover from ambiguity in real time. An LLM has none of that. It has one shot per session, the prompt you handed it, and whatever artefacts it can read on disk. "We'll figure it out as we go" assumes a shared mental model that an agent does not have and cannot acquire mid-task.&lt;/p&gt;

&lt;p&gt;That single asymmetry rewires three habits at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task decomposition encodes data dependencies, not just logical ones.&lt;/strong&gt; A backend agent that needs a schema change cannot start until the migration is merged and the generated types are regenerated. A frontend agent that consumes an API cannot start until the spec is in. The dependency graph that an experienced PM would have drawn on a whiteboard in 2008 is now load-bearing again — because the agent will, with complete confidence, hallucinate a column that doesn't exist if you let it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel-versus-sequential stops being a schedule optimisation and becomes a context-isolation boundary.&lt;/strong&gt; Two agents working in parallel do not see each other's uncommitted changes. If you want their work to converge, the dependency between them has to be resolved by a merge, not by a conversation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WIP limits return&lt;/strong&gt; — not because humans get cognitively overloaded (they do, but that's not the story here) — but because too many concurrent agent PRs collapse the human review queue. The bottleneck is downstream of the agents, and the queue has to be sized to it.&lt;/p&gt;

&lt;p&gt;The thing to internalise: agentic teams are still iterative — but the iteration happens &lt;em&gt;inside the seams&lt;/em&gt;, not across them. Classical PM holds the seams. Agile lives within them.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Human gates belong at decision points, not code points
&lt;/h2&gt;

&lt;p&gt;The most common mistake I see in newly agentic teams is putting a human in front of every diff. It looks responsible. It is actually the opposite — it bottlenecks humans on grunt work and starves the genuinely risky decisions of attention.&lt;/p&gt;

&lt;p&gt;The right test is the &lt;strong&gt;reversibility test&lt;/strong&gt;. Ask, of any given change: &lt;em&gt;if this lands and turns out to be wrong, can I undo it cheaply?&lt;/em&gt; If yes, it is reversible code; flow it through the agents, the checklist, the audit. If no — the change commits the company to something sticky — it is a decision, and a decision is the human's job.&lt;/p&gt;

&lt;p&gt;The decisions that almost always fail the reversibility test, in any production team I have seen, fall into a tight set of categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business priorities and what ships in what order.&lt;/li&gt;
&lt;li&gt;Schema and data-shape migrations to shared environments.&lt;/li&gt;
&lt;li&gt;Production infrastructure changes.&lt;/li&gt;
&lt;li&gt;Authentication, identity, and money-handling code.&lt;/li&gt;
&lt;li&gt;The governance documents themselves — the rules the agents operate under.&lt;/li&gt;
&lt;li&gt;The final merge to the trunk.&lt;/li&gt;
&lt;li&gt;External communication and launch decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Around the gates, you need three guardrails that protect the gates rather than replace them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tool-call budgets per agent session.&lt;/strong&gt; A bounded number of actions before the session is force-terminated. This is the difference between a stuck agent and a runaway agent burning context and credibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WIP limits on open agent PRs.&lt;/strong&gt; Five is a reasonable starting number for a small team. The number isn't the point; the principle is matching agent throughput to the human review queue, which is the bottleneck you cannot 10x.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An explicit escalation protocol.&lt;/strong&gt; When an agent encounters a decision outside its authority, it posts a clear "decision required" signal and &lt;em&gt;stops&lt;/em&gt;. It does not guess. The worst outcome is an agent that solves an authorisation question by interpolating from context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Move human attention to where it matters. Automate where it doesn't. The cost of a wrong gate placement is paid every day; the cost of fixing it is paid once.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The self-audit, and why "all todos done" is a lie
&lt;/h2&gt;

&lt;p&gt;There is a specific failure mode that took me longer than I'd like to learn. An agent finishes a task, ticks off every item on its own todo list, and announces that the feature is complete. The PR goes up. Tests are green. The review queue moves.&lt;/p&gt;

&lt;p&gt;Two weeks later the bug appears. It turns out the spec required something the agent never noticed, and never wrote a todo for, and never tested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An agent's todo list is its plan to itself.&lt;/strong&gt; It is not the spec. It is not the acceptance criteria. The two will diverge silently unless something explicitly checks.&lt;/p&gt;

&lt;p&gt;The thing that closes the gap is a &lt;strong&gt;code-versus-plan audit&lt;/strong&gt; that runs &lt;em&gt;before&lt;/em&gt; the PR is marked ready. The audit cross-references the diff against the plan modules the issue claims to close, and looks for five categories of finding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gap.&lt;/strong&gt; The plan said X; the code does not do X. &lt;em&gt;Blocker.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft gap.&lt;/strong&gt; The plan said X for a later phase; the code defers correctly &lt;em&gt;and&lt;/em&gt; the deferral is tracked as an issue elsewhere. &lt;em&gt;OK.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improvement.&lt;/strong&gt; The code does more than the plan asked, in a way that's clearly safe. &lt;em&gt;Note.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-scope.&lt;/strong&gt; The code does more than the plan asked, in a way that is risky or surprising. &lt;em&gt;Warn — either trim, or amend the plan.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doc drift.&lt;/strong&gt; The plan and the code disagree, and the plan was never updated. &lt;em&gt;Blocker.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The detail that most teams get wrong is the &lt;strong&gt;asymmetric routing&lt;/strong&gt;. Blockers must be fixed in &lt;em&gt;this&lt;/em&gt; PR — the PR cannot honestly claim to close the feature otherwise. Non-blockers do not derail the PR; they become &lt;strong&gt;durable, tracked issues&lt;/strong&gt;, never just PR comments, never just lines in a report. Comments evaporate. Backlog issues persist. If you only enforce the blocker half, you ship rigorously; if you only enforce the non-blocker half, you ship endlessly.&lt;/p&gt;

&lt;p&gt;The further move: have one agent audit another's PR before any human sees it. False positives go back to the originating agent — not to the human. The &lt;strong&gt;gate&lt;/strong&gt; stays human; the &lt;strong&gt;screening&lt;/strong&gt; moves to a cheap resource. This is the move that scales.&lt;/p&gt;

&lt;p&gt;One anti-pattern is worth naming explicitly: &lt;strong&gt;post-merge audits&lt;/strong&gt;. By definition they cannot block. They become tech debt by default. If the audit isn't gating the merge, it isn't an audit; it's a retrospective.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Common criteria: checklists beat opinions
&lt;/h2&gt;

&lt;p&gt;The reason most code review is exhausting is that it is a debate about taste. The reason most &lt;em&gt;agent&lt;/em&gt; code review is exhausting is that there is no shared taste — the agent has the median opinion of GitHub, which is to say no opinion at all.&lt;/p&gt;

&lt;p&gt;The fix is unromantic: a written, versioned checklist of &lt;strong&gt;binary, parseable, author-agnostic&lt;/strong&gt; criteria. The same questions regardless of who wrote the code — founder, contractor, agent, intern.&lt;/p&gt;

&lt;p&gt;The categories that benefit most from this treatment, in any production team I've worked with, are remarkably consistent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tenant and data-isolation invariants&lt;/strong&gt; — does every query that crosses the multi-tenant boundary include the tenant filter?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret handling&lt;/strong&gt; — is the diff free of plaintext credentials, even in gitignored files?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability shape&lt;/strong&gt; — is every new log line going through the structured wrapper, with the correlation identifier, rather than bare console output?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-contract conformance&lt;/strong&gt; — is every new endpoint described in the spec the client is generated from?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test-pyramid hygiene&lt;/strong&gt; — does the new module ship with at least the test layer the policy requires?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration safety&lt;/strong&gt; — is the schema change additive, backward-compatible, and reversible by default?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These work because each is &lt;strong&gt;regex-checkable, grep-able, or schema-checkable.&lt;/strong&gt; No judgment required to fail. An agent can pass or fail each one. Humans disagree about code style; nobody disagrees about whether a secret leaked.&lt;/p&gt;

&lt;p&gt;The bonus effect is sociological. The checklist becomes &lt;strong&gt;shared vocabulary&lt;/strong&gt;. "This PR fails RBAC-001" carries the same meaning to a teammate, an agent, and a future post-incident review. Onboarding becomes linear: read the checklist, you know the standard.&lt;/p&gt;

&lt;p&gt;The caveat — and it matters — is that checklists handle the &lt;strong&gt;floor&lt;/strong&gt;, not the ceiling. They free human reviewers from the mechanical work so the humans can do the work only humans can do: architecture, business logic, security boundaries, the thing the spec didn't anticipate. If your reviewers are spending their attention on tenant filters, you don't have a code review problem. You have a checklist problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The formula
&lt;/h2&gt;

&lt;p&gt;If I had to compress a year of running an AI-driven team — now with agentic members alongside the humans — into four lines, this is what I would write on the wall:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Write the contracts before the first agent runs.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gate at decision points, not code points.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audit code against plan before declaring "done."&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encode the floor as a checklist; reserve human judgment for the ceiling.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this is a return to waterfall. The work inside the seams is as iterative as anything I did under any flavour of agile — more so, because the cycle time is shorter. What changed is the &lt;strong&gt;interfaces&lt;/strong&gt;. Agentic teams scale on the quality of their interfaces — the spec, the gate, the checklist — not on the quantity of their code. Agile lives inside the seams. Classical PM holds the seams.&lt;/p&gt;

&lt;p&gt;The cheapest leverage in software right now is not a better model. It is a better plan.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Boris Cherny (Member of Technical Staff, Anthropic), &lt;em&gt;Mastering Claude Code in 30 minutes&lt;/em&gt; — official Anthropic walkthrough on YouTube. &lt;a href="https://www.youtube.com/watch?v=6eBSHbLKuN0" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6eBSHbLKuN0&lt;/a&gt; — see the early sections on shared project context, CLAUDE.md, and "think before you code." Discussion: &lt;a href="https://news.ycombinator.com/item?id=44197169" rel="noopener noreferrer"&gt;https://news.ycombinator.com/item?id=44197169&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;em&gt;Best practices for Claude Code&lt;/em&gt; — Anthropic. &lt;a href="https://code.claude.com/docs/en/best-practices" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/best-practices&lt;/a&gt; — explicitly recommends writing your project's CLAUDE.md before the first plan-mode session, on the grounds that upfront context dramatically reduces plan-correction cycles. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>agentaichallenge</category>
      <category>agents</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Most Important Skill A Software Engineer Can Have</title>
      <dc:creator>J.P. Solano</dc:creator>
      <pubDate>Thu, 11 Nov 2021 16:28:37 +0000</pubDate>
      <link>https://forem.com/jsolano/the-most-important-skill-a-software-engineer-can-have-9cf</link>
      <guid>https://forem.com/jsolano/the-most-important-skill-a-software-engineer-can-have-9cf</guid>
      <description>&lt;p&gt;Sometimes people believe that Software Engineers are like monks, and they spend their days in silence and coding. Nothing more far from reality. On good days, software engineers will code only 40% of their days, other, maybe 10% or maybe 0%. But, what are they doing the rest of the time?, meditating?, eating food and drinking coffee?, playing Ping-Pong?&lt;/p&gt;

&lt;p&gt;No really.&lt;/p&gt;

&lt;p&gt;First, let’s remember the main purpose of a software engineer is not coding per se, it is &lt;strong&gt;solving problems&lt;/strong&gt;. To achieve that goal, an effective software engineer will need to interact with diverse members of the team throughout the life cycle of a problem until they find an acceptable solution. Within that cycle, code is a critical part, but it is not the most important. Instead, having a clear understanding of the problem and the most efficient solutions is critical before starting to code. This makes it more likely to end with successful results. Remember, &lt;strong&gt;the worst possible scenario for a software engineer is presenting a great piece of code that does not resolve the initial problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here a list of activities software engineers do that are not coding, but can help do solve problems in their organizations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Writing design docs&lt;/strong&gt;: These allow software engineers to share a high level overview of the problem and the potential solutions with key stakeholders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code reviews&lt;/strong&gt;: Reviewing somebody else’s code, giving feedback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Whiteboarding sessions&lt;/strong&gt;: Talking with peers about potential implementations, systems design, solving scenarios, technologies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Peer programming sessions&lt;/strong&gt;: When 2 people work together to crack especially hard problems with a brainstorming approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Status meetings&lt;/strong&gt;: When you have to give status updates of your project to the team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;And many more&lt;/strong&gt;: Product requirement meeting, Design springs, API design springs, UX design springs, 1:1 with managers or direct reporters, Peer reviews, Self assessment reviews, Respond to emails, Collaboration chats.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;We (humans) can solve problems BECAUSE we are great communicators!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if for software engineers, all these activities would represent 60% to 80% of a their day, then you will agree on the importance of an effective communication skill. Moreover, and thanks to COVID-19, where are in remote office era, where written communication has taken special relevance. See this interesting twitter thread about the future of the remote office.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1kdlnfma6qd7myjpznc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1kdlnfma6qd7myjpznc5.png" alt="Alt Text" width="800" height="262"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F34uelzds4n7cwhiauzif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F34uelzds4n7cwhiauzif.png" alt="Alt Text" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Communication is the most important of your skills and will determine in high degree your ability to solve problems and in the long term, it will shape your career success. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6orxq7aodcvphwdw6jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6orxq7aodcvphwdw6jt.png" alt="Alt Text" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some practices that will make you a better communicator, and will help you to solve problems in your organization (specially for engineers):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be concrete or specific.&lt;/strong&gt; E.g. : If you are responding to a long email thread and you want to agree or disagree about something, don’t assume everybody has the same information that you have:, better rewrite the key points and close with a clear position.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Empathy&lt;/strong&gt;: Connecting with your audience sounds cliche, but is true. Try to understand who the audience is (1 or many) and, what their expectations are. Using this information to adapt your message will make a big difference in the interaction and collaboration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be a good listener&lt;/strong&gt;: Less is more, and effective communication is not about how long the message is, it’s more about the quality. Try not to be the first in talk; instead listen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prefer facts over emotions&lt;/strong&gt;: Trying to detach from a problem when it is very important for you is hard, but the risk from not doing so is high. If we reduce the discussion to how we feel about the solution vs what is important for solving a problem, we take the risk of leading the conversation to a dead (and very personal) end. People can disagree with your idea. So, be prepared to defend your points, but never take it personally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repetition&lt;/strong&gt;: On any interaction, be sure you have a clear idea what part of your message you want to break through: pick one or two words and repeat it regularly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gestures / Voice&lt;/strong&gt;: Most communication, including zoom meetings, are managed by non-verbal body language and gestures. Be aware of your body language and what sign it may transmit to the receiver. Incorrect body language could trigger unconscious biases in your receiver that will hurt the whole conversation. Using some strategic pauses can increase the value of your ideas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On better writing skill, I recommend this video about the The Craft of Writing Effectively&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=vtIzMaLkCaM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=vtIzMaLkCaM&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Engineering is easy, people are hard. &lt;br&gt;
-- Google &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;initial inspiration from Clement Mihailescu's video about the topic.  &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>skill</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building a React app to solve every Sudoku puzzle.</title>
      <dc:creator>J.P. Solano</dc:creator>
      <pubDate>Thu, 22 Oct 2020 01:25:41 +0000</pubDate>
      <link>https://forem.com/jsolano/building-a-react-app-to-solve-every-sudoku-puzzle-3c95</link>
      <guid>https://forem.com/jsolano/building-a-react-app-to-solve-every-sudoku-puzzle-3c95</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Peter Norvig, the legendary Google mogul and AI titan, wrote &lt;a href="http://norvig.com/sudoku.html" rel="noopener noreferrer"&gt;a python essay to solve every Sudoku puzzle&lt;/a&gt; 10 years ago. Back then, he may not have expected that his code will inspire so many other posts and to be ported to so many different languages. For JavaScript, the latest version of the solver that I found was &lt;a href="https://github.com/einaregilsson/sudoku.js/" rel="noopener noreferrer"&gt;@einaregilsson/sudoku&lt;/a&gt; from 2014 .   &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I thought it would be interesting to create a react app that uses Peter Norvig's solver ideas and adds some learning layers to the UI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are some details from the &lt;a href="https://www.industrialempathy.com/posts/design-docs-at-google/" rel="noopener noreferrer"&gt;design document&lt;/a&gt; that I used to create the app. Let's start. &lt;/p&gt;

&lt;p&gt;If you want to check it out before reading, go to the &lt;a href="http://jsolano.github.io/react-sudoku-solver" rel="noopener noreferrer"&gt;LIVE DEMO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or the github repo &lt;a href="https://github.com/jsolano/react-sudoku-solver" rel="noopener noreferrer"&gt;jsolano/react-sudoku-solver&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan and Scope
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Designing and implementing a HTML/JS/CSS Web app using React (with hooks).&lt;/li&gt;
&lt;li&gt;Designing and implementing an algorithm that solves Sudoku puzzles in JavaScript.  (From easy to extra heavy-hard levels)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Goals and non-goals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Goals:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Build a HTML/JavaScript application that solves a given Sudoku puzzle. &lt;/li&gt;
&lt;li&gt;Use React components and React hooks.&lt;/li&gt;
&lt;li&gt;Cover aesthetics and usability. &lt;/li&gt;
&lt;li&gt;Support entering puzzle strings in the format described in Peter Norvig's article.
&lt;/li&gt;
&lt;li&gt;Cover Performance of the algorithm (Easy, Medium, Hard, Expert).&lt;/li&gt;
&lt;li&gt;Display time taken to solve a puzzle.&lt;/li&gt;
&lt;li&gt;Cover Unit testing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Non-Goals:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;UI level automation-tests. &lt;/li&gt;
&lt;li&gt;Generate new unsolved puzzle.&lt;/li&gt;
&lt;li&gt;Print a Sudoku.&lt;/li&gt;
&lt;li&gt;Storage any session data (local or remote).&lt;/li&gt;
&lt;li&gt;Accept user solutions to the puzzle.&lt;/li&gt;
&lt;li&gt;Make the solver stop in a specific step.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Initial Design
&lt;/h2&gt;

&lt;p&gt;The idea was to create a sense of flow in the UI, where users can easily understand how to use it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5oub6gzznx8aoxxkif4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5oub6gzznx8aoxxkif4d.png" alt="Alt Text" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  System Context Diagram
&lt;/h2&gt;

&lt;p&gt;There are two main modules of the app: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpnwaivue7urjbr3m8lc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpnwaivue7urjbr3m8lc6.png" alt="Alt Text" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, I made a raw version of the basic JS components and utilities:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyypcp1yvmag4g2jiq7zy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyypcp1yvmag4g2jiq7zy.png" alt="Alt Text" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, I started working on the solver service using JEST for testing. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8z6i20fc5y0ga91mv8n4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8z6i20fc5y0ga91mv8n4.png" alt="Alt Text" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later, I implemented the react components for the board, modal, messages and buttons, and then integrated with the solver service using react hooks.  &lt;/p&gt;

&lt;h3&gt;
  
  
  The Learning Layer.
&lt;/h3&gt;

&lt;p&gt;Here's when things started to get interesting.  On one side, the UI learning column helped me understand how the solver was working and how to improve the implementation.  But, after I ported Peter Norvig's algorithm, which uses a backtracking search strategy and solves ALL SUDOKUS, I realized the learning column was useless because in the search of a solution, it created temp steps that were not valid. I needed to change my approach. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Turning Point
&lt;/h3&gt;

&lt;p&gt;I could've just removed the learning feature and lived with just a simple solver but instead, I chose to implement other solving strategies that provided the detailed solutions. &lt;/p&gt;

&lt;p&gt;I did my research about Sudoku solving strategies, and there were more than 38 options. I was totally hooked. &lt;a href="https://www.sudokuwiki.org/sudoku.htm" rel="noopener noreferrer"&gt;See more here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But all of these strategies come with a &lt;em&gt;caveat&lt;/em&gt;: you can work on many lines of code while trying to implement some of these strategies and still not solve all the puzzles. (I learned this the hard way). So, I found a solution: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Creating a react app that uses human solving strategies (for learning purposes and for fun), and only applying Backtracking Search as the last resort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So now, the app will apply this strategies :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hidden Singles &lt;/li&gt;
&lt;li&gt;Naked Pairs/Triples &lt;/li&gt;
&lt;li&gt;Pointing Pairs &lt;/li&gt;
&lt;li&gt;And as a last option: &lt;strong&gt;Backtracking Search&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also, it comes with a prevention for infinity loops and a spinner while it's solving the puzzle. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftpfeukgd38o53bp68env.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftpfeukgd38o53bp68env.png" alt="Alt Text" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update #1:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added Pick Just One link to load a random puzzle. (Thanks Andre for the suggestion!) 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxmvvigk3v56ddoqfwgha.png" alt="Alt Text" width="800" height="561"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Update #2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added a message when the entered board is solve in the parsing moment. (Thanks Andre for the hint!) This could happens after filtering for cell possible values and all cell get solved. (not common, but possible e.g.: ..6.....2.81.4293.25...34..4.8.1..76..2...8..17..6.3.9..35...94.9732.51.5.....7.. )
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frf3ijhfoxei71qaid3ir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frf3ijhfoxei71qaid3ir.png" alt="Alt Text" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update #3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added responsive layout for mobile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flxwktsrwqpcrw94px9aq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flxwktsrwqpcrw94px9aq.png" alt="Alt Text" width="480" height="859"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update #4:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changed the useState hook for useReducer to decouple the state management from the component and also added localStorage persistence.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are a Sudoku fan and want to collaborate, take a look of the &lt;a href="https://github.com/jsolano/react-sudoku-solver" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;. Join me in implementing the other 34 strategies!&lt;/p&gt;

&lt;p&gt;/JP&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The enemies of people who work with ideas are not the people with the opposing ideas. They're those who want to ban the discussion altogether. -Paul Graham &lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>css</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
