limen

software organizations need an endocrine system

as humans and agents produce more concurrent changes, the missing infrastructure is not another shared workflow. it is a system that keeps independent workflows consistent at the boundaries between them.

start with two pull requests in two repositories.

in playlist-api, pull request #42 at head sha def456 renames a graphql field, which from any consumer's point of view removes it:

 type Playlist {
   id: ID!
-  episodes: [Episode!]!
+  items: [Episode!]!
 }

in ios-client, pull request #87 adds a playlist screen whose query selects Playlist.episodes. the query exists nowhere but this open pull request: no registry holds it, no production traffic exercises it. one change came out of a coding agent session. the other came from an engineer in neovim. the two workflows share no tooling and never communicate.

each pull request is green: the checks in its own repository pass because each is correct against the software that exists today. together they describe a future that cannot ship.

nothing turns red when pull request #42 opens. but the truth about the consumer flips at that moment, and flips back if the rename is withdrawn, all without a new commit to the consumer. a check that understood the proposed future would report:

consumer sha:
abc123 -> abc123 -> abc123

consistency state:
green -> red -> green

today, both pull requests stay green until one of them merges, and the incompatibility surfaces later, wherever the merge order happens to put it.

validity is not solely a property of an artifact. it is a property of that artifact evaluated against the current and proposed state around it.

no tool in either repository is positioned to see this. git knows a commit. ci knows whether that commit passes one repository's tests. a coding agent knows its worktree and its conversation. a schema registry knows a published or deployed contract. a reviewer sees one proposed diff. org-wide code search sees merged trees, not proposals. each evaluates work locally, and the conflict does not exist locally. it exists between two proposals.

the state none of them holds is the organization's proposed future:

current software
+
provider proposal
+
consumer proposal
+
rollout proposal
+
other active dependencies
=
the future the organization is currently trying to create

a field rename is the smallest instance of the class. the same shape appears wherever independently produced work must agree: database migrations, event schemas, feature flags, rollout ordering. graphql is the running example not because this is a frontend problem, but because it is the rare boundary where both the dependency and the verdict are provable from artifacts alone, a property the rest of the argument leans on.

and the class is growing for a mechanical reason: ai coding tools let one engineer keep several workstreams moving at once, so implementation accelerates while coordination does not, and every additional concurrent proposal multiplies the pairs of proposals that can disagree. how often those pairs collide in practice, and what a collision costs, are open empirical questions. the argument that follows rests on the structure of the problem, not on its frequency.

a continuity problem

storytellers have a name for the solution to this problem: canon.

the hateful eight is told in six chapters around one haberdashery. chapter five, "the four passengers," is a flashback: it reveals that the four men already at minnie's haberdashery are a gang who murdered minnie and everyone else there earlier the same day. imagine the script under concurrent revision: one writer reworking chapter three, another reworking the chapter five flashback. current canon says minnie runs the haberdashery.

chapter 5 draft:
the gang murders minnie hours before the stagecoach arrives

chapter 3 draft:
minnie pours coffee for the new arrivals that afternoon

when the chapter 3 draft was written, it was consistent. once chapter 5 proposes minnie's death, chapter 3 is inconsistent with the future the writers are collectively proposing. if chapter 5 is revised and minnie survives, chapter 3 is consistent again without changing a word (the same green -> red -> green flip the consumer pull request went through, with the same unchanged artifact underneath).

canon also shows why this state cannot be kept as a flat bag of facts.

hard fact:
the chapter 5 flashback shows minnie's murder on screen

proposed fact:
the current chapter 5 draft kills minnie before the stagecoach arrives

intentional contradiction:
bob claims minnie left him minding the haberdashery. established canon
says she never would. he is lying, and the film plants the contradiction
as a clue

a continuity system must know where each claim came from, how strongly it is established, whether it is current or proposed, which future work relies on it, and whether an apparent contradiction is accidental or intentional. major warren runs exactly this check on screen: bob's story contradicts what canon establishes about minnie, so warren reads the contradiction as a lie rather than an error, and acts on it.

software organizations hold every equivalent form of state:

demonstrated:
the current schema contains Playlist.episodes

declared:
the playlist service owns that contract

proposed:
a provider pull request removes Playlist.episodes

dependent:
a consumer pull request references Playlist.episodes

inferred:
a service may rely on undocumented response ordering

superseded:
a later provider revision restores Playlist.episodes

intentional exception:
two incompatible proposals target mutually exclusive releases

an exact contradiction can safely fail a check. an inferred contradiction should remain uncertain. two apparently incompatible proposals may both be fine if they are mutually exclusive, ordered, feature-gated, or aimed at different releases.

this is not a generic knowledge problem. the goal is to maintain canon at the consequential boundaries where independently produced work must agree.

an endocrine system

