Skip to content

[PRD] Stabilize Sure for AFK-safe development #183

Description

@hendripermana

Problem Statement

Sure has advanced financial capabilities, especially recurring finance,
subscriptions, globally applicable debt and asset models, Islamic finance, and
regional capabilities for Indonesia and Southeast Asia such as PayLater,
Personal Lending, digital and cooperative lending, precious metals, and
reconciliation. However, its development foundation does not yet make those
capabilities safe to evolve autonomously.

The full test suite is not a blocking CI gate, the test schema is not currently
ready, security scanning is partially non-blocking, product identity is
inconsistent, UI systems overlap, package managers conflict, financial
terminology is ambiguous, and several financial invariants are duplicated or
economically incorrect. Examples include PayLater being classified differently
in Ruby and PostgreSQL, principal payments being treated as expenses, silent
exchange-rate fallback, mutable precious-metal quantity without a reconstructable
history, and AI privacy claims that are stronger than the implementation proves.

Sure also lacks an explicit boundary between universal financial semantics and
regional financial practices. Without that boundary, global expansion could
erase important Indonesia and Southeast Asia use cases, while country-specific
assumptions could leak into calculations used by every Family.

This makes feature catch-up risky. Importing upstream features before
stabilizing these foundations would increase complexity, hide regressions, and
make AFK agent execution unreliable.

Solution

Establish a verified foundation contract for Sure before adopting major
features. The work will make CI blocking, restore a reproducible PostgreSQL 18
test baseline, align implementation with canonical domain language, remove stale
product identities and parallel UI systems, enforce financial invariants at
observable boundaries, clarify AI governance, and turn upstream activity into
an evaluated comparison register rather than an automatic backlog.

Sure will use a Global Financial Core for country-neutral assets, liabilities,
cash flows, recurring finance, reporting, provenance, and authorization.
Regional Coverage will provide explicit languages, currencies, terminology,
providers, examples, and financial practices. Indonesia and Southeast Asia
remain first-class markets without becoming hardcoded defaults for every
Family.

The result is one Sure product across Managed and Self Hosted modes, one
household financial boundary, one design system, one package manager, and one
set of financial semantics that can be tested end to end while expanding fairly
across regions.

