saascode

Road to Shopgraph

builds · aug 29, 2026 · 7 min read · product: Shopgraph

A small apparel brand's founder at her desk beside the stockroom, checking the Shopgraph dashboard before deciding on a restock

On 2026-05-05, Shopify shipped automatic store-event annotations, free, to every merchant on every plan. Four days later, Genesis surfaced the product concept that became Shopgraph. On 2026-05-19, a developer called Annotrack launched a Shopify App Store entry doing the same core job at entry-level self-serve pricing. On 2026-06-27, research ran and returned the verdict "uncontested position" three independent times, in three separate documents. Shopify's own changelog was not in the competitor table. Shopgraph is a queryable decision-memory layer for indie e-commerce sellers — it captures business decisions bound to their outcomes and makes the resulting history answerable in natural language. The differentiator we thought we were building had already evaporated. The one that survived was already in the schema.

Starting point

The conceptual framing came from the enterprise tier. Chord Commerce — a context-graph platform for merchants above the $20M GMV mark — had demonstrated that operational history made queryable was a commercially valuable asset. Chord does not serve the indie tier: its only call to action is "Speak to an expert," and its customers run at the scale of Sonos and Ruggable. The gap it declines to fill — sellers doing $500K to $10M in GMV, with the same decision problem and no product addressing it — was the opening.

A seller at that scale makes hundreds of decisions a year across campaigns, pricing, inventory, and listings. Very few are written down. Fewer still are bound to their outcomes. We took the "context graph for commerce" framing from Chord's public positioning and a landing pattern that shows the real product UI in the hero. The product concept, the buyer, and the mechanism we built from the gap itself: per-tenant corpus, semantic retrieval over that corpus, natural-language chat that refuses rather than fabricates, and an authenticated API letting external agents query the memory. No exact prior blueprint existed; the product assembles primitives from several engineering domains in a configuration that had not been built as a product before.

Reading the market

The research ran on 2026-06-27. It examined seven analytics vendors — Triple Whale, Helium 10, Jungle Scout, Lifetimely, Northbeam, Polar Analytics, and Chord. It found no seller-owned, queryable decision-memory product at the indie tier. Confidence: HIGH. That finding appeared three times, in three separate documents.

Shopify was not in the competitor table.

Here is the timeline that a later pass reconstructed:

2026-05-05. Shopify ships automatic store-event annotations — color-coded markers on analytics charts showing when store events occurred. Free. Every plan. "No setup and nothing to configure." This is event capture at $0 incremental cost, built into the platform every seller already pays for.

2026-05-09. Genesis surfaces the product concept. Four days after Shopify announced free annotations.

2026-05-19. Annotrack launches on the Shopify App Store: log any operational event with a date, a category, and a note; see before-and-after performance comparisons; export to CSV. Entry-level self-serve pricing, with a free tier up to a modest usage threshold.

2026-06-27. Research runs. Seven analytics vendors examined. The platform hosting every potential user is not in the table. The only risk the research identifies is messaging clarity. Build begins.

2026-06-28. v1.0.0 tagged.

2026-07-29. Shopify ships an API allowing third-party apps to write annotations onto merchant analytics charts.

The methodology had a single identifiable blind spot: it asked who else sells this, and never asked what the platform already gives away. Two of these events — the native annotations and Annotrack — preceded the research by weeks and were fully public. Nobody opened Shopify's own changelog. A platform changelog is a competitor source when your product lives inside that platform's ecosystem; the research had no step for it.

What survived. Shopify Help Center, verbatim: "You can't create or add your own annotations manually. Annotations are generated automatically from…" The platform annotates what it can derive. What it forbids is a merchant typing their own reasoning into those charts. That restriction is the seat it left open.

Annotrack's existence proves supply exists in the space. Its zero-review status eleven weeks after launch proves nothing about demand; it is one weak signal from a small independent developer in an early category. Annotation tools with a manual-entry model carry a consistent adoption problem — a feature that requires an ongoing habit is one that practitioners consistently leave unused, and that problem predates this product.

The gap that remains after the platform's move: outcome bound to the decision, semantically indexed, seller-owned, and queryable by an external agent in one corpus. That combination does not exist in Shopify's native tooling and is not what Annotrack offers.

The decisions that shaped it

Derived capture as a first-class schema primitive. source TEXT NOT NULL DEFAULT 'manual' CHECK (source IN ('manual','derived')) was in the database design from planning — before the SEO research identified derived capture as the surviving angle. It was a data-correctness decision: the system should distinguish system-inferred records from seller-entered ones. Every campaign launched, price adjusted, listing edited, and restock placed arrives as a derived record. The seller does not have to form a logging habit. Derived capture accumulates whether or not anyone forms one. This is the direct answer to the platform restriction.