canon explains what must remain coherent. the endocrine system explains how coherence can be maintained without centralizing every workflow.

in the body, an organ releases a hormone that changes behavior somewhere else. the producing organ does not know the target organ's internal implementation. the signal travels through shared circulation, and only cells with the matching receptor respond.

that maps onto software work:

gland....................producing workflow
hormone..................boundary-state signal
bloodstream..............shared plane
receptor.................dependency on a boundary
target organ.............affected workflow
physiological response...check, context update, gate, or revalidation
homeostasis..............organizational consistency

a provider workflow does not enumerate its consumers. it advertises that a boundary changed. only active work expressing a dependency on that boundary responds, and the receiver needs the changed contract, its provenance, and the evidence. it does not need the provider's internals.

this is not orchestration. an orchestrator owns execution: it assigns tasks, selects workers, sequences actions, gathers results, and resolves conflicts. it buys coordination by pulling every workflow into a shared execution plane that it controls. an endocrine system executes nothing. it distributes state to autonomous systems that keep control of their own behavior.

software workflows should keep the same autonomy. one engineer uses neovim. another uses claude code. a team hosts on github, gitlab, cursor origin, or an internal forge. a deployment system operates independently of all of them. none of that should have to change for the whole to stay consistent.

what they need is a protocol at their edges.

five invariants

this model collapses into familiar failure modes the moment it becomes another ide, agent harness, notification feed, ai reviewer, destination dashboard, or durable session. it collapses just as fast if every engineer must fill out a template to declare each dependency. five properties keep it from becoming those things:

  1. workflows remain autonomous.
  2. the shared plane never requires workflow internals.
  3. signals are typed, causal, and provenance-backed.
  4. only affected work receives a state change.
  5. uncertainty never masquerades as certainty.

the rest is these invariants turned into mechanism.

boundaries, receptors, and signals

the mechanism needs a small shared vocabulary.

boundaries

a boundary is an externally relied-upon property with an identity, an owner, a current state, a proposed state, and compatibility semantics.

graphql field
protobuf message field
openapi endpoint
package export
event schema
database column
configuration key
feature-flag behavior
rollout prerequisite

early systems should prefer machine-readable boundaries. "this team assumes the ranking algorithm feels roughly the same" may be a real dependency, but it is not precise enough to become a merge-blocking signal.

active work

active work is something the organization is currently attempting to make true:

pull request
branch
agent session
build
migration
deployment
rollout
design proposal

active work stays opaque. the shared plane gets an identity, a lifecycle state, an immutable source reference where possible, and the boundaries the work changes or depends on. nothing else. this is invariant 2 in practice.

receptors

a dependency is the receptor for a boundary signal. the playlist screen's query:

query PlaylistScreen($id: ID!) {
  playlist(id: $id) {
    episodes {
      id
      title
    }
  }
}

the operation resolves against the provider's schema, a binding the adapter reads from the consumer's own codegen configuration, itself a machine-readable artifact. the selection on line 3 therefore provably depends on Playlist.episodes. that receptor is discovered deterministically from the graphql ast and retained with exact provenance:

boundary:
Playlist.episodes

active work:
ios-client#87@abc123

location:
GraphQL/Operations/PlaylistScreen.graphql:3

evidence:
operation resolves against the provider base schema

confidence:
1

confidence 1 means the dependency follows from the ast and the schema, not from a guess. a string-built query, or a suspected reliance on undocumented response ordering, would carry lower confidence. lower-confidence receptors, as the precision rules below require, can inform but never gate.

no engineer annotates any of this. adapters infer exact dependencies from schemas, imports, generated metadata, deployment manifests, and other machine-readable artifacts.

signals

a signal is a typed boundary transition, not prose:

boundary.proposed      active work proposes a change to a boundary
boundary.invalidated   dependent work provably conflicts with a proposal
boundary.restored      a previous invalidation no longer holds
boundary.activated     a proposed change became current
boundary.withdrawn     a proposed change was abandoned
boundary.uncertain     analysis could not reach a verdict

the invalidation for the opening example is compact, causal, and auditable:

{
  "type": "boundary.invalidated",
  "boundary": "graphql://playlist-api/schema.graphql/Playlist.episodes",
  "cause": {
    "work": "github://playlist-api/pull/42",
    "head": "def456"
  },
  "affected_work": {
    "work": "github://ios-client/pull/87",
    "head": "abc123"
  },
  "evidence": {
    "base_valid": true,
    "proposed_valid": false,
    "path": "GraphQL/Operations/PlaylistScreen.graphql",
    "line": 3,
    "confidence": 1
  }
}

this is not an ai-generated summary of somebody's transcript. it is a small typed fact derived from immutable evidence.

adapters and the shared plane