User Stories

  1. As a Family Member, I want every financial screen to use consistent financial meanings, so that reports do not contradict account details.
  2. As a Family Member, I want all Family financial records visible to me, so that the household has one shared picture.
  3. As a Family Admin, I want administrative capabilities separated from financial editing, so that membership and provider settings remain controlled.
  4. As a Family Admin, I want Managed and Self Hosted deployments to preserve the same financial behavior, so that deployment choice does not create a different product.
  5. As a Family Member, I want assets and liabilities classified by economic substance, so that net worth is accurate.
  6. As a PayLater user, I want utilized PayLater credit treated as a liability, so that available credit is never counted as wealth.
  7. As a borrower, I want principal payments separated from interest, margin, and fees, so that expenses and debt reduction are reported correctly.
  8. As a mortgage user, I want property collateral linked conceptually to secured debt, so that property and KPR are not conflated.
  9. As a vehicle-financing user, I want the financed vehicle and its debt represented separately, so that asset value and outstanding liability remain clear.
  10. As a consumer-financing user, I want one-time electronics installments distinguished from reusable PayLater facilities, so that debt behavior is modeled correctly.
  11. As a lender to another person, I want Personal Lending represented as a receivable, so that money owed to my Family is an asset.
  12. As a borrower from another person, I want that obligation represented as debt rather than Personal Lending, so that direction cannot be misread.
  13. As a Family Member, I want internal transfers excluded from income and expense, so that moving money does not distort reports.
  14. As a credit-card user, I want purchases recognized as expenses and card payments recognized as transfers, so that expenses are not counted twice.
  15. As a borrower, I want loan disbursement recognized as cash plus liability rather than income, so that earnings are not overstated.
  16. As a Personal Lending user, I want lending and repayment to move value between cash and receivables, so that only genuine gains or fees affect income.
  17. As a multi-currency user, I want original currencies preserved, so that historical facts are not rewritten into a reporting currency.
  18. As a multi-currency user, I want dated exchange rates used for dated facts, so that historical reports are financially meaningful.
  19. As a multi-currency user, I want missing exchange rates disclosed, so that Sure never presents a silently fabricated total.
  20. As a Family Admin, I want changing Reporting Currency to change presentation only, so that financial history remains intact.
  21. As an investment user, I want observed holdings distinguished from trade history, so that incomplete provider history does not fabricate positions.
  22. As a precious-metals user, I want quantity, activity, market price, and valuation represented as distinct facts, so that ownership history can be reconstructed.
  23. As a gold user, I want Gold treated as one Precious Metal type, so that the domain can support other metals without parallel implementations.
  24. As a Family Member, I want balance anchors distinguished from calculated snapshots, so that observed balances and rebuildable projections remain trustworthy.
  25. As a Family Member, I want material balance conflicts surfaced for reconciliation, so that syncs do not silently rewrite history.
  26. As a provider-sync user, I want repeated syncs to be idempotent, so that retries cannot duplicate financial facts.
  27. As an import user, I want repeated imports to preserve identity and provenance, so that retries and corrections are auditable.
  28. As a Family Member, I want manual corrections protected from automatic enrichment, so that my confirmed facts are not overwritten by suggestions.
  29. As a reviewer, I want material source conflicts represented as Review Items, so that ambiguity is resolved explicitly.
  30. As a Family Member, I want Recurring to remain a useful operational hub, so that patterns and subscriptions remain easy to manage.
  31. As a developer, I want Recurring Patterns, Subscriptions, Renewals, Services, and Sure Membership to have distinct meanings, so that code cannot confuse unrelated lifecycles.
  32. As a subscription user, I want each Renewal to represent one billing cycle, so that expected and actual payments can be reconciled.
  33. As an AI user, I want to consent before my data is processed, so that AI usage is explicit.
  34. As a Family Admin, I want to select the AI Provider and Family automation policy, so that data processing follows household policy.
  35. As an AI user, I want my chat private to me while its tools remain Family-scoped, so that another Family can never be queried.
  36. As an AI user, I want to know the provider, model, purpose, data categories, cost, and retention policy, so that consent is informed.
  37. As a Family Member, I want AI output treated as a suggestion until confirmed, so that AI cannot silently change material financial facts.
  38. As a document user, I want AI indexing limited to explicitly selected documents and deletable, so that RAG storage is controllable.
  39. As a Sure user, I want AI accessible through a dedicated workspace, so that a global floating overlay does not obstruct financial workflows.
  40. As a Sure user, I want one coherent design system, so that pages do not mix Sure DS, shadcn, and isolated CSS conventions.
  41. As a keyboard or assistive-technology user, I want accessible interaction behavior preserved during component migration, so that removing shadcn does not remove accessibility.
  42. As a Sure user, I want the product called Sure everywhere, so that Permoney and non-legal Maybe branding do not create confusion.
  43. As a maintainer, I want required Maybe Finance attribution preserved, so that identity cleanup remains legally compliant.
  44. As a contributor, I want one JavaScript package manager and lockfile, so that local and CI dependency resolution agree.
  45. As a contributor, I want the checked-in schema to load into a clean PostgreSQL 18 database, so that test success is reproducible.
  46. As a contributor, I want the full test suite to block merges, so that lint-only success cannot hide behavioral regressions.
  47. As a contributor, I want security scans to block on findings, so that warnings are not silently accepted.
  48. As an AFK agent, I want each ready issue to name its domain terms, boundaries, acceptance behavior, and verification commands, so that implementation requires no guessing.
  49. As a maintainer, I want upstream changes classified before adoption, so that active community work improves Sure without erasing local advantages.
  50. As a maintainer, I want local capabilities marked Already Ahead where appropriate, so that catch-up work does not replace stronger implementations.
  51. As a maintainer, I want stale comparison evidence dated and linked to local issues, so that the catch-up register remains actionable.
  52. As a product owner, I want major feature adoption paused until foundation gates are green, so that feature velocity becomes sustainable rather than fragile.
  53. As a user anywhere in the world, I want universal asset, debt, cash-flow, recurring, and reporting concepts, so that Sure does not assume one country's financial system.
  54. As a user in Indonesia or Southeast Asia, I want local currencies, terminology, providers, Islamic finance, PayLater, cooperative lending, informal lending, arisan, and service catalogs treated as first-class coverage, so that global scope does not erase my real financial life.
  55. As a user in another region, I want regional products expressed through the same stable financial concepts, so that my market can be added without creating a country-specific fork.
  56. As a maintainer, I want country-specific assumptions isolated from universal calculations and classifications, so that expanding Regional Coverage cannot corrupt the Global Financial Core.