Outcome auto-binding without seller discipline. A scheduled task pulls marketplace metrics at T+7 days and T+30 days after each decision and retrospectively binds actual results to the original record. The schema carries outcome_status, outcome_metrics, and outcome_captured_at. Capture without outcome binding is a diary. Binding on a timer, without requiring the seller to remember, turns the log into a causal record.

Re-embedding on outcome bind. Each decision is embedded in a semantic index when it is created. When the outcome binds — once the actual results are known — the record is re-embedded. A decision changes meaning when the result is known; the index reflects both states automatically. Re-embedding on bind was a non-obvious implementation choice: the record that was "we raised the price" becomes "we raised the price and organic ranking improved over 30 days" only after the window closes.

The grounded-refusal contract. The similarity threshold governing retrieval lives inside the database function that performs it — below application code, unreachable by any caller. When retrieval finds nothing above threshold, the system returns a structured refusal; no language model is called on an empty context. The demo ships with a deliberately empty embedding table: honest refusal is the correct behavior on an empty corpus, and it is encoded where it cannot be bypassed rather than enforced by convention in application code.

Read-only by design. The product answers about the past. All verbs available to external agents are read-scoped. Prescription, optimization, and writing back to marketplaces are out of scope by business definition — a ceiling chosen on purpose, not a gap.

The agent-queryable API gated to the middle tier. Three read verbs — query memory in prose, retrieve past decisions, find similar past decisions — are available to authenticated external agents on the Growth tier and above. Sellers at that tier can point any compliant external agent at their decision corpus. That composability is what annotation tools do not offer.

What fought back

The market moved and the build did not see it. This belongs in the log because a build log that only records wins is not a build log. The research asked the right questions about the wrong set of sources. Nobody opened the platform's own changelog. By the time the tag was cut, two of the four market events that restructured the competitive picture had been public for weeks. The scope never narrowed. The product documentation still asserts "uncontested position" verbatim. The correction happened in the SEO research pass, six weeks after v1.0.0. The lesson is a methodology finding: when the product lives inside a platform ecosystem, the platform's release notes are a competitor source and belong in the research step alongside the analytics vendors.

A critical authentication gap, caught before release. Six seller routes returned successful responses to unauthenticated users — the route matcher was missing entries for five route prefixes. All were fixed and re-verified to redirect correctly before the tag. Systematic, route-driven automated testing caught it; no buyer did.

The design that was planned did not ship. Planning materials specified a dark, data-cockpit aesthetic. The operator-generated design came back warm and light: paper-toned background, forest green primary, Plus Jakarta Sans paired with IBM Plex Mono, single light mode. The token specification was rewritten from the actual output. The catalog folder path retains the original slug as a path identifier only; the design it names is not the design that shipped.

Operational limits stated plainly. Outcome binding and sync tasks require a paid hosting tier for sub-one-hour scheduling intervals; the free tier's minimum is too long for the product to behave as designed. Sixteen non-critical security findings are tracked for the next patch release. Third-party API credentials — for embeddings, chat routing, and the Shopify connector — are operator-supplied; the product degrades gracefully until they are configured.

Deferred. Amazon connector support ships as a stub in v1.0 — the platform's approval process and dual-authentication complexity make sequencing it after the Shopify core the right call; no ingestion routes exist in the current release. Natural-language-to-SQL execution is deferred: permitting a language model to generate and run SQL against a multi-tenant database, without a validated isolation architecture in between, is a data exposure risk. The v1.0 natural-language path uses retrieval over indexed records and a deterministic query-template library only.

What shipped

A complete multi-tenant build: v1.0.0 tagged, deployed against a live remote database, every route authenticated and the full schema row-level-secured, no critical security findings. Each seller tenant is an isolated decision corpus — the isolation is structural, not a configuration option.

The shipped capability set: Shopify ingestion with OAuth, signed webhook verification, and delta sync; derived and manual decision capture; outcome auto-binding on a timer; per-tenant semantic index with re-embedding on bind; natural-language chat that refuses rather than fabricates; a deterministic query-template library for structured commerce analytics; an agent-queryable API gated to the middle tier; cross-tenant instance management; and three subscription tiers driven from the database.

The product that emerged from contact with the market is narrower and more honest than the one that was planned. The platform gave away event capture and AI conversation at $0; what it forbids is a merchant recording their own reasoning, and what it does not provide is outcome binding, semantic re-indexing once results land, and a corpus queryable by an external agent. That is what shipped. The moat compounds slowly — it is worth a year of a seller's data. The pitch that survives is the derived half: the half that accumulates without asking anything of the seller.

See it

See Shopgraph →

end