Phase IA Information Architecture Full IA

Information Architecture

The full information architecture of Tendd: entities, screens, navigation, flows, and a page-level library with real copy and states, ready for Wireframes.

Phase IA. Prompt 1 built the skeleton (entities, sitemap, navigation, flows, coverage, critique below). Prompt 2 built the page-level library: one page per cluster plus global chrome, system pages, and SEO, each with ordered content blocks, real copy drafts, and states. Every block traces to a job in JTBD or a locked decision (D1 to D5). Index: docs/sitemap.md.

Both skeleton flags are now resolved (for Wireframes)

FLAG 1, the "Save" tab had no landing screen: resolved in Core. The Save tab lands on a save-focus state of Home (cancel candidates pinned, summary shows potential savings, inline Cancel), not a new screen.

FLAG 2, Connect Bank and Add Subscription reused outside onboarding: resolved in Account. One "Add a source" action re-enters both in-app through a chooser. No duplicate screens.

Updated 2026-07-04: Welcome is the public landing; full-width desktop and two-pane realized

Welcome / Value Intro is now the public marketing landing (the front door), not a minimal onboarding screen. Full-width, greyscale, with a marketing top nav and a footer (the only footer in the set): hero with a sample list, benefits, how-it-works, trust and security, and social proof. Its CTAs enter the activation chain at Path Choice. See onboarding.md, navigation.md, seo.md.

Desktop layout realized in Wireframes. The tab bar becomes a left rail with the header folded into its top; single-column screens sit in a centered, comfortable measure; Home and Subscription Detail are a two-pane master-detail at wide desktop. See core.md. The page-level markdown docs remain the source of truth; this render is updated to match.

Entities

The core objects a person deals with to close their jobs. Screens display entities; entities grow out of jobs, not out of a competitor's menu. Nine core entities, plus objects held under question.

1. Subscription

Name, real merchant name and logo, amount, frequency, next date, category, status, source, linked account. The central object.

J-MAIN, J3

2. Account (source)

Bank connection via Plaid, or a manual private source. Status, last sync, count detected.

J1, J5, D5

3. Preset

Service template (name, logo, typical price, frequency) so manual entry is low effort. 400+ at launch.

J5, D2

4. Alert

Price change and payment failed are free; trial ending, unusual, duplicate are Pro. Plain-language, active voice.

J4

5. Charge

A billing instance: date, amount, subscription, status. Full timeline is Pro history.

J4, D3

6. Cancellation

Method (basic free, full guide Pro), progress status, money saved. The relief moment stays free.

J2, E2

7. Snapshot

Shareable card: count, monthly total, optional win, no bank data. Virality is a hypothesis.?

S1, E2

8. User & data controls

Minimal identity, path, plan, notification preferences, data-access explanation, one-tap deletion.

E3, J1

9. Plan (Tendd Pro)

Tier (Free / Pro monthly / yearly / lifetime), price $7.99 or $69, status. A business rule.

D3, D4

Under question (no entity, no screen): household / shared view JH1, Gmail scan and screenshot import v2, AI assistant JH2, budgets, credit score, investments, bill negotiation (all explicitly cut). A scope note: the free tier is uncapped on both subscription count (per D3) and bank connections (July 2026 product decision), over the older CLAUDE.md "up to 10" and "up to 2 bank accounts" lines.

Sitemap

Sixteen screens across six clusters, derived from the entities and from what each person is trying to do. Every screen names the job it serves. Amber marks Emma's primary path. Empty, error, and loading are states, shown in the flows, not screens.

Onboarding and Activation (public landing, then a one-time chain) - Welcome / Value Intro (J1: public marketing landing, the front door) - Activation Path Choice (J1 + J5: two equal paths, D2) - Connect Bank (J1 bank path; D5 Plaid) - Add Subscription (manual + presets) (J5 privacy path; D2) - Guided Reveal (J-MAIN: the aha, gradual, D1) [PRIMARY PATH] Core - Home / Subscription List (J-MAIN + E1: calm list) [PRIMARY PATH] - Subscription Detail (J3 decode + J4 alerts) Stay Ahead - Alerts / Activity (J4: price change, payment failed) Cut and Celebrate - Cancel Guide (J2: basic free, D3) - Cancel Win Moment (E2: the small win) - Share Snapshot (S1: privacy-safe card) Depth (Pro, gated by D3) - History and Trends (J-MAIN over time) - Upgrade / Tendd Pro (D3 split + D4 price) Account and Trust - Connections / Accounts (J1 + J5: manage sources, D5) - Data and Privacy (E3: data use, delete) - Settings / Profile (E3: plan, preferences)

Flows

How the personas actually move, with decision points, states, and honest dead ends, not just the happy path. Rectangles are screens matching the sitemap; diamonds are decisions; stadium nodes are states and outcomes.