Implementation Decisions

  • Execute this PRD as ordered foundation workstreams. Do not begin major feature catch-up until the blocking foundation gate is green.
  • Preserve the Rails monolith and relational PostgreSQL model. Full event sourcing is explicitly rejected for this phase.
  • Define a Global Financial Core for country-neutral assets, liabilities, cash flows, recurring finance, provenance, reporting, and authorization.
  • Represent market-specific products, terminology, providers, examples, and workflows as explicit Regional Coverage built on the Global Financial Core.
  • Treat Indonesia and Southeast Asia as first-class Regional Coverage, preserving Islamic finance, PayLater, pinjol and digital lending, koperasi, informal lending, arisan, local service providers, IDR, and regional payment practices without making them universal defaults.
  • Add other regions through the same extension boundaries rather than country forks or duplicated financial models.
  • Use Family as the household, authorization, tenancy, and financial-record boundary.
  • Allow Family Members to view and manage the complete Family financial record. Reserve membership, integrations, security, billing, and household-wide settings for Family Admins.
  • Treat operational super-administration as a platform concern, not a household role.
  • Keep Managed and Self Hosted modes on one financial domain and core UX. Express differences through explicit platform capability and policy boundaries.
  • Use Sure as the sole product identity. Remove Permoney completely. Retain Maybe Finance references only for required legal attribution, licensing, and accurate history.
  • Use the canonical glossary vocabulary for new code, tests, UI, and issues.
  • Keep Recurring as the user-facing hub while separating Recurring Pattern, Subscription, Renewal, Service, and Sure Membership in the domain model.
  • Define Account classification from one canonical economic rule shared by Ruby and PostgreSQL. Add parity tests for every Account type.
  • Model Mortgage, Vehicle Financing, Consumer Financing, PayLater, and Personal Lending as specializations or configurations of stable asset/debt concepts rather than creating shallow account modules for every real-world product.
  • Decompose the oversized debt implementation behind a stable Debt Agreement interface. Separate agreement terms, installment calculation, payment allocation, Sharia financing rules, notification policy, and provider concerns.
  • Keep conventional and Sharia-compliant financing structures within the same debt semantics. Murabaha, Ijarah, and related structures are financing structures, not unrelated account types.
  • Distinguish Entry facts, Balance Anchors, rebuildable Balance Snapshots, and Current Balance projections.
  • Distinguish Holding Snapshots from Trades because providers may report positions without complete trade history.
  • Introduce reconstructable Precious Metal Position semantics using Metal Activity, Quantity Anchors, Market Price Observations, and derived Metal Valuations.
  • Preserve original currencies on facts and observations. Use Family currency only as Reporting Currency.
  • Use dated exchange rates for dated reporting. Missing rates must mark aggregates incomplete or create Review Items; never silently substitute a rate of one.
  • Consolidate parallel exchange-rate representations behind one canonical contract after mapping all consumers.
  • Preserve the internal amount sign convention only behind domain boundaries. UI and external APIs communicate inflow and outflow explicitly.
  • Treat internal account movement as Transfer, not income or expense.
  • Split debt payments into Principal Payment and Financing Cost. Principal reduces liability; interest, margin, and fees are expenses.
  • Treat credit-card and PayLater payments as Transfers. Recognize the original purchases as expenses.
  • Attach Data Provenance to the highest-value financial boundaries: Entry, Balance Anchor, Holding Snapshot, Quantity Anchor, Import, and provider sync.
  • Require source identity, external identity where available, effective time, observation time, and producing process for material facts.
  • Make imports, syncs, jobs, and webhooks retry-safe and idempotent.
  • Use Reconciliation or Review Items for material conflicts instead of last-write-wins.
  • Keep automatic merchant and category work as Enrichment. Manual confirmation outranks automatic enrichment.
  • Preserve audit history for material financial corrections and Family Admin actions.
  • Keep AI Processing opt-in and provider-agnostic. Remove unsupported claims that transmitted data is anonymous.
  • Let Family Admins configure AI Providers and Family automation. Require individual User consent for private chat use.
  • Exclude prompts and financial payloads from telemetry and tracing by default.
  • Require explicit selection and verifiable deletion for document indexing.
  • Prevent AI from applying material financial changes without preview and explicit confirmation.
  • Remove the globally rendered floating chat. Keep AI conversations in the dedicated chat workspace and expose contextual AI actions through Sure DS components only.
  • Make DS::* the only public component API and use the design specification as the sole visual authority.
  • Remove the shadcn namespace, components, controllers, demos, and styling after migrating all consumers. Preserve proven WAI-ARIA interaction behavior.
  • Move every Stimulus controller under the canonical JavaScript controller directory.
  • Use pnpm as the only JavaScript package manager and remove the npm lockfile.
  • Keep JavaScript and Ruby untyped during this phase. Do not introduce Sorbet, Steep, or TypeScript merely to claim a typecheck gate.
  • Make CI checks blocking: schema load, full Minitest, Zeitwerk, RuboCop, Biome, Brakeman, and Importmap audit.
  • Remove non-blocking security configuration and permissive dependency installation from CI.
  • Use a disposable PostgreSQL 18 database with no production credentials or volumes.
  • Maintain a living upstream comparison register. Classify each evaluated upstream change as Adopt, Adapt, Reject, Already Ahead, or Investigate with evidence, date, dependencies, and a local issue.
  • Do not measure catch-up quality through commit, migration, route, controller, or file counts.
  • Keep the rewritten engineering guide concise and verifiable. Domain language belongs in the glossary, durable trade-offs in ADRs, agent feedback loops in the harness, and visual rules in the design specification.

