Arkive

Synergy: system design

As of
Version1.1.0
Kindspec
Length3,056 words, about 13 min
Tagssystem-designsynergy

How Synergy is built. The PRD and spec say what it does; this page and the decisions it links say where each piece lives and how the pieces meet. Terms follow Mentions and link lifetime.

Packages

synergy-packages

An arrow means "imports". The features registry and the type packages register their linkable types with synergy/server; apps/web renders links with synergy/react. Only foundation/core talks to Postgres.

PackageHolds
packages/core (foundation)DB client and RLS (withRLS), auth (resolveApiCaller), withApiGuard, entitlements, logging. Unchanged by Synergy.
packages/platform/synergy (platform)Synergy's tables and migrations, its repository (the only access path), the rules, the resolver and renderer contracts, the save call, and the Rich Live Link component.
packages/ui (foundation)Design-system primitives the component builds on; later the editor and the Lexicon matcher.
Providers (packages/ops now, features later)Their own entity tables, plus one registration per linkable type.
packages/features-registry or the appAssembles every provider's registrations into the maps Synergy receives as data.
apps/webGuarded API routes and the playground.

Synergy ships three entry points, so a browser bundle can never pull in database code:

  • @sidekick/synergy/server: the repository, the save call and the resolvers' contract. It imports server-only.
  • @sidekick/synergy/react: the Rich Live Link component and the renderers' contract. No database code, so it runs on the server and in the browser.
  • @sidekick/synergy/contracts: zod schemas and types shared by both, the content helpers (extractRefs, the quote re-matcher) and the error codes.

See Platform layer and Dependency flow.

Type registration

Each linkable type is registered by the package that provides it, never listed in Synergy. The registration comes in two halves, a server half and a React half, one per entry point:

TypeScript
// server half, imported from '@sidekick/synergy/server'
interface LinkableTypeServer {
   provider: string; // the registering package, e.g. 'ops', 'taxila'
   type: string; // e.g. 'note', 'datum', 'tweet'
   entitlement: string; // feature key whose entitlement gates it, e.g. 'sandbox'
   // batched: one call per provider per page; returns JSON only, so it can be cached and sent to any consumer
   resolve(
      tx: Tx,
      requests: readonly ResolveRequest[],
   ): Promise<ReadonlyMap<string, RenderData>>;
   // writes an anchor mark into the target's content when a link to a passage is made; returns the anchor id
   addAnchor(tx: Tx, entityId: string, at: PassageAddress): Promise<string>;
}

// React half, imported from '@sidekick/synergy/react'
interface LinkableTypeReact {
   type: string;
   render(data: RenderData, display: "card" | "preview"): ReactNode; // pure: no fetching, no hooks, no browser APIs
}

resolve fetches and always runs on the server; render only turns the fetched data into React, so it runs wherever the component runs. Sidekick renders in both places: in a server component for a page's first paint, and in the browser when the editor inserts or changes a link, where the component fetches the new link's data through POST /links/resolve and renders it on the spot. A third party (Notion, Slack, a bot) uses the same JSON and renders it its own way. The registry or the app builds both maps and passes them to Synergy, so neither core nor Synergy imports a provider (research 05, option A). Feature flags are separate and come later.

Keys, never copy

Synergy holds no user-visible text (Centralized copy; Pratik, 2026-10-31). Everything it stores or returns is a stable key, and every label comes from packages/copy, so a term can be renamed or translated without a migration or an API change:

  • provider and type on registrations and index rows (ops, note): the type's label ("Note") is a copy key such as synergy.type.ops.note.
  • Relation types store a source_key and a target_key, named by the end that reads them (explained-by at the source, explains at the target); "explained by" on screen comes from copy. User-defined types (post-MVP) are the exception, because their names are the user's own content.
  • Statuses, states, marks and display types are enums (deprecated, no_longer_linked, passage_removed), and error codes carry no message; the client looks up the message by code.
  • The resolved link and every API response carry keys only. Sidekick's UI and the Rich Live Link map them through copy; a third party maps them its own way.

User content (titles, display names, labels, change notes, tag names) is stored as written.

Tables (Synergy's migrations)

synergy-tables

An arrow points from a table to the tables that hang off it. relationships.from_id and to_id are entity_index ids (left out of the drawing to keep it readable). The outbox and idempotency keys are not synced and are hard-deleted.

Every table: client-generated UUIDs, user_id, created_at, updated_at, provenance (actor kind: person, system, agent or API key; actor id; reason), and RLS comparing user_id = nullif(current_setting('app.current_user_id', true), '')::uuid. Syncable tables soft-delete; every unique index on them is partial (WHERE deleted_at IS NULL), so a tombstone never blocks re-adding the same tag or saving the same item again. How tombstones stay visible to Synergy is in Tombstones.

  • entity_index: id, provider, type, display name, optional title, status (active, deprecated, superseded), version, revision, content_seq, edited_at, deleted_at. "Deleted" is shown from deleted_at, not stored as a status, so a restore brings back whatever status the entity had. No external-reference columns (Capture external content).
  • content_seq goes up on every write to an entity's content: revision saves, version saves, and anchors added for someone else's link. It is the token for the stale-write check, the ETag and the render cache key. version and revision keep their meaning and only drive the dots (Content sequence).
  • version_log: entity, version, optional change note, actor, time.
  • entity_anchors: entity, anchor id, removed_in_version (empty while the passage exists). One row per passage that a link points at, written when the first link to it is made. A reference whose anchor row has removed_in_version set shows "passage removed".
  • entity_mentions: entity, relationship id. The direct and alias mentions in the entity's content, as last reported by its provider (Save content). relationships.mentioned is kept true while the relationship's source has a row here.
  • relationships: from, to, role (solo, list or member), parent and position (members), optional label, type (never empty), version and revision snapshot, to_anchor_id and to_anchor_quote (empty for a whole-entity target), cited, mentioned, tombstone (actor, reason, deletion_batch_id).
    • Members copy their list row's from, type and role into a composite FK (parent_id, from_id, type, parent_role) → (id, from_id, type, role) with parent_role fixed to list by a CHECK, so a member can't point at another member and every member is a complete edge with its own type. A list row has no to; solos and members do (CHECK).
    • type is NOT NULL so the FK can't be skipped (Postgres ignores a composite FK when any column is null). An untyped link uses the seeded system type untyped, kind reference, which displays no type name.
    • Positions are fractional text keys (lexorank) with a unique index on (parent_id, position), so moving one member writes one row.
    • deletion_batch_id groups the tombstones written by one delete, so a restore brings back exactly that batch.
  • relation_types: source_key (the type's identity, which relationships.type references), target_key, kind (reference or association; untyped and superseded-by are system rows of kind reference, not extra kinds), status, system flag; seeded with the starter vocabulary plus untyped. Labels live in copy.
  • tags and tag_applications: as in the spec, with the format check constraint.
  • outbox: event type, subject, actor, payload, time, and xact_id (pg_current_xact_id()), which lets a reader process events in commit order. A long transaction can commit a lower bigserial id after a reader has moved past it; the transaction id can't be rebuilt later, so it is stored from the first row. Event types: entity created, content saved, version bumped, status changed, entity deleted, restored or erased; relationship created, updated (label or type), cited, uncited, deleted or restored; snapshot moved (the referencer confirmed the link still holds); passage removed; tag created, renamed, merged or deprecated; tag applied or removed. Read by a dedicated read-only role outside RLS, since readers work across users. 90-day retention after every reader has processed it.
  • idempotency_keys for creates.

The outbox and idempotency keys are non-syncable: hard delete, no soft-delete triggers, so pruning works.

Each provider table has a deferrable foreign key to entity_index(id), so a provider row can't exist without its index row.

Tombstones

Synergy must see its own tombstones: a deleted target still shows its name, "No longer linked" must differ from "never existed", and undo and restore update deleted rows. Three of the existing database templates prevent that, so Synergy departs from them (Tombstone visibility):

  • RLS compares only user_id. The repository filters deleted_at IS NULL in each query that needs live rows. The template in Row-level security also hides deleted rows in USING.
  • Restore may update a deleted row. The update trigger allows an update to a deleted row only when it restores it (NEW.deleted_at IS NULL). Every other update to a tombstone is still refused.
  • Hard delete only on the non-syncable tables (outbox, idempotency keys), which carry no soft-delete triggers.

Indexes

to_id (backlinks), (to_id, to_anchor_id) (passage check), from_id, the unique (parent_id, position), entity_anchors (entity_id, anchor_id), entity_mentions (entity_id) and (relationship_id), tag applications by tag, index rows by owner and status, an index on outbox xact_id, and the search indexes. Trigram and full-text GIN indexes lead with user_id (btree_gin: (user_id, display_name gin_trgm_ops) and the same for the simple tsvector), so a search reads one user's rows instead of every user's.

Write path

A provider saves inside one withRLS transaction: it writes its own row, then calls Synergy in the same transaction.

synergy-save

Every Synergy write takes the per-user lock first: pg_advisory_xact_lock(hashtextextended(user_id::text, 0)), before it reads or writes anything. That covers the delete block and the cycle check against each other (a delete and a new reference into the same target can't both commit), and one fixed lock order means no deadlocks between a save and a link create. For one user the contention is negligible.

  • Create: register the entity's index row (id, provider, type, display name).

  • Save content: the provider sends the base content_seq, revision or version, the optional change note, and the current sets it extracts from the new content with extractRefs: every block and anchor id, and every relationship id the content mentions. It also declares the links this save creates (below). Synergy then:

    1. checks content_seq (409 stale_content on a stale one);
    2. compares the sets with entity_anchors and entity_mentions itself;
    3. refuses passage_referenced if a reference points at an anchor that's gone and this isn't a new version; on a new version, sets removed_in_version on those anchor rows;
    4. tombstones associations into gone anchors, moving only their sources' updated_at (actor system, with the reason);
    5. refuses a mention whose relationship has neither end at this entity;
    6. updates entity_mentions and mentioned, and tombstones links with neither cited nor mentioned;
    7. bumps content_seq, the revision or version, and edited_at, and writes the outbox events.

    Sending the current set instead of the changes makes the call self-healing (a missed or buggy save is corrected by the next one) and safe to retry, and the comparison is written once, in Synergy (Anchors in content).

  • Link from content: the editor generates the relationship id, writes it into the mark, and the save that carries the mark declares the new link (target, anchor, type, label). Synergy creates it in that transaction with mentioned = true and cited = false, so removing the text later removes the link.

  • Link from a field, the links panel or the API (POST /links): creates a cited link (cited = true).

  • Every link create snapshots the target's version and revision and runs the cycle check for a reference. A passage target calls the target provider's addAnchor, which writes the mark into the target and moves its content_seq and updated_at, never its version or revision. The response carries an anchor receipt per passage target, { targetId, contentSeq, anchor: { id, blockId, quote } }, so an editor in the same page that has the target open adds the mark itself and moves its base content_seq (no 409). Not the whole target: version and revision don't change on an anchor write, and the request was about the source. An editor the receipt can't reach (another tab, another device) gets 409 on its next save; it fetches the latest content, copies in the anchors it lacks (by block id and quote) and saves again, with nothing shown to the user. The 409 merge is the guarantee; the receipt only saves a round trip.

  • Supersede: a superseded-by link, stored from the old entity to each replacement, kind reference. An entity may have any number of successors. Creating the first one marks the source superseded, after the confirmation that reports how many entities reference it (confirmation_required until the request confirms). Removing the last one sets the source back to active.

  • Status, tags, cite and uncite: metadata writes that bump no counter.

  • Delete: refused with delete_blocked while a live reference points at the entity; otherwise soft-delete, which tombstones its outgoing links under one deletion_batch_id. Erasure overrides.

  • Restore and undo (restore an entity, undo an unlink, relink): bring back the same rows, but only after re-running the delete block and the cycle check under the lock, because the graph may have changed since. A restored reference into a tombstone, or one that would close a cycle, is refused with restore_conflict, naming each edge.

Read path

  1. The guarded route reads the caller's relationships joined to the target index rows: one query per page, cursor-paged.
  2. For each link it decides the state on the server, before any resolver runs: unknown (the type's provider isn't registered; shown like locked), locked (the type's entitlement isn't enabled for the caller), deleted, redacted (later), then the marks (edited, changed) and "passage removed" from the snapshot and entity_anchors.
  3. Inline and minimal mentions need nothing more. Card and preview mentions are grouped by provider and resolved with one batched resolve call each, through the render cache keyed by (entity, content_seq, display type).
  4. The cache holds render data only. Status, states and marks are read fresh from the index on every request, including the states of links shown inside a live preview: a preview's render data carries relationship ids, never their states.
  5. The response is the resolved link (frozen as a zod schema in /contracts): relationship, target index fields, state, marks, and render data when asked for. An entity's read response also carries the roll-up of its outgoing references and ETag: "<content_seq>".

API

Entity content (create, save, delete, restore) goes through each provider's own routes, which call Synergy in the same transaction. Synergy's routes, all through withApiGuard, under /api/synergy:

Method and pathRequestResponseErrors
GET /entities/:idIf-None-Match (optional)index fields, roll-up, ETag; 304 when unchangednot_found
PATCH /entities/:id/status{ status: 'active' | 'deprecated' }index fieldsnot_found
GET /entities/:id/versionscursorversion log pagenot_found
GET /entities/:id/linksdirection (out or in), cursorresolved links page (in = backlinks)not_found
POST /linksid, from, to, anchor, type, label, confirm; idempotencyresolved link, anchor receiptcycle, locked, deprecated_vocabulary, confirmation_required, not_found
PATCH /links/:idlabel, type, cited, list positionresolved linkcycle, deprecated_vocabulary, not_found
DELETE /links/:idnonetombstonenot_found
POST /links/:id/restorenoneresolved linkrestore_conflict, not_found
POST /links/:id/snapshotnone (moves the snapshot: "still holds")resolved linknot_found
POST /links/resolve[{ relationshipId, display }]resolved links, in request ordernone per item: a missing one resolves as not found
GET /searchq, type, provider, status, tag, cursorindex rows pagenone
GET /tags, POST /tagscursor; name, description; idempotencytags page; taginvalid_tag
PATCH /tags/:idrename, description, deprecate, merge intotaginvalid_tag, not_found
PUT / DELETE /tags/:id/applicationsentity or relationship idapplicationdeprecated_vocabulary, not_found
GET /relation-typesnonevocabularynone

POST /links/resolve is how a client asks for card and preview data: the server never parses content, so only the client knows each mention's display type.

"Page updated"

A page someone is viewing or editing can learn that the entity changed elsewhere (another device, an agent, a bot) and offer "Page updated, reload". The foundation is already in the API: GET /entities/:id with If-None-Match: "<content_seq>" answers 304 with no body while nothing changed, so a check is one indexed read. Any module's page can use it, because the check is per entity in Synergy, not per module.

  • MVP client strategy (built with the shared editor, not in Phase 3): check when the tab regains focus or becomes visible, and every 30 seconds while it is visible; tabs of one browser tell each other through BroadcastChannel. While editing, the banner warns early; the 409 merge still protects the save.
  • Post-MVP: push instead of polling, fed by the outbox (server-sent events or Supabase Realtime broadcast from the server). It changes how the client hears about a change, not the API.
Error codeHTTP
validation failure400
not signed in (from the guard)401
locked (link into a provider the account doesn't have)403
not_found: also for another user's ids, so a response never reveals whether an id exists404
stale_content, delete_blocked, passage_referenced, cycle, restore_conflict, confirmation_required409
invalid_tag, deprecated_vocabulary422

Lives in Synergy (/react) and builds on ui primitives. It renders on the server and in the browser. It takes the mentions to show and a transport, resolveLinks(requests) => Promise<ResolvedLink[]>, so the host decides how the request travels: a Sidekick server component calls the same handler as POST /links/resolve, Sidekick's browser code (the editor inserting a link) calls the route with the session cookie, and a third party calls it with its own credentials. It owns the frame and every state, and calls the registered renderers with the resolved render data. The display type belongs to each mention.

Content helpers

  • extractRefs(content) walks Tiptap JSON and returns the block and anchor ids and the mentioned relationship ids. Every provider uses it to build the sets for the save call.
  • The quote re-matcher finds a quote in new content: Markdown import and Refresh of captured external content use it to re-attach anchors. When the best match is weak, the user is asked instead of the match being guessed.
  • Post-MVP candidate: a block-level patch endpoint for bots and agents, which handle whole Tiptap documents with marks they don't understand poorly.

Testing

Integration tests through the guarded API are the main seam; the component is tested in Vitest browser mode with MSW (Testing layers). Synergy adds:

  • Race tests with two database connections: an anchor added while the target is open (stale save gets 409), a delete and a new reference into the same target (one fails), and a restore after the graph changed (restore_conflict).
  • A test pinning spec story 71 ("dep wor" finds "deep work"), tuning trigram word_similarity until it passes.
Arkive

Index

Notes, decisions, and progress on my journey as I build Project Sidekick — built in the open; written as it happens.

Tags (150)

View

258 entries.

As ofTitleKind
2026-10-31Content sequencedecision technical architecture-decision synergydecision
2026-10-31React as peer dependencydecision technical architecture-decision monorepo reactdecision
2026-10-31Tombstone visibilitydecision technical architecture-decision synergy rlsdecision
2026-10-31Anchors in contentdecision technical architecture-decision synergy anchorsdecision
2026-10-31Capture external contentdecision technical architecture-decision synergy taxiladecision
2026-10-31Mentions and link lifetimedecision technical architecture-decision synergydecision
2026-10-31Platform layerdecision technical architecture-decision monorepo synergydecision
2026-10-31Synergy store choicesdecision technical architecture-decision synergy postgresqldecision
2026-10-31Synergy: system designReadingsystem-design synergyspec
2026-10-31Synergy - Feature Specificationsprd spec synergyprd
2026-10-31Entities and the Entity Indexprd feature synergyprd
2026-10-31Foundationsprd feature synergyprd
2026-10-31Keeping Links Trueprd feature synergyprd
2026-10-31Relationshipsprd feature synergyprd
2026-10-31Rich Live Linkprd feature synergyprd
2026-10-31Scope and Phasesprd feature synergyprd
2026-10-31Dependency flowsystem-design monorepo clispec
2026-10-31ESLint plugin boundariessystem-design code-quality-check eslintspec
2026-10-31Phase 3 graph store metadata serviceplan living-plan phase-3 api-guard rls postgresql api offline graphplan
2026-10-30Lexicon highlightingdecision technical architecture-decision synergy taxiladecision
2026-10-30Testing layersdecision technical architecture-decision testingdecision
2026-10-30Testing layerssystem-design testing vitest playwrightspec
2026-10-30Search and Backlinksprd feature synergyprd
2026-10-30Tagsprd feature synergyprd
2026-10-30Design constraintssystem-design global-tagging-and-linking rls offline soft-deletespec
2026-10-29Cost to Add Laterprinciple product engineeringguidance
2026-10-27Individual Firstprinciple productguidance
2026-10-27One Interfaceprinciple api cliguidance
2026-10-27One interface for every consumerdecision technical architecture-decision api clidecision
2026-10-27Overview of Synergyprd feature synergyprd
2026-10-24Lesson 8: Phase 2 close-outplan phase-2 task guidanceplan
2026-10-24Phase 2 lesson 7 walkthrough: the ops package and entitlements grantbuild walkthrough phase-2 feature-system database postgresql cliguidance
2026-10-24Phase 2 walkthroughbuild walkthrough phase-2 api-guard feature-system rls authenticationguidance
2026-10-24Phase 2 lesson 3 walkthrough: entitlementsbuild walkthrough phase-2 feature-system database drizzle rls postgresql testingguidance
2026-10-24Phase 2 lesson 4 walkthrough: withApiGuardbuild walkthrough phase-2 api-guard rls api authentication testingguidance
2026-10-24Phase 2 lesson 5 walkthrough: request and auth-failure loggingbuild walkthrough phase-2 api-guard observability eslint testingguidance
2026-10-24Phase 2 lesson 6 walkthrough: /api/health and guard verificationbuild walkthrough phase-2 api-guard api nextjs testingguidance
2026-10-24Phase 2 lesson 2 walkthrough: resolveApiCallerbuild walkthrough phase-2 api-guard authentication supabase testingguidance
2026-10-24Lesson 7 (task 2.10): dev entitlement seed scriptplan phase-2 task feature-system database postgresqlplan
2026-10-24Phase 2 build rules and target designplan phase-2 api-guard rls api authentication typescript guidanceplan
2026-10-24Phase 2 lesson 1 walkthrough: feature registrybuild walkthrough phase-2 feature-system typescript monorepo testingguidance
2026-10-24Pre-2 walkthroughbuild walkthrough pre-2 rls supabase drizzle postgresql testing eslintguidance
2026-10-24Agent guideai-coding agent gateway agent-guidance rls supabase drizzle api react prettierguidance
2026-10-24Backlogged unplannedplan living-plan backlog feature-system taxila zinsser alter-ego parrot rls supabaseplan
2026-10-24Commands and environmentai-coding command environment agent-guidance prettier pnpm cliguidance
2026-10-24Living implementation planplan living-plan taxila zinsser alter-ego war-room factory parrot core-driveplan
2026-10-24Phase 2 core infrastructure API guard feature system completeplan living-plan phase-2 api-guard rls api authentication feature-systemplan
2026-10-24Phase 9 API keys CLIplan living-plan phase-9 taxila api-guard rls api authentication cliplan
2026-10-24With API guardsystem-design security api-guard rls api authentication typescriptspec
2026-10-23Lesson 3 (tasks 2.8, 2.9): entitlements table and getEnabledFeaturesplan phase-2 task feature-system database drizzle rls postgresql testingplan
2026-10-23Lesson 4 (tasks 2.2, 2.3): withApiGuard with withRLSplan phase-2 task api-guard rls api security testingplan
2026-10-23Lesson 5 (tasks 2.4, 2.5): request and auth-failure loggingplan phase-2 task api-guard observability eslintplan
2026-10-23Lesson 6 (tasks 2.11, 2.12): /api/health and guard verificationplan phase-2 task api-guard api nextjs testingplan
2026-10-23Centralizedsystem-design observability api authenticationspec
2026-10-23Database and securityai-coding database security agent-guidance api-guard rls drizzle api react repository-patternguidance
2026-10-23Error handlingsystem-design observability api-guard rls supabase api nextjs react aispec
2026-10-23Phase 1.1 DB RLS enforcementplan phase-1.1 rls database supabase drizzle postgresql api typescriptguidance
2026-10-23Checkpoint B walkthroughbuild walkthrough phase-0 checkpointguidance
2026-10-20Lesson 2 (task 2.1): resolveApiCallerplan phase-2 task api-guard authentication supabase nextjsplan
2026-10-18Lesson 1 (tasks 2.6, 2.7): FeatureManifest and ALL_FEATURESplan phase-2 task feature-system typescript monorepoplan
2026-10-18Registrysystem-design feature-systemspec
2026-10-17Core Drive to be Practical and Grounded in Realitysystem-design feature core-drive prdprd
2026-10-17MVP Scopeprd mvp specification core-drive taxila war-room factory alter-ego zinsser parrot api cli native-appprd
2026-10-17An AI Writing Coach and an Appsystem-design prd feature zinsser aiprd
2026-10-17Overview of Taxilasystem-design prd feature taxila ragprd
2026-10-16Best practice rulessystem-design code-quality-check eslintspec
2026-10-16ESLint best practice rulesdecision technical architecture-decision eslint typescript nextjsdecision
2026-10-16Stay on ESLint revisit oxlintdecision technical architecture-decision eslint typescriptdecision
2026-10-16Pre 2 foundation hardening completeplan pre-2 foundation security database testingplan
2026-10-16Portable documentation vaultopportunity documentation agentic-coding portability severity-mediumopportunity
2026-10-16Prettier at repo levelsystem-design code-quality-check prettierspec
2026-10-16Server actionssystem-design nextjs rls api authenticationspec
2026-10-15Pooler client configurationopportunity phase-2 database supabase drizzle severity-mediumopportunity
2026-10-14Vitestdecision technical architecture-decision testing vitest monorepodecision
2026-10-14App runtime role for Drizzledecision technical architecture-decision rls supabase drizzledecision
2026-10-14Profile creation Postgres triggersystem-design security postgresql api authenticationspec
2026-10-14Profiles schemasystem-design security rls authenticationspec
2026-10-14Tag taxonomyai-coding agent-guidance taxonomy discoveryguidance
2026-10-13Anatomy of a Core Drive Entrysystem-design prd feature core-driveprd
2026-10-13Core Drive Stores Personal and Sensitive Informationsystem-design prd feature core-drive taxila graphprd
2026-10-13Core Drive Stores Values Onlysystem-design prd feature core-drive war-room factoryprd
2026-10-13Core Drive to Foster Reflections and Learningssystem-design prd feature core-driveprd
2026-10-13Model Routingprd vercel ai embedding routingprd
2026-10-13Overview of Core Drivesystem-design prd feature core-drive factory ai alter-egoprd
2026-10-13Phase 0 — Foundation and Toolingplan phase-0 api nextjs typescript eslint turborepo pnpmplan
2026-10-13Source Attributionprd feature alter-ego aiprd
2026-10-12Command Paletteprd ux specificationprd
2026-10-12MVP Design Objectiveprd ux specificationprd
2026-10-12Be the Best Version of Yourselfprd value-proposition specificationprd
2026-10-12Make the Right Behavior Easierprd value-proposition specificationprd
2026-10-11Solve Problems and Build Thingsmotivation creativityjournal
2026-10-11A Personal Discoverymotivation discipline bucket-list ambition entrepreneurship sidekickjournal
2026-10-11Commercialize Sidekickmotivation finance freedomjournal
2026-10-10Realityprinciple reality pragmatism survivalguidance
2026-10-10Seek Closureprinciple productivity happiness purposeguidance
2026-10-08No Do-oversprinciple core-drive execution productivityguidance
2026-10-08Pragmatismprinciple practical pragmaticguidance
2026-10-04Protect Your Mind and Your Timeprinciple productivity automation minimalismguidance
2026-10-03Focus Funnelprinciple core-drive productivityguidance
2026-10-02Fuel Career Growthmotivation career ambitionjournal
2026-10-02Learnmotivation learning ai ragjournal
2026-09-19A graph pattern not a graph databasesystem-design global-tagging-and-linking postgresql graphspec
2026-09-19Actual stateglossary terminologyglossary
2026-09-19Algorithm of lifeglossary terminology nextjsglossary
2026-09-19Alter egosystem-design prd feature taxila alter-ego factory aiprd
2026-09-19API firstsystem-design api clispec
2026-09-19API route fail openopportunity phase-2 api security eslint severity-lowopportunity
2026-09-19API versioningsystem-design apispec
2026-09-19App runtime for Drizzlesystem-design database drizzle postgresqlspec
2026-09-19Approve buildssystem-design monorepo nextjs pnpmspec
2026-09-19Architectural driverssystem-design offlinespec
2026-09-19Architecture invariantsai-coding architecture invariant agent-guidance api nextjsguidance
2026-09-19Asynchronoussystem-design rag embeddingspec
2026-09-19Atomicsystem-design rag embeddingspec
2026-09-19Authenticationsystem-design security taxila api authentication pwa mobile clispec
2026-09-19Background jobssystem-design vercel background-jobspec
2026-09-19Best practicesai-coding-harness agent-guidance drizzle api react pnpm css offline embedding soft-deleteguidance
2026-09-19Build for today designed for futuresystem-design offlinespec
2026-09-19Bundle everythingsystem-design monorepospec
2026-09-19Capacitorsystem-design native-app nextjs mobile offlinespec
2026-09-19Centralizedsystem-design feature-systemspec
2026-09-19Centralized and client agnosticsystem-design security rls api authentication clispec
2026-09-19Centralized copydecision technical architecture-decision authentication typescript clidecision
2026-09-19Centralized copysystem-design contentspec
2026-09-19Checkpoint aplan phase-0 checkpoint nextjs typescript turborepo pnpm cliplan
2026-09-19Checkpoint bplan phase-0 checkpoint eslint prettier turborepo pnpmplan
2026-09-19Checkpoint cplan phase-0 checkpoint nextjs pnpmplan
2026-09-19Checkpoint dplan phase-0 checkpoint api-guard rls supabase drizzle api authenticationplan
2026-09-19CLIsystem-design cli apispec
2026-09-19Context assemblersystem-design ai war-room factory api-guardspec
2026-09-19Coresystem-design feature-systemspec
2026-09-19Corepacksystem-design monorepo pnpmspec
2026-09-19CSS modulessystem-design css eslint mantinespec
2026-09-19DB access chokepointopportunity phase-2 database rls architecture severity-highopportunity
2026-09-19dotenv CLIdecision technical architecture-decision clidecision
2026-09-19dotenv CLIsystem-design config clispec
2026-09-19Driving forces and key featuressystem-design api offlinespec
2026-09-19Edge runtimedecision technical architecture-decision supabase api nextjsdecision
2026-09-19Edge runtimesystem-design security supabasespec
2026-09-19Embedding status fieldsystem-design rag embedding typescriptspec
2026-09-19Enforced conventionssystem-designspec
2026-09-19Env vars in turbo JSONdecision technical architecture-decision turborepo verceldecision
2026-09-19Env vars in turbo JSONsystem-design monorepo turborepo vercelspec
2026-09-19Environment contract driftopportunity phase-2 config security developer-experience severity-mediumopportunity
2026-09-19ESLint rules to use tsupdecision technical architecture-decision nextjs eslintdecision
2026-09-19Essential and ideal stateglossary terminologyglossary
2026-09-19Evolvabilitysystem-design rls offlinespec
2026-09-19Factorysystem-design prd feature factoryprd
2026-09-19Feature package workai-coding feature monorepo agent-guidance feature-systemguidance
2026-09-19Flat configdecision technical architecture-decision typescript eslintdecision
2026-09-19Flat configsystem-design code-quality-check eslintspec
2026-09-19Force dynamicdecision technical architecture-decision supabase authentication nextjsdecision
2026-09-19Force dynamicsystem-design nextjs supabasespec
2026-09-19Global tags and metadatasystem-design global-tagging-and-linking taxila zinsser alter-ego war-room factory core-drivespec
2026-09-19GraphQL and Relaysystem-design api graphql relayspec
2026-09-19GraphQL Relaydecision technical architecture-decision api-guard rls supabase drizzle api authentication nextjsdecision
2026-09-19Historic stateglossary terminologyglossary
2026-09-19Idempotent APIsystem-design api idempotencyspec
2026-09-19Independent deploymentssystem-design feature-systemspec
2026-09-19Informationglossary terminologyglossary
2026-09-19Installation at workspace levelsystem-design code-quality-check typescript pnpmspec
2026-09-19Instrumentationsystem-design observability vercel embeddingspec
2026-09-19Isolationsystem-design feature-systemspec
2026-09-19Lifecycle and traceabilityprd governance planningguidance
2026-09-19Mantinesystem-design css mantinespec
2026-09-19Many clients and many consumerssystem-design api pwa ai rag clispec
2026-09-19May become part of Taxilasystem-design core-drive taxilaspec
2026-09-19Middlewaresystem-design security api authenticationspec
2026-09-19Migrationsystem-design database drizzle pnpmspec
2026-09-19Model router contractsystem-design ai model-routing provider-agnostic embeddingspec
2026-09-19Module resolution bundlerdecision technical architecture-decision nextjs typescriptdecision
2026-09-19Module resolution bundlersystem-design code-quality-check typescriptspec
2026-09-19Never mutate outside API layersystem-design apispec
2026-09-19No API versioningdecision technical architecture-decision api-guard api nextjs clidecision
2026-09-19No utility stylesdecision technical architecture-decision eslint mantine cssdecision
2026-09-19Non syncable tablessystem-design database offlinespec
2026-09-19Notesai-coding-harness agent-guidance nextjs eslint pnpm cssguidance
2026-09-19Observabilitysystem-design api-guard api authentication vercel observabilityspec
2026-09-19Observablesystem-design rag embedding observabilityspec
2026-09-19Offline readysystem-design api pwa offline soft-delete idempotencyspec
2026-09-19Package boundary enforcementopportunity phase-2 monorepo eslint architecture severity-mediumopportunity
2026-09-19Parrotsystem-design prd feature parrotprd
2026-09-19Phase 0 foundation tooling completeplan living-plan phase-0 nextjs typescript eslint prettier turborepo pnpmplan
2026-09-19Phase 1 Supabase and auth shellplan phase-1 rls supabase drizzle postgresql authentication nextjsguidance
2026-09-19Phase 1 Supabase auth shell completeplan living-plan phase-1 api-guard rls supabase drizzle postgresql apiplan
2026-09-19Phase 1.1 DB level RLS soft delete enforcement completeplan living-plan phase-1.1 rls supabase drizzle postgresql pnpm soft-deleteplan
2026-09-19Phase 10 observability hardeningplan living-plan phase-10 api-guard rls api authentication nextjs offlineplan
2026-09-19Phase 11 dogfooding friends family access optionalplan living-plan phase-11plan
2026-09-19Phase 12 billing SaaS readiness optional pathplan living-plan phase-12 api offlineplan
2026-09-19Phase 4 Taxila v1 knowledge managementplan living-plan phase-4 taxila api-guard rls drizzle api authenticationplan
2026-09-19Phase 5 Zinsser v1 writing editor firstplan living-plan phase-5 taxila zinsser api mantine ai embeddingplan
2026-09-19Phase 6 core drive AI layer alter egoplan living-plan phase-6 taxila zinsser alter-ego war-room factory core-driveplan
2026-09-19Phase 7 war room factory v1plan living-plan phase-7 war-room factory core-drive rls api offlineplan
2026-09-19Phase 8 PWA iOS shellplan living-plan phase-8 taxila alter-ego nextjs vercel pwa mobileplan
2026-09-19Post mvp factory extensions bots agentsplan living-plan backlog factory parrot api-guard rls supabase drizzleplan
2026-09-19Prd.features.core drive and Taxilasystem-design prd feature taxila core-driveprd
2026-09-19Prefer JSON configsystem-design monorepospec
2026-09-19Present stateglossary terminologyglossary
2026-09-19Productivity Modulesystem-design prd feature war-roomprd
2026-09-19Profile trigger and referential integrityopportunity phase-2 database authentication integrity severity-highopportunity
2026-09-19Public API onlysystem-design api rls authentication clispec
2026-09-19PWAsystem-design pwa offlinespec
2026-09-19RAGsystem-design rag ai embeddingspec
2026-09-19Repository clientsystem-design database rls supabase drizzle api repository-patternspec
2026-09-19Request flowsystem-design monorepo api offlinespec
2026-09-19Retryablesystem-design rag embeddingspec
2026-09-19Row level securitysystem-design security rls drizzle offlinespec
2026-09-19Runtime database URL driftopportunity phase-2 security rls config severity-highopportunity
2026-09-19Runtime role reproducibilityopportunity phase-2 database security severity-criticalopportunity
2026-09-19Runtime validationsdecision technical architecture-decision api-guard supabase api typescript clidecision
2026-09-19Runtime validationssystem-design typescriptspec
2026-09-19Security proof and ciopportunity phase-2 testing ci security severity-highopportunity
2026-09-19Shared tsconfigdecision technical architecture-decision nextjs clidecision
2026-09-19Shared tsconfigsystem-design code-quality-check typescriptspec
2026-09-19Signup confirmation flowopportunity authentication ux severity-lowopportunity
2026-09-19Soft delete supportsystem-design database soft-deletespec
2026-09-19Start Todayprinciple core-drive execution consistencyguidance
2026-09-19State representationsystem-design api aispec
2026-09-19Structured response attributionsystem-design ai structured-streaming source-attribution citationspec
2026-09-19Syncable tablessystem-design database offline soft-deletespec
2026-09-19System overview diagramsystem-designspec
2026-09-19Task 1.1plan phase-1 task supabase postgresql api authentication nextjsplan
2026-09-19Task 1.10plan phase-1 task rls supabase drizzle postgresql authentication typescriptplan
2026-09-19Task 1.11plan phase-1 task api-guard rls supabase api authentication nextjsplan
2026-09-19Task 1.12and1.13plan phase-1 task supabase api authentication nextjs react typescriptplan
2026-09-19Task 1.14plan phase-1 task react pnpm mantine cssplan
2026-09-19Task 1.15and1.16plan phase-1 task supabase authentication nextjs react mantineplan
2026-09-19Task 1.17plan phase-1 task supabase authenticationplan
2026-09-19Task 1.18plan phase-1 task api-guard rls supabase drizzle postgresql authenticationplan
2026-09-19Task 1.2plan phase-1 task supabase drizzle postgresql authentication nextjs pnpmplan
2026-09-19Task 1.3plan phase-1 task supabase nextjs typescriptplan
2026-09-19Task 1.4plan phase-1 task supabase authentication nextjs react typescriptplan
2026-09-19Task 1.5plan phase-1 task rls supabase authentication typescriptplan
2026-09-19Task 1.6plan phase-1 task rls supabase drizzle authentication typescript offlineplan
2026-09-19Task 1.7plan phase-1 task drizzle postgresql typescriptplan
2026-09-19Task 1.8plan phase-1 task turborepo pnpmplan
2026-09-19Task 1.9plan phase-1 task rls supabase drizzle postgresql authenticationplan
2026-09-19Technology stacksystem-design supabase drizzle postgresql nextjs typescript turborepo pnpm vercelspec
2026-09-19Tiered context modelsystem-design core-drive domain situation war-room factory ai embeddingspec
2026-09-19Tiptap requirementsystem-design rag embeddingspec
2026-09-19tsupsystem-design code-quality-check eslintspec
2026-09-19Turboreposystem-design monorepo turborepo pnpmspec
2026-09-19TypeScript hoistingdecision technical architecture-decision nextjs typescript pnpmdecision
2026-09-19Use corepackdecision technical architecture-decision pnpm verceldecision
2026-09-19Use navigation hooksystem-design nextjsspec
2026-09-19User profile creation by DB triggerdecision technical architecture-decision supabase api authenticationdecision
2026-09-19Verceldecision technical architecture-decision nextjs turborepo pnpm verceldecision
2026-09-19Vercelsystem-design monorepo turborepo pnpm vercelspec
2026-09-19Why Prettier at repo level?decision technical architecture-decision prettier turborepo graphdecision
2026-09-19Why Turborepodecision technical architecture-decision turborepo pnpmdecision
2026-08-24Architectural OverviewSidekick's architectural overview — an API-first platform tuned for solo developerssidekick project technical architecturedocument
2026-07-19Project Sidekick - A Bird’s Eye ViewAn introduction to Project Sidekick. What is it? What problem does it solve? Why am I building it?sidekick project essaydocument
2026-07-10Building in the Margins of RealityProject kick-off post and a confessional essay about my past attempts and their failures. Why start now? What do I hope to achieve?sidekick project essayjournal
2026-05-29Checkpoint A walkthroughbuild walkthrough phase-0 checkpointguidance
2026-05-29Checkpoint C walkthroughbuild walkthrough phase-0 checkpointguidance
2026-05-29Checkpoint D walkthroughbuild walkthrough phase-0 checkpointguidance
2026-05-29Config files explainedbuild walkthrough phase-0 turborepo typescript eslint prettierguidance
2026-05-29Phase 1 walkthroughbuild walkthrough phase-1 supabase drizzle authenticationguidance