an adapter translates one surface's artifacts into this vocabulary. a graphql adapter parses schemas and operation documents. a code-host adapter maps pull requests to active work. a migration adapter reads sql. adapters run next to the workflows they observe and may inspect whatever they need.

the shared plane stores what adapters publish: boundaries, receptors, active work, proposed transitions. a compatibility engine evaluates dependent work against current and proposed boundary states, emitting signals when verdicts change.

what this looks like in practice

no shipped system composes all of these pieces today. here is how they would fit together, on the example from the opening.

claude code builds the playlist screen and pushes it as ios-client#87 at sha abc123. the session stays open but idle. an engineer working in neovim opens playlist-api#42 at sha def456 with the schema rename. the two workflows share no ide, harness, transcript, plan, or agent runtime.

the graphql adapter has already recorded the receptor: ios-client#87 depends on Playlist.episodes. when playlist-api#42 appears, the adapter publishes a boundary.proposed transition for that field. the compatibility engine validates the consumer operation against both provider states:

provider base:
valid

provider proposal:
invalid

exact evidence, so the engine emits one boundary.invalidated signal.

the signal materializes where decisions are already made:

github:
a failing check on ios-client#87, annotated at the exact line

claude code:
an external context event in the idle session

ci:
a machine-readable compatibility failure

deployment:
a rollout gate

where evidence is incomplete, the same surfaces show a visibly neutral state instead, never green. no one opens a separate dashboard or reads another feed. the state appears where the affected work already lives.

when playlist-api#42 is revised to keep episodes, or withdrawn entirely, a boundary.restored signal retracts the invalidation. the failing check returns to green. the idle claude session receives the restoration. the consumer commit is abc123 throughout.

that is organizational homeostasis. a local change perturbs shared state, only the dependents respond, and restoring the boundary returns the system to consistency.

partial versions of this exist

pieces of this system exist today, one slice at a time. the honest claim is that nothing does this across slices.

a monorepo with atomic commits solves the code half of the playlist example: provider and consumer change in one commit, and one build graph evaluates every affected target together. but a monorepo buys atomicity by centralizing hosting, tooling, and ci: it is the shared workflow, not an alternative to needing one. even inside it, two unmerged in-flight changes can still disagree with each other, and no commit graph represents rollout or deployment state.

schema registries and breaking-change checks validate a proposed provider change against known consumers. consumer-driven contract testing is a close ancestor of the receptor idea: consumers record their expectations, and providers verify against them before deploying. merge queues compose proposals, but only at merge time, within one integration domain. each of these covers one boundary type, one repository, or one direction, and each evaluates proposed work against the current system or against registered, deployed consumers, almost never against other proposed work. and where contract testing asks every consuming team to author its own expectations, the receptor model moves that cost into the adapters, which infer expectations from artifacts.

deprecation cycles are the manual version of the missing signal. a provider that cannot see its consumers marks a field deprecated and waits months while traffic analytics drain. a query that lives only in an open pull request never shows up in traffic analytics at all.

the sharpest way to see the remaining gap is the opening figure. a ci check re-evaluates a pull request when that pull request changes, not when someone else's proposal changes. none of these systems watches two open proposals against each other and takes standing work from green to red and back while its own commits never change.

so the missing layer is not a better version of any one check. it is the circulation between them: a shared representation of boundaries, active work, and proposed state that any of these systems could publish into and subscribe to, with verdicts pushed back into the work they affect.

model less, not more

there is an obvious bad version of this idea: ingest every repository, issue, document, message, and agent transcript into an enormous semantic graph, then ask a model what might be related.

that system would be stale, noisy, and impossible to trust as a hard gate.

software organizations do not need an omniscient shared brain. they need precise state propagation at consequential boundaries. the adapter split from the vocabulary section is what makes that possible:

adapters:
inspect implementation-specific evidence

shared plane:
store only organizationally consequential state

adapters may inspect whatever their surface holds. an agent adapter may even know which branch or session owns a piece of active work. the shared plane still receives only the normalized boundary state, dependency, provenance, and compatibility verdict.

this separation matters for privacy, security, scalability, and trust. signals carry references, not content: a pull request id and a file path, not a diff or a transcript. it is not the whole privacy story: who may see the cause of a red state that originates in a repository they cannot read, and who may enumerate everything that depends on a boundary they own, are unresolved policy surface.

precision is existential

an endocrine system for software cannot behave like biological hormones in every respect. hormones are diffuse, concentration-based, probabilistic, redundant. software boundary signals must be:

typed
versioned
targeted
idempotent
causally attributable
permissioned
auditable
retractable

most importantly, the system must distinguish three outcomes:

failure:
exact evidence proves active work is inconsistent → intervene

success:
complete analysis found no incompatibility → pass

neutral:
not enough evidence to decide → stay visibly undecided

neutral is essential: invariant 5 in mechanism form, carried by boundary.uncertain. incomplete analysis must never become a false green. the same rule covers the system's own outages: when the shared plane or an adapter is down, dependent work shows neutral, visibly, never a stale green.

not:

a model thinks this may be related → interrupt everyone

one exact invalidation is valuable. twenty speculative warnings destroy trust, because false positives train engineers to override the check, and an overridden check protects nothing.

precision also answers the objection that proposed-vs-proposed comparison invites: my green work goes red because of someone else's draft. a red state produced this way is never anonymous: the signal names its cause, so the affected team sees exactly which proposal did it and why. whether red blocks merging can be the consuming workflow's policy rather than the plane's: one repository gates on it, another only annotates. and lifecycle can weight signaling: a draft never marked ready need not turn anyone red at all.

the difficult part is the proposed future

open pull requests are only the simplest representation of proposed state. real organizations maintain alternatives, staged migrations, mutually exclusive experiments, ordered rollouts, feature-gated behavior, and work targeting different releases. relations between pieces of active work carry that structure:

co-intended          two proposals meant to land together
ordered-before       one proposal must land before another
requires             one proposal cannot land unless another does
supersedes           one proposal replaces another
mutually-exclusive   at most one of the two can land
effective-after      a change takes effect only after a rollout step
gated-by             a change is inert until a flag flips

these relations change verdicts. two provider proposals that both restructure Playlist collide if composed. marked mutually-exclusive, they never appear in the same evaluated future, and both stay green. naively composing every active proposal would manufacture exactly such false collisions, along with an explosion of hypothetical futures. the system must evaluate the few futures the organization actually intends.

that requirement draws a line through the no-annotation rule. receptors are inferred: dependencies are frequent and mechanical, and no engineer should declare them by hand. intent relations likely have to be declared: no ast reveals that two proposals are alternatives. the line holds because intent is rare, author-owned, and high-leverage: declaring "this supersedes that" is closer to writing a commit message than to filling out a form. but selecting which futures to evaluate, out of everything currently proposed, is an open problem, and likely the hardest one in this design.

rollout state adds a second layer. a database migration may be compatible only under a particular sequence:

consumer accepts old and new
→ provider begins emitting new
→ historical data migrates
→ old path is removed

which is why the long-term problem is larger than pre-merge code analysis. it is consistency across code, rollout, and operational state.

the long-term system

at small scale, the system can live as a code-host application, reconciling all active work directly. at larger scale, it needs a temporal boundary graph with reverse indexes:

boundary → active dependents
work → boundary dependencies
work → proposed boundary changes

a boundary change recomputes only the affected subgraph. one plausible architecture:

append-only transition log
+
materialized temporal boundary graph
+
incremental impact workers
+
periodic reconciliation against authoritative sources

operationally this is a shared internal service, like an artifact registry or a ci fleet, most plausibly owned by a platform team and held to the failure rule above. that rule has teeth: if workflows gate on neutral, the plane becomes merge-critical for the whole organization; if they do not, an outage readmits exactly the unverified merges the system exists to catch. the operators inherit that tradeoff.

adapters can expand in stages. first, deterministic code contracts:

graphql
protobuf
openapi
package interfaces

value arrives before any network effect: one boundary type between one provider and one consumer delivers its first catch the first time it takes a standing pull request red for an exact, attributable reason.

then, multiple workflow surfaces:

github
gitlab
cursor origin
claude code
codex
ci systems

then, rollout-aware boundaries:

database migrations
event evolution
feature flags
deployment ordering
configuration contracts

these bind less statically than a graphql operation, so receptor confidence drops with the boundary class. the precision rule follows it down: below exact evidence, signals inform but never gate.

finally, a boundary protocol that lets external systems publish and consume typed boundary advertisements. at that point the system is no longer meaningfully a github application. github is one adapter. an agent harness is another. a schema registry, ci system, or deployment controller can participate without becoming the center of the organization's workflow.

a shared bloodstream, not a shared workflow

for machine-readable boundaries like a graphql field, a protobuf message, or an openapi endpoint, proposed work can be evaluated against proposed work deterministically. typed, causal, retractable signals can carry the verdicts into standing work without any workflow exposing its internals.

under that protocol, every independently operating workflow advertises changes to the boundaries it owns, expresses dependencies on boundaries owned elsewhere, and receives current consistency state. humans and agents keep their own tools. repositories keep their forges. services deploy independently.

the open problems are real: how often cross-proposal inconsistency bites, and what it costs. how declared intent selects the futures worth evaluating. how signal visibility crosses permission domains. who builds, operates, and keeps available enough of the plane and its adapters for coverage to matter.

but the shape of the missing layer is clear. it is not another workflow every team must join. it is circulation between the workflows teams already have.

that is the endocrine system software organizations are missing.