Testing Decisions

  • Tests verify observable behavior and financial invariants, not private implementation details.
  • Commands are tested through their durable state changes and collaborator contracts. Queries are tested through outputs.
  • Existing Minitest model, controller, job, interface, component, integration, and system-test patterns are preferred over new test frameworks.
  • The clean-database seam must load the checked-in schema into disposable PostgreSQL 18 before running tests.
  • The full Minitest suite is a blocking completion gate.
  • Managed and Self Hosted smoke tests verify shared financial behavior and explicit capability differences.
  • Family authorization tests verify full financial visibility for Members and administrative restrictions for non-Admins.
  • Account classification contract tests cover every Account type and prove Ruby/database parity, including PayLater and Personal Lending.
  • Regional contract tests prove that universal classifications and calculations remain country-neutral while region-specific labels, provider catalogs, currencies, schedules, and workflows activate only for the intended Regional Coverage.
  • Indonesia and Southeast Asia coverage tests preserve Islamic finance, PayLater, cooperative and digital lending, informal lending, arisan, local service catalogs, and IDR behavior without affecting Families in other regions.
  • Balance tests verify anchors, rebuildable snapshots, current projections, reconciliation, effective dates, and rebuild idempotency.
  • Money-flow tests verify that transfers, credit payments, debt disbursements, principal repayments, financing costs, and Personal Lending do not distort income or expense.
  • Multi-currency tests verify original-value preservation, dated conversion, reporting-currency changes, and missing-rate behavior.
  • Investment tests verify that Holding Snapshots remain valid without complete Trade history.
  • Precious-metals tests verify quantity reconstruction, adjustments, fees paid in cash or metal, dated prices, FX conversion, and valuation without mutable-history drift.
  • Recurring tests verify the boundaries among Recurring Patterns, Subscriptions, Renewals, Services, and Sure Membership.
  • Import and provider tests verify stable external identity, idempotent retries, provenance retention, pending/posted reconciliation, and conflict Review Items.
  • AI tests verify opt-in consent, provider disclosure, Family scoping, User-private chat access, telemetry redaction, explicit document indexing, deletion, and confirmation before material writes.
  • UI system tests verify sign-in, dashboard access, transaction creation, account reconciliation, dedicated chat navigation, and absence of the floating chat.
  • Component tests verify that migrated DS interactions preserve keyboard, focus, ARIA, Turbo, and Stimulus behavior.
  • Identity checks fail when Permoney appears outside migration/history evidence or Maybe Finance appears outside approved legal/historical contexts.
  • Upstream-register tests or validation tooling verify that each entry contains classification, evidence, evaluation date, rationale, and local issue linkage.
  • Static typing is not a completion gate in this phase. Its adoption requires a separate issue after the baseline remains green.

Out of Scope

  • Major feature catch-up such as Anthropic support, RAG/vector stores, Goals, Account Statements, broad SSO expansion, or other large upstream features.
  • Full event sourcing or a wholesale ledger rewrite.
  • A complete static-typing migration.
  • Automatic dependency upgrades unrelated to a foundation workstream.
  • Creating separate financial products for Managed and Self Hosted modes.
  • Creating a model for every named consumer loan product.
  • Claiming complete coverage of every financial product in every country; Regional Coverage expands from verified user needs through stable global interfaces.
  • Removing legally required Maybe Finance attribution.
  • Applying database migrations automatically outside an explicitly verified isolated environment.
  • Replacing the existing Rails, Hotwire, PostgreSQL, Sidekiq, or Redis architecture.

Further Notes

  • The canonical agent guide, domain glossary, agent harness, triage configuration, and foundation ADRs have been established as grounding artifacts.
  • RuboCop, Biome, and Brakeman currently pass locally.
  • The test environment resolves to sure_test, but the database schema is not currently prepared, so the full suite has not yet been proven green.
  • Known high-risk findings include PayLater classification disagreement between Ruby and PostgreSQL, debt principal reported as expense, silent exchange-rate fallback, mutable precious-metal quantity, duplicate package-manager lockfiles, Stimulus controllers outside the canonical directory, global floating-chat UI, shadcn/Sure DS overlap, stale product identity, and non-blocking CI security/test gaps.
  • Global scope does not mean modeling every product in advance. Sure expands Regional Coverage from verified user needs while preserving universal financial invariants.
  • Work should be split into small vertical issues, but every child issue must preserve this PRD's domain contracts and blocking completion gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified and ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions