You might notice I’ve retitled this series from Collaborative Spec-Driven Development to Collaborative Context Management. The shift isn’t just cosmetic—as I’ve followed evolving industry trends and discussions across various channels, I’ve noticed many teams moving away from traditional spec-driven development entirely. When I dug a bit deeper, I realised why: rather than front-loading massive, static specifications, they were continuously accumulating and refining context as they went.
Spec-driven development works brilliantly when you know exactly what you’re building. But in the real world, requirements are rarely that clean. You usually need to iterate just to figure out what you’re actually trying to build. Looking at my own workflow, I realised I was doing the exact same thing: instead of drafting heavy specs upfront, I have an initial conversation with an agent, bank any clear product direction, architectural decisions, or engineering standards, and push to a working implementation as fast as possible.
That working output gives me immediate, tangible feedback—which gets banked right back into the context layer for the next pass. If I don’t like a direction, I can scrap the code and pivot cleanly without losing the underlying knowledge we’ve already captured.
The Document Trap: What We Are (and Aren’t) Solving
In Part 1, I laid out the systemic friction points that emerge when teams attempt to scale AI-assisted development across multiple disciplines. We looked at the scoping trap, context drift, fidelity loss, thought traffic, and the collation bottleneck.
At their core, almost all of these issues stem from relying on documents as the primary vehicle for context.
Documents are inherently monolithic. They bundle user personas, business constraints, architectural choices, and technical tasks into a single flat file. For human reading, that bundling feels convenient. For AI agents, it is a liability:
- The Collation Bottleneck & Document Toil: To avoid broad scoping traps, teams naturally break context down into smaller documents (PRDs, ADRs, interface contracts, guidelines). But managing a large, ever-growing sprawl of separate files—tracking where they live, identifying which ones apply to a specific task, and keeping them organised—creates immense administrative toil without an established, highly disciplined process.
- Context Drift & Stale Assumptions: When documentation lives in static files or shared workspaces without version isolation, an in-flight agent can be derailed in two ways: either an upstream constraint shifts mid-implementation, or older, reachable documents that were never kept up to date silently poison the agent’s reasoning with obsolete assumptions.
- Spec Rot and Review Fatigue: The moment code is written, detailed implementation specs begin to decay. Maintaining them turns developers into full-time document janitors, reviewing pages of generated markdown that will be obsolete by next sprint.
Trying to solve these problems by introducing more document templates, stricter Jira hygiene, or heavier prompt prefixes only treats the symptoms. To build a resilient, agent-native workflow, we need to rethink the underlying data structure we use to represent context.
I didn’t want to build an all-encompassing enterprise platform that attempts to solve every problem under the sun. Instead, I focused on a specific, high-impact subset: eliminating document management toil, guaranteeing context stability during execution, and preventing spec rot without sacrificing engineering rigour.
To do that, I built Spool.
Enter Spool: Graph Version Control for Context
Spool is an open-source, local-first graph version-control system driven by a lightweight CLI (spl).
The mental model is simple: just as Git provides version control for your lines of code, Spool provides version control for your atomic context.
Instead of storing project knowledge in sprawling markdown files, Spool models context as a directed acyclic graph (DAG) composed of atomic nodes and semantic edges. Every change is recorded in an immutable transaction history, supporting branches, diffs, snapshots, and merges directly within your local workspace.
Why Not Just Use Git for Context?
When people hear “version-controlled context,” the natural question is: why not just put a bunch of markdown or JSON files into a Git repository and use standard Git branches?
It’s a fair question. Git is the undisputed standard for managing source code, but source code and knowledge context behave very differently:
- Git merges text, not concepts: Git thinks in terms of lines of text in files. If two team members add new relationships or details to the same feature on separate branches, Git sees two people editing the same file and throws a merge conflict—even when their ideas don’t contradict each other at all. A context graph understands meaning, so it can combine independent ideas without tripping over line numbers or file formatting.
- You can’t easily query across Git branches: With Git, your local files only reflect the branch you currently have checked out. If an agent needs to see how a requirement connects to an architectural decision across the team, you’d have to switch branches or build complex tooling to dig through Git history. A graph lets you query connections across the entire project instantly without moving files around on disk.
- AI agents iterate too quickly for Git commits: During a development run, agents generate lots of intermediate thoughts, checks, and temporary task plans. Committing every tiny step to Git would quickly clutter your repo history and slow down your development pipeline.
- Context needs to be modular, not all-or-nothing: When you check out a Git branch, you get the whole repository. But an agent working on a specific task doesn’t need the entire project’s history—it just needs the immediate neighbourhood of ideas, rules, and decisions related to that task.
In short, Git was designed to track files on a disk; Spool was designed to track connected ideas and their relationships.
A practical rule of thumb for choosing between the two:
- Use Git directly when context is static, human-curated (e.g. traditional
docs/adr/*.mdfiles), low-frequency, and needs to be reviewed line-by-line in standard GitHub or GitLab pull requests. - Use a dedicated Graph Store when context is dynamically traversed, generated or refined by autonomous agents, relational (linking business rules, component boundaries, and architectural standards), and requires instant sub-second queries, cross-branch delta merging, or local-first streaming.
With that distinction clear, let’s look at the four core pillars of how Spool addresses the context problem.
Pillar 1: Atomic Concepts & Multi-Disciplinary Domain Isolation
The first principle of Spool is decomposing monolithic documents into discrete, self-contained concepts.
In a document-driven workflow, an agent is often handed a sprawling, multi-concern specification paragraph like this:
“The order processing system must handle asynchronous billing notifications with guaranteed delivery. We should use PostgreSQL for order persistence and Kafka for publishing domain events via an outbox worker to prevent duplicate charges, ensuring error payloads conform to RFC 7807 and checkout drop-off is reduced.”
This is a classic document monolith. It mashes customer pain, business rules, architectural choices, infrastructure dependencies, and organisational standards into a single blob of prose. An agent reading this has to untangle what is a non-negotiable business constraint versus an implementation suggestion.
In Spool, that monolith is decomposed into atomic concepts—short, self-contained statements where each node captures a single verifiable truth:
- Product Requirement: “Checkout defers billing address collection until final payment submission”
- Architecture Decision (ADR): “Order service persists state to PostgreSQL and publishes domain events using a transactional outbox pattern to Apache Kafka”
- Architecture Trade-off: “Transactional outbox relay introduces 100ms–500ms delay between database commit and Kafka publication”
- Engineering Standard: “All public HTTP APIs return error responses formatted according to RFC 7807 Problem Details”
How Spool Uses Labels to Organise Context
In Spool, labels are not just cosmetic tags or arbitrary folder names—they are first-class semantic metadata that give the knowledge graph its structure, queryability, and governance rules.
Every atomic node in Spool can carry one or more labels (e.g. labels: ["Product", "Requirement"] or labels: ["SecurityPolicy", "Compliance"]). Spool leverages labels in three critical ways:
- Precision Slicing and Context Retrieval: Rather than dumping an entire folder of markdown files into an agent’s context window, agents and tools slice the graph along label dimensions. An agent can ask Spool for “all active Requirements linked to the Checkout component” or “all SecurityPolicy nodes governing Payment gateways”, extracting only the exact subgraph required for a task.
- Role-Based Governance with Dedicated Agents: Spool itself remains lightweight and schema-neutral—it doesn’t hardcode rigid validation rules into the engine. Instead, teams can deploy specialised, role-specific AI agents (such as a Product Agent or Architecture Reviewer) that police these conventions. A Product Agent, for instance, uses the
Productlabel to verify that business requirements remain strictly jargon-free, while a delivery agent uses theEphemerallabel to identify temporary task specs that should not be promoted to the permanent mainline. - Multi-Perspective Composition: Because concepts often cut across multiple disciplines, multi-labeling allows atomic nodes to participate in multiple perspectives simultaneously. An API error contract can be labeled
["Architecture", "DataContract"]and["EngineeringStandard", "APIStandard"]without duplicating data or creating disjointed copies.
Example Role Taxonomies (Extensible to Any Team)
To illustrate how this works in a software delivery lifecycle, we use three foundational role taxonomies. These are simply reference examples—Spool is completely domain-agnostic, and any team can define custom taxonomies to match their organisation:
Product Domain: Focuses strictly on user value and business constraints, free from technical jargon.
Problem&Outcome: Anchor why work is happening by capturing verified customer friction and measurable goals.Capability&Requirement: Define the specific functional behaviours and business rules that solve the problem.Constraint: Enforces non-negotiable business or regulatory boundaries (e.g. GDPR compliance or geographic restrictions).- How it’s used: Agents can filter directly for business rules or trace an implementation back to the underlying customer problem without wading through infrastructure details.
Architecture Domain: Models structural invariants, component topologies, and technical trade-offs.
Decision(ADR): Records foundational structural choices (such as adopting an event-driven architecture or choosing a persistence strategy).Component&Boundary: Maps subsystem ownership, isolation tiers, and network boundaries.DataContract: Defines explicit schemas and serialisation contracts across system boundaries.Tradeoff&QualityAttribute: Explicitly documents accepted downsides (e.g. eventual consistency latency) and non-functional requirements like throughput or latency budgets.- How it’s used: When an agent plans an implementation, it queries the relevant component boundaries and data contracts to ensure new code adheres to accepted architectural standards.
Engineering Standards: Establishes organisational guardrails, conventions, and quality gates across the codebase.
SecurityPolicy: Enforces mandatory security requirements, such as token encryption, hashing standards, and authentication flows.TestingStandard: Specifies required testing strategies, coverage tiers, and hermetic integration test requirements.APIStandard&Convention: Standardises API designs, error handling formats (e.g. RFC 7807), and naming conventions.AntiPattern: Explicitly documents forbidden architectural or coding patterns and why they must be avoided.- How it’s used: Agents check active standards and anti-patterns connected to their target components, preventing common mistakes and ensuring consistent code quality without bloated system prompts.
Adding Custom Domains and Roles
Because Spool’s graph model is schema-flexible, any other discipline or team can seamlessly plug in its own taxonomy:
- Design & UX: Nodes labeled
DesignSystem,ComponentVariant,AccessibilityStandard, orInteractionPattern. - Data & ML Engineering: Nodes labeled
DatasetContract,FeaturePipeline,ModelTopology, orEvaluationMetric. - Security & Compliance: Nodes labeled
AuditRequirement,PIIClassification,ThreatModel, orDataRetentionPolicy. - Site Reliability & DevOps: Nodes labeled
SLO,AlertPolicy,DeploymentTopology, orDisasterRecoveryPlan.
Semantic Edges Preserve High-Fidelity Intent
Instead of hoping an agent correctly infers how an architectural choice fulfills a product requirement from document proximity, Spool connects atomic concepts using typed, directional relationships:
[
{
"action": "add",
"entity": "node",
"id": "req-deferred-billing-address",
"title": "Checkout collects billing address only during final payment method submission",
"labels": ["Product", "Requirement"],
"properties": { "priority": {"kind": "string", "string": "high"} }
},
{
"action": "add",
"entity": "node",
"id": "adr-order-outbox-kafka",
"title": "Order service persists state to PostgreSQL and publishes domain events using a transactional outbox",
"labels": ["Architecture", "Decision"],
"properties": { "status": {"kind": "string", "string": "accepted"} }
},
{
"action": "add",
"entity": "edge",
"id": "edge-order-outbox-satisfies-order-req",
"source": "adr-order-outbox-kafka",
"target": "req-deferred-billing-address",
"type": "SATISFIES"
}
]
When an agent queries the graph, it traverses SATISFIES, COMPLIES_WITH, FORBIDS, and INCURS edges directly. The meaning is preserved because the relationships are structural and unambiguous.
Pillar 2: Taming Context Drift with Branching & Snapshot Isolation
Context drift manifests in two distinct ways: concurrently and chronologically.
The concurrent failure is in-flight drift. Imagine an agent is ten minutes into a multi-step refactoring task. Meanwhile, an architect commits an update to a shared architecture document on the mainline. If the agent dynamically reads from that live document mid-run, its assumptions shatter—it either hallucinates trying to bridge the contradiction or begins rewriting code to match an architecture it wasn’t instructed to implement.
The chronological failure is stale context. In a repository full of markdown specs, older documents that are still reachable in the workspace often linger without being kept up to date. An agent querying the workspace can easily pull in obsolete requirements or deprecated API conventions alongside current ones, flying blind without any signal that the older document was superseded.
Spool solves both problems by bringing Git-like branch isolation and explicit versioned graph snapshots to your context:
# 1. Create an isolated feature branch for the upcoming task
spl branch create feat/deferred-billing --from-branch main
spl switch feat/deferred-billing
# 2. Inspect the current branch state
spl status --branch feat/deferred-billing
When an agent executes against feat/deferred-billing, it operates on a stable snapshot of the graph. Upstream modifications on main do not touch the active execution context.
When the work is complete, changes are merged back into main through a controlled promotion process:
# Preview the merge and inspect potential conflicts
spl merge preview --source feat/deferred-billing --target main
# Apply the merge with an explicit author and commit message
spl merge apply --source feat/deferred-billing --target main \
--preview <preview-id> --transaction <tx-id> \
--author "Werner Swart <werner@example.com>" \
--message "Promote deferred billing context to main"
If an upstream concept was modified or superseded while the branch was active, spl merge detects the conflict explicitly before the shared graph is updated.
Pillar 3: Solving Spec Rot — The Codebase as Truth & Ephemeral Nodes
A major failure mode of early spec-driven practices was treating technical specifications as permanent artifacts.
Teams would generate lengthy technical implementation plans, commit them to the repository, and watch them rot within days. When the implementation inevitably required minor code-level adjustments, nobody went back to update the markdown plan. Whenever future agents had access to those lingering files and explored beyond the immediate ask, discovering those stale plans risked poisoning their reasoning with outdated assumptions.
This points to a foundational principle: once a technical plan has been implemented and validated, the codebase itself (source code, tests, schemas, types) becomes the living source of truth for technical behaviour.
Technical specs exist solely to align and guide development during active implementation. To support this lifecycle and prevent graph pollution, Spool introduces the Ephemeral label:
[
{
"action": "add",
"entity": "node",
"id": "spec-tx-outbox-relay-worker",
"title": "Implement transactional outbox relay worker polling outbox table every 200ms with batch Kafka dispatch",
"labels": ["Implementation", "TechnicalSpec", "Ephemeral"],
"properties": { "pollIntervalMs": {"kind": "integer", "integer": 200} }
},
{
"action": "add",
"entity": "node",
"id": "task-outbox-relay-metrics",
"title": "Add Prometheus counters for relay worker dispatched event count and batch dispatch latency",
"labels": ["Implementation", "Task", "Ephemeral"]
}
]
The Knowledge Promotion Lifecycle
- Durable Concepts Stay: Permanent business requirements, architectural decisions (
Decision), component topologies, and engineering standards remain in the graph indefinitely. - Transient Steps Fade: Implementation plans, task checklists, and spike notes are tagged with the
Ephemerallabel. Once the code is written, verified by automated tests, and merged, these transient nodes are cleaned up using Spool’sprunecommand (spl prune), ensuring ephemeral task scaffolding never lingers to pollute future context windows. - Discoveries are Promoted: If an implementation reveals a genuine new invariant (e.g. an unexpected database locking constraint), that discovery is promoted to a durable
DecisionorStandardnode—not buried in an ephemeral task file.
Pruning ephemeral scaffolding while preserving durable truths permanently eliminates context rot. The permanent graph stays lean, containing only the high-level invariants that code alone cannot express.
Pillar 4: Precision Context Retrieval via Bounded Subgraphs
In a traditional document-based setup, gathering context is a search problem: an engineer or an agent has to dig through disparate markdown files, ADR folders, and coding guidelines to locate and assemble the pieces relevant to a specific task.
This process is slow and error-prone. Agents spend valuable tokens and reasoning steps scanning past irrelevant sections, or worse, miss critical constraints buried in an unrelated document.
With Spool, an agent retrieves context by querying a bounded subgraph centred on the task at hand:
# Query the contextual neighbourhood around a feature (both inbound and outbound edges up to depth 2)
spl context --branch main --query "deferred billing" --direction both --max-depth 2
Because edges carry semantic meaning, spl context traverses the exact connected neighbourhood:
- The
Requirement(“Collect billing address at final submission”) - The linked
Problemit addresses (“Cart abandonment at step 2”) - The linked
Decisionthat satisfies it (“Order service transactional outbox”) - The linked
Standardgoverning that decision (“All public APIs must format errors per RFC 7807”)
The agent receives a tightly bounded, high-fidelity context packet containing only what is strictly relevant to that vertical goal—without having to dig through multiple documents or guess where related context lives.
The Collaborative Context Loop in Action
Here is what this looks like in practice during a typical development cycle:
- Intent & Alignment: During initial planning, product managers and engineers align on feature scope, customer problems, and business constraints.
- Bank Atomic Nodes: Durable product requirements, architectural decisions, and standards are committed to the graph (
spl add && spl commit). - Branch & Isolate: The engineer or agent creates a dedicated feature branch (
spl branch create feat/checkout-ux) to guarantee execution stability against upstream drift. - Query Bounded Subgraph: The agent runs
spl contextto extract only the connected neighbourhood relevant to the vertical goal. - Synthesise Ephemeral Spec: The agent authors a focused, atomic execution plan and task checklist tagged
Ephemeral. - Implement & Test Code: The agent writes the code and hermetic tests against living code as the ultimate source of truth.
- Prune Ephemeral Scaffolding: Once code is verified by automated tests, transient execution specs are cleaned up on the branch using
spl pruneso ephemeral scaffolding never pollutes the permanent record. - Promote & Merge: Durable discoveries or new architectural invariants that emerged during implementation are promoted to
mainviaspl merge apply.
If the feature direction turns out to be wrong after reviewing the working code, we can discard the code and branch without losing the captured business rules and architectural decisions.
Scaling Across Teams: The Remote Store
Right now, Spool operates primarily as a local-first tool within a developer’s local workspace. This local-first architecture is critical: it offers sub-millisecond query responses, offline capability, and zero-latency context retrieval during active pairing sessions with local coding agents.
However, software engineering at enterprise scale is fundamentally collaborative. Complex systems aren’t built in isolation by a single engineer—they involve product managers, domain architects, security leads, and multiple development teams, increasingly joined by fleets of autonomous background agents running in the cloud.
To bridge this gap, I am actively working on a remote store for Spool.
Just as Git relies on remotes (like GitHub or GitLab) to synchronise distributed repositories across teams, a Spool remote store acts as the shared synchronisation hub for your project’s context graph:
- Cross-Discipline Team Synchronisation: Product managers authoring business rules, architects recording ADRs, and tech leads defining standards can push and pull graph updates seamlessly—ensuring everyone (and their agents) works against the same canonical domain model without passing stale documents back and forth.
- Autonomous Cloud Agents: Autonomous agents running in CI/CD pipelines, headless staging sandboxes, or PR review bots can pull the latest graph snapshot, create isolated task branches in the cloud, execute code changes against verified standards, and submit structured merge proposals back to the remote store.
- Multi-Agent Coordination: As multi-agent workflows evolve, different specialised agents (e.g. a security auditor agent, a test generator agent, and an implementation agent) can share a unified, version-controlled context graph rather than passing lossy, conversational summaries between each other.
- Human-in-the-Loop Governance: Teams can enforce pull-request-style reviews and verification gates on context changes before they are merged into the shared mainline, preserving graph integrity as both humans and agents contribute new ideas.
Combining local-first speed with a shared remote store completes the feedback loop, transforming context management into a truly collaborative, organisation-wide capability.
Looking Ahead
Moving from Spec-Driven Development to Collaborative Context Management isn’t about writing more documentation—it is about managing context with the same discipline and tooling we use for source code.
By breaking down monolithic documents into versioned, atomic concepts, Spool gives teams:
- Zero Collation Overhead: Relevant context is traversed via semantic edges rather than hand-stitched by engineers.
- Drift-Free Execution: Agents operate on stable, isolated branch snapshots.
- Taming Context Rot: The codebase remains the ultimate source of truth, supported by ephemeral execution specs and durable domain invariants.
In Part 3, we’ll dive into how conversational agents can autonomously author and maintain this graph during live pairing sessions, and how we use graph-based goal selection to orchestrate multi-agent development pipelines.
If you’re experimenting with context management in your own engineering workflows, check out Spool on GitHub and share your thoughts.