Screen Loading / empty / error state Success end Dead end (a defect, see Critique)

Flow A. J-MAIN: see all recurring charges calmly (Emma, bank path)

The main job, first session, bank-connected path.

flowchart TD
  classDef state fill:#fff7e6,stroke:#d9a441,color:#5c4813;
  classDef success fill:#e9f5ee,stroke:#3f9c68,color:#1e4d33;
  classDef dead fill:#fdeaea,stroke:#c96a6a,color:#6b2b2b;

  Welcome["Welcome / Value Intro"] --> PathQ{"Bank or privacy path?"}
  PathQ -->|Privacy| AddSub["Add Subscription"]
  PathQ -->|Bank| ConnectBank["Connect Bank"]
  ConnectBank --> SyncLoad(["Loading: syncing your bank"])
  SyncLoad --> ConnOK{"Connection succeeded?"}
  ConnOK -->|no| ConnErr(["Error: could not connect"])
  ConnErr --> RetryQ{"Try again?"}
  RetryQ -->|yes| ConnectBank
  RetryQ -->|no| FallbackQ{"Use the manual path instead?"}
  FallbackQ -->|yes| AddSub
  FallbackQ -->|no| StuckExit(["Dead end: leaves without any list"])
  ConnOK -->|yes| FoundQ{"Any recurring charges found?"}
  FoundQ -->|no| NoneEmpty(["Empty: no recurring charges found"])
  NoneEmpty --> AddSub
  FoundQ -->|yes| Reveal["Guided Reveal"]
  AddSub --> Reveal
  Reveal --> Home["Home / Subscription List"]
  Home --> Success(["Success: sees all charges calmly"])

  class SyncLoad,ConnErr,NoneEmpty state
  class Success success
  class StuckExit dead
      

Dead end: leaves without any list if both retry and the manual fallback are declined. The Guided Reveal is one node; internally it is gradual per D1 (count, categories with logos, then total paired with an action).

Flow B. J5: track without sharing bank data (Ravi, manual + presets)

The privacy path. The manual-entry trap is the risk it must survive.

flowchart TD
  classDef state fill:#fff7e6,stroke:#d9a441,color:#5c4813;
  classDef success fill:#e9f5ee,stroke:#3f9c68,color:#1e4d33;
  classDef dead fill:#fdeaea,stroke:#c96a6a,color:#6b2b2b;

  Welcome2["Welcome / Value Intro"] --> PathQ2{"Bank or privacy path?"}
  PathQ2 -->|Bank| BankRef(["Bank path: see Flow A"])
  PathQ2 -->|Privacy| AddSub2["Add Subscription"]
  AddSub2 --> PresetLoad(["Loading: preset library"])
  PresetLoad --> PresetOK{"Preset library loaded?"}
  PresetOK -->|no| LibErr(["Error: presets unavailable"])
  LibErr --> ManualCustom(["Step: add a custom subscription by hand"])
  PresetOK -->|yes| SearchQ{"Service in the presets?"}
  SearchQ -->|yes| AddFromPreset(["Step: add from a preset, prefilled"])
  SearchQ -->|no| ManualCustom
  AddFromPreset --> MoreQ{"Add another?"}
  ManualCustom --> MoreQ
  MoreQ -->|yes| AddSub2
  MoreQ -->|no| EnoughQ{"Anything added yet?"}
  EnoughQ -->|no| EmptyReveal(["Empty: nothing to reveal yet"])
  EmptyReveal --> AbandonRisk(["Dead end: abandons half-done, manual entry trap"])
  EnoughQ -->|yes| Reveal2["Guided Reveal"]
  Reveal2 --> Home2["Home / Subscription List"]
  Home2 --> Success2(["Success: private list, no bank"])

  class PresetLoad,LibErr,EmptyReveal state
  class Success2 success
  class AbandonRisk dead
      

Dead end: abandons half-done. Ravi has twice abandoned manual entry in the research; if nothing pulls him back he leaves with a partial list.

Flow C. J2 + E2: find, cancel, and feel the win (Claudia)

Basic cancel instruction is free (D3); the full guide and direct link are Pro. The external dark pattern is the risk.

flowchart TD
  classDef state fill:#fff7e6,stroke:#d9a441,color:#5c4813;
  classDef success fill:#e9f5ee,stroke:#3f9c68,color:#1e4d33;
  classDef dead fill:#fdeaea,stroke:#c96a6a,color:#6b2b2b;

  Home3["Home / Subscription List"] --> Detail3["Subscription Detail"]
  Detail3 --> CancelQ{"Cancel this one?"}
  CancelQ -->|no| Home3
  CancelQ -->|yes| Guide["Cancel Guide"]
  Guide --> DepthQ{"Free basic steps or Pro full guide?"}
  DepthQ -->|"Basic, free"| BasicSteps(["Step: basic instruction, link plus steps"])
  DepthQ -->|"Wants full guide"| Upgrade3["Upgrade / Tendd Pro"]
  Upgrade3 --> PayQ{"Upgrade now?"}
  PayQ -->|no| BasicSteps
  PayQ -->|yes| FullGuide(["Step: full guide plus direct link"])
  BasicSteps --> DoneQ{"Managed to cancel?"}
  FullGuide --> DoneQ
  DoneQ -->|yes| Win["Cancel Win Moment"]
  DoneQ -->|"no, blocked by retention flow"| BlockedErr(["Error: stuck in the service dark pattern"])
  BlockedErr --> HelpQ{"In-app help offered?"}
  HelpQ -->|no| StuckCancel(["Dead end: gives up, no in-app next step"])
  HelpQ -->|yes| Guide
  Win --> ShareQ{"Share the win?"}
  ShareQ -->|yes| Share["Share Snapshot"]
  ShareQ -->|no| Success3(["Success: saved money, calm"])
  Share --> Success3

  class BlockedErr state
  class Success3 success
  class StuckCancel dead
      

Dead end: gives up with no in-app next step if a blocked cancellation is not caught. Declining the upgrade always returns the free basic instruction, so the relief moment is never paywalled.

Flow D. J4: stay ahead of a surprise (alert to action)

Entry is a notification (the return hook). Price change and payment-failed alerts are free; trial-ending and unusual are Pro.

flowchart TD
  classDef state fill:#fff7e6,stroke:#d9a441,color:#5c4813;
  classDef success fill:#e9f5ee,stroke:#3f9c68,color:#1e4d33;
  classDef dead fill:#fdeaea,stroke:#c96a6a,color:#6b2b2b;

  Notif(["Event: notification, price change or payment failed"]) --> Alerts["Alerts / Activity"]
  Alerts --> AnyQ{"Any alerts to show?"}
  AnyQ -->|"load failed"| AlertErr(["Error: could not load alerts"])
  AlertErr --> RetryA{"Retry?"}
  RetryA -->|yes| Alerts
  RetryA -->|no| HomeA["Home / Subscription List"]
  AnyQ -->|no| AllClear(["Empty: all clear"])
  AllClear --> HomeA
  AnyQ -->|yes| TypeQ{"Alert type?"}
  TypeQ -->|"Trial ending or unusual, Pro"| UpgradeA["Upgrade / Tendd Pro"]
  TypeQ -->|"Price change or payment failed, free"| DetailA["Subscription Detail"]
  UpgradeA --> HomeA
  DetailA --> NeedQ{"Price change or payment failure?"}
  NeedQ -->|"price change"| ActQ{"Keep or cancel?"}
  ActQ -->|keep| SuccessA(["Success: caught it early, nothing to do"])
  ActQ -->|cancel| GuideA["Cancel Guide"]
  NeedQ -->|"payment failure"| FixQ{"Is the fix inside the app?"}
  FixQ -->|"yes"| SuccessA
  FixQ -->|"no, at the bank or merchant"| NoNext(["Dead end: no in-app next step for a failed payment"])

  class AlertErr,AllClear state
  class SuccessA success
  class NoNext dead
      

Dead end: no in-app next step for a failed payment when the fix lives at the bank or merchant and the app stops at "informed".

Coverage matrix

Jobs against screens. A checkmark means the screen genuinely helps close that job. A gate that only unlocks a job does not count. The orphan column is highlighted.

Job WelPthBnkAddRevHomDetAlrGdeWinShrHisUpgConPrvSet
J-MAIN see charges calmly
J1 activate without anxiety
J2 identify and cancel unused
J3 understand a charge
J4 stay ahead of surprises
J5 track without sharing bank
E1 feel competent, not judged
E2 the small win
E3 feel safe, control data
S1 share the discovery

Outcome: zero orphan jobs, one orphan screen. Every job has a home. The only column with no checkmark is Upgrade / Tendd Pro, which traces to decisions D3 and D4, not to a job. It is retained by design as a contextual gate over the Pro surfaces, not removed. Key: Wel Welcome, Pth Path Choice, Bnk Connect Bank, Add Add Subscription, Rev Guided Reveal, Hom Home, Det Subscription Detail, Alr Alerts, Gde Cancel Guide, Win Cancel Win, Shr Share Snapshot, His History and Trends, Upg Upgrade, Con Connections, Prv Data and Privacy, Set Settings.

Critique

Four defect classes, most dangerous first. Fixes are proposals for Prompt 2, not applied here. All dead-end and missing-state fixes are states and copy on existing screens, so the 16-screen inventory does not change.

1. Dead ends

WhereDefectProposed fix
Connect Bank (Flow A)Declining both retry and manual fallback leaves the user with no list.Keep an "add them yourself" action persistent on the error state; never an error with only a dead exit.
Add Subscription (Flow B)Ravi abandons manual entry half-done and leaves with a partial list.Persist partial progress, run the reveal on a partial list, and re-hook with the return notification.
Cancel Guide (Flow C)A blocked external cancellation leaves the user stuck with no next step.Add a "could not cancel" state with alternative steps or a mark-to-retry, so there is always an in-app move.
Subscription Detail (Flow D)A failed-payment alert ends at "informed" when the fix is at the bank or merchant.Add a plain-language next-step card ("update your card" or "no action needed, retries on DATE").

2. Missing states

WhereDefectProposed fix
Home / Subscription ListEmpty, loading, and sync-error states are not yet specified.Define a calm empty state, a non-alarming loading state, and a sync-error state that keeps the last known list.
Subscription DetailNo state for when enrichment fails and the name stays cryptic. This threatens J3.Define an "unrecognized charge" state that invites naming or categorizing it.
History and TrendsA paid user with under 3 months of history has no defined empty state.Define a "still gathering your history" state, distinct from the Pro upsell.
Cancel GuideNo state for a service that has no guide yet.Define a "no guide yet" state with generic steps and a request-a-guide action.
Share SnapshotCard generation and share failure are not specified.Define a loading state while the card renders and an error state if the share fails.

3. Excess depth

No violation. First-session J-MAIN sits at exactly 3 taps, at the ceiling. Watch item: do not add any onboarding step, or the main job moves to 4 taps. Steady-state J-MAIN is 0 to 1 tap. J4 from a notification is about 2 taps; J2 for Claudia is 2 taps to the guide.

4. Orphans

One orphan screen: Upgrade / Tendd Pro, retained as a contextual gate justified by D3 and D4. No orphan jobs. Every job in JTBD is served by at least one screen.

Site graph

Every screen and transition, grouped by cluster. The full page-level detail lives in the library below.

flowchart TD
  subgraph OB["1 Onboarding"]
    W["Welcome"] --> PC["Path Choice"]
    PC --> CB["Connect Bank"]
    PC --> AS["Add Subscription"]
    CB --> GR["Guided Reveal"]
    AS --> GR
  end
  subgraph CORE["2 Core"]
    HOME["Home"] --> DET["Subscription Detail"]
  end
  subgraph SA["3 Stay Ahead"]
    AL["Alerts"]
  end
  subgraph CC["4 Cut and Celebrate"]
    CG["Cancel Guide"] --> CW["Cancel Win"] --> SH["Share Snapshot"]
  end
  subgraph PR["5 Depth Pro"]
    HT["History and Trends"] --> UP["Upgrade"]
  end
  subgraph AC["6 Account and Trust"]
    CON["Connections"]
    DP["Data and Privacy"]
    SET["Settings"]
  end
  GR --> HOME
  HOME --> AL
  HOME --> AS
  DET --> CG
  AL --> DET
  DET --> HT
  HT --> UP
  SET --> CON
  SET --> DP
  CON --> CB
  CON --> AS
    

Page-level library

One page per cluster, plus global chrome, system pages, and SEO. Each is the source of truth for its surface, with real copy, states, and mockups. Both skeleton flags are resolved (see the top of this page).

Global Navigation

GC1 App Header, GC2 Tab Bar, persona x plan state matrix, the desktop left-rail and header-fold delta, and the footer rule (none on app screens; the Welcome landing is the exception).

Node 0

1 Onboarding

Welcome (now the public marketing landing), Path Choice, Connect Bank, Add Subscription, Guided Reveal. Equal-weight paths, persistent fallback, gradual reveal.

Screens 1 to 5

2 Core

Home and Subscription Detail. Owns GC3 and GC4. FLAG 1 resolved: the Save tab is a save-focus state of Home.

Screens 6 to 7

3 Stay Ahead

Alerts / Activity. Owns GC5. Active-voice feed, quiet new-dot, Pro types gated inline.

Screen 8

4 Cut and Celebrate

Cancel Guide, Cancel Win, Share Snapshot. Free-first cancel, could-not-cancel next step, privacy-safe snapshot.

Screens 9 to 11

5 Depth (Pro)

History and Trends, Upgrade. Owns GC7. Context-only gate, honest preview lock, yearly-first pricing.

Screens 12 to 13

6 Account and Trust

Connections, Data and Privacy, Settings. Owns GC6. FLAG 2 resolved: one Add-a-source re-enters onboarding in-app.

Screens 14 to 16

9 System

Not found, server error, maintenance (skipped), consent [?], toasts. The app's connective tissue.

Node 9

SEO

The search engine, scoped honestly to the one public surface (the Welcome landing, now in-repo). Keyword model, templates, checklist.

Node 8

Index and rollups: docs/sitemap.md. Reusable sections GC3 to GC7 are specified inside the cluster page that owns each (see the library pages).