<?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>DEV Community: zS1m</title>
    <description>The latest articles on DEV Community by zS1m (@contrails).</description>
    <link>https://dev.to/contrails</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4027347%2F6afc4ff1-a7a7-40c4-9beb-0fe44164ef75.png</url>
      <title>DEV Community: zS1m</title>
      <link>https://dev.to/contrails</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/contrails"/>
    <language>en</language>
    <item>
      <title>Contracts and Transparency: The Boundary Problem in SDD Collaboration</title>
      <dc:creator>zS1m</dc:creator>
      <pubDate>Mon, 13 Jul 2026 13:52:02 +0000</pubDate>
      <link>https://dev.to/contrails/contracts-and-transparency-the-boundary-problem-in-sdd-collaboration-47bl</link>
      <guid>https://dev.to/contrails/contracts-and-transparency-the-boundary-problem-in-sdd-collaboration-47bl</guid>
      <description>&lt;p&gt;Recently my team has been building an AI product from zero to one. In this era of AI-assisted development, you inevitably run into SDD (Spec-Driven Development) frameworks like OpenSpec and BMAD. We work with a separated front-end/back-end setup and use OpenSpec to drive development; I also use it in several of my personal projects.&lt;/p&gt;

&lt;p&gt;Compared with the smooth experience of building a full-stack project solo with OpenSpec, using it in a front-end/back-end split brought some scenarios I didn't expect: with each side writing its own change, the process would stall at the explore stage. Whenever I wanted to push forward, I often found I had to wait for the other side to confirm some detail first — and they were often waiting on me. In the end, the two of us just ended up awkwardly stuck, staring at each other across our changes.&lt;/p&gt;

&lt;p&gt;This got me thinking: with the same tools and the same process, why does adding one more developer make things less smooth? After a few more days of experience and reflection, I gradually figured out some of the sticking points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Layers Behind the Friction
&lt;/h2&gt;

&lt;p&gt;To figure out where things were getting stuck, I started by reviewing how the back-end developer and I actually collaborated. It went roughly like this: when a new requirement came in, we each opened our own change in OpenSpec, explored and brainstormed separately, and produced our proposals. But during exploration, something would gradually surface: the shape of the API I consume depends on the back end's implementation design, while the fields the back end needs to settle depend on how the front end plans to use them. So I went digging through their design and code, they came to read mine, neither of us could move forward independently, and the explore stage simply stalled.&lt;/p&gt;

&lt;p&gt;Compared with solo full-stack development, what is actually different about working in a pair? Why did I never hit this problem working alone? The answer is simple: when I build full-stack by myself, both ends are in my hands. I make the call on every API and every field, so the two ends are aligned inside my head by default. With two people, that alignment has to be made explicit — laid out somewhere both sides can see — and that was exactly the place we lacked.&lt;/p&gt;

&lt;p&gt;Digging deeper, there are two layers of causes underneath. The first is the product stage. For an innovative AI product going from zero to one, requirements change constantly. When a requirement changes, the API contract has to change with it; a field settled today may be overturned tomorrow. In other words, a contract is only as stable as the requirements behind it, and the zero-to-one stage is exactly when requirements keep flipping. So neither side dared — or was able — to nail the contract down first. All we could do was guess and write, then compare notes, and when things didn't match, go back, revise, and compare again, round after round.&lt;/p&gt;

&lt;p&gt;The second layer is more subtle: between the two of us, there was never a contract that stood up first — something we could simply follow. The front-end and back-end changes usually advanced side by side, and the shape of the API was gradually ground out of the two implementations. Which means that for any given requirement, there was never a single source of truth both sides recognized. Every attempt to move forward required diving into the other side's implementation details to confirm things — while those details were themselves still changing.&lt;/p&gt;

&lt;p&gt;At that point I had a vague feeling: the root of the friction was that the boundary between front end and back end had blurred.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Missing Contract
&lt;/h2&gt;

&lt;p&gt;Following the thread of the blurred boundary: what is the boundary between front end and back end supposed to look like?&lt;/p&gt;

&lt;p&gt;Traditional development answered this long ago: an API document is the boundary between front end and back end — in other words, a contract. Once a requirement is settled, you define the API first and produce an OpenAPI document both sides agree on; the back end implements against it, and the front end consumes against it. To the front end, this contract is the single source of truth: how the back end designs and implements things internally is not its concern. Likewise, the back end doesn't need to know how the front end will use the data. Each side tucks its details behind the contract, and the boundary becomes clear on its own.&lt;/p&gt;

&lt;p&gt;Hold our collaboration up against that answer and the problem is obvious. We had spread our designs and implementation details out for each other to read, yet never stood up a contract. The details that should have been hidden were fully transparent, while the agreement that should have been established was absent all along.&lt;/p&gt;

&lt;p&gt;At first I assumed the fix was "the back end defines the contract, the front end consumes it" — after all, the API is provided by the back end, so letting the provider define it seems only natural. But the pattern that turned out smoother in practice was for front end and back end to each produce contracts for different requirements and modules, with the other side following along. That made me realize that who defines the contract matters far less than this: every contract needs one clear owner, who establishes it independently, up front, and keeps it stable, while the other side treats it as the source of truth. Whether that owner is the front end or the back end can switch freely by requirement or by module.&lt;/p&gt;

&lt;p&gt;Once that clicked, I had a new criterion for "transparency": whether things should be transparent depends on whether a single contract exists between the two sides. If there is one, let the contract do the talking, and implementation details should stay hidden; only when there is none do you need to spread the details open to stay aligned. Our friction came precisely from falling back to reading each other's details in a place where the contract should have been doing the talking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaboration Without a Contract
&lt;/h2&gt;

&lt;p&gt;Measured against this criterion, the collaboration between me and AI turns out to be the exact opposite.&lt;/p&gt;

&lt;p&gt;Come to think of it, is there a contract between me and the AI? Apparently not, and one can't really be established, because a contract presupposes that "once agreed, both sides execute accordingly" — while every plan and every piece of code the AI generates is a fresh answer produced on the spot. The same request may yield one thing today and something different tomorrow. Without resorting to special measures, there is no way for me to agree with it in advance on "how you will implement this" and then accept the result against that agreement. The front-end/back-end pattern of "establish a contract, hide the details on each side" simply doesn't hold here.&lt;/p&gt;

&lt;p&gt;With no contract to establish, only one road is left: spread the details open. This is also something I gradually confirmed while using OpenSpec. The key to getting usable, accurate output from AI is to read the details of its generated plans carefully, and to correct anything wrong or off-course promptly and thoroughly. Every piece of design and every assumption in the plan is a visible imprint of the AI's thinking. The closer you read and the earlier you correct, the less rework you face at the implementation stage. Conversely, if you skip the plan to save effort, the problems tend to resurface in the code in far subtler ways.&lt;/p&gt;

&lt;p&gt;Interestingly, Claude Code doesn't fully unfold its thinking process to the user the way the web client does (I'm not sure why — possibly a trade-off around how much a terminal can display), while OpenSpec happens to surface that process through documents, which in a way patches exactly this piece of transparency.&lt;/p&gt;

&lt;p&gt;So the same act of "spreading the details open" is the disease behind a blurred boundary between front end and back end, yet the core of quality assurance between me and AI. Transparency itself is neither good nor bad; it still comes down to that criterion — whether a reliable contract exists between the two sides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Sides of Transparency
&lt;/h2&gt;

&lt;p&gt;Once I understood this criterion, I found it explains far more than development collaboration.&lt;/p&gt;

&lt;p&gt;The Trisolarans in &lt;em&gt;The Three-Body Problem&lt;/em&gt; are an extreme example. Their thinking and communication are completely transparent: the moment a thought arises, their kind knows it instantly. Internally, this transparency makes their communication nearly lossless and extremely efficient, and their civilization and technology advance rapidly because of it. But once they face humanity, an adversary with opposing interests, the same transparency becomes a flaw — no hiding, no deception — that humans turn against them. One and the same property, and across the line between camps, its costs and benefits flip completely.&lt;/p&gt;

&lt;p&gt;DeepSeek-R1 is an example in the other direction. When it launched, it shook the entire AI community: at a time when everyone assumed model capability could only be pushed up by piling on compute, it used reinforcement learning to make the model write out its reasoning chain explicitly, finding a new path to improvement through "thinking in the open". For an AI that needs to be reviewed and corrected by humans, transparency is itself part of its capability.&lt;/p&gt;

&lt;p&gt;In one case transparency became a fatal flaw; in the other, a capability. Put together, it isn't hard to see that transparency has no absolute good or bad in itself — what matters is which side of which boundary it sits on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts: A Rule of Thumb
&lt;/h2&gt;

&lt;p&gt;Back to development collaboration. This experience left me with a practical rule of thumb: when collaborating with someone, first ask — is there a single contract we can both follow?&lt;/p&gt;

&lt;p&gt;If there is, treat the contract as the source of truth, keep implementation details on your own side, and don't reach across the boundary to see how the other side does things. If there isn't, first check whether one can be established. If it can, establish the contract early; if it can't (as with AI), then spread the details fully open — review them carefully and correct them promptly.&lt;/p&gt;

&lt;p&gt;This post records nothing more than one stretch of experience on a zero-to-one project, and it may not apply to every team or stage. But the next time a process stalls for no obvious reason, this is probably the first question I'll ask: is what's missing here a contract, or a moment of laying the cards on the table?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>openspec</category>
    </item>
  </channel>
</rss>
