Skip to content
C.W.K.
Stream
Lesson 03 of 04 · published

A Rejected Feature Is Not a Backlog Item

~12 min · constraints, resource-ownership, siblings, scope

Level 0Raw Ore
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"'Add live prices' is a rejected feature, not a backlog item."

A constraint that comes from next door

The market data plan allows one live streaming connection per asset class, and the portfolio sibling's serving process already holds it. That app is running, in production, using that connection to do its job.

So Touchstone is REST-only against that provider — permanently. Not "until we upgrade the plan", not "until we build a shared connection broker". The architecture doc spells out the consequence in the strongest available terms, and the wording is the lesson: a rejected feature, not a backlog item.

The difference is not tone

A backlog item is a promise with the date left blank. It sits in a list, it gets re-estimated, and every few months someone asks whether now is the time. It shapes design too: people leave seams for it, write abstractions "so we can swap this later", and defend those seams in review against people who correctly point out that nothing uses them.

A rejected feature is a closed question. It changes what you build: no streaming seam, no adapter interface with one implementation, no configuration flag reserved for the day it arrives. And crucially, it changes what happens when someone proposes it — the answer is not "good idea, it's in the backlog", it is "here is why that is somebody else's connection."

Record the reason, not just the decision. "No live prices" invites relitigation every time a new person joins. "One connection per asset class, owned by the portfolio app's serving process" cannot be relitigated without changing a fact about the world — and if that fact ever does change, the note tells you exactly which fact to check.

Resource ownership between sibling apps

The general pattern is worth extracting, because it shows up wherever a group of small applications shares an external allowance: one paid seat, one API rate limit, one webhook registration, one OAuth app, one outbound IP on an allowlist.

The failure mode is quiet and specific. Nobody writes down who owns it, two apps use it, and the second one appears to work — right up until the first one's connection gets dropped by the provider because a newer session claimed the slot. The symptom lands on the app that did nothing wrong, which is the worst possible place for a symptom to land, because it is the one place nobody will be looking for a cause.

The fix is cheap and has to be done early: name the owner in the architecture document of both apps, and state the consequence for the non-owner. Here the non-owner's line is unambiguous — REST-only, permanently, against that provider.

Note what it does not forbid. The constraint is about one provider's streaming budget. It does not stop Touchstone reading a different library for Korean and Japanese quotes, or a public macro source for the series behind its gauges. A well-scoped constraint names the exact resource — a vaguely-scoped one ("do not use external data") would have prevented most of the product for no reason.

Code

The shape of a shared-allowance constraint, written down once·text
RESOURCE:  one live streaming connection per asset class
ALLOWANCE: the market data plan
OWNER:     the portfolio app's serving process (in production)

CONSEQUENCE FOR THIS APP:
  REST-only against that provider, permanently.
  "Add live prices" is REJECTED, not deferred.

WHAT IT DOES NOT FORBID:
  - a different library for KR / JP quotes
  - public macro series for the gauge inputs
  - any amount of REST polling within the daily cadence

WHAT WOULD REOPEN IT:
  the plan's per-asset-class limit changing, OR
  the portfolio app releasing the connection
  -> named facts, so a future reader knows what to re-check

External links

Exercise

List the external allowances your systems share — API rate limits, paid seats, webhook registrations, allowlisted IPs, single-instance integrations. For each, write down the owner and what the non-owners are therefore forbidden to do. Any allowance where you cannot name an owner in one line is a live incident waiting for the week when two teams get busy at once.
Hint
The dangerous ones are the allowances that fail silently for the owner rather than loudly for the newcomer. If the provider's behavior on limit is 'drop the oldest session', the symptom appears in the app that has been running correctly for months.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.