How to stay uncopyable, ship twice a month, and run AI responsibly — what runs where, what never leaves Malaysia, and how we govern it.
A front-end HTML page can always be View-Source'd. There is no client-side trick — obfuscation, minification, license checks — that stops a determined developer from copying a static page. Anyone who promises otherwise is selling snake oil.
So we stop trying to protect the code and instead build a moat around the things that are genuinely hard to copy. This is how every durable software business actually defends itself.
| Moat | Why a copier can't lift it | How we build it |
|---|---|---|
| 1. Data network effect | A clone starts with zero rental history, zero tenant records, zero estate cases. Our value compounds with every month of data. | Every payment logged, every disbursement, every resolved estate makes the product smarter and stickier. The dataset is the product. |
| 2. Server-side logic | Payment processing, document generation, notification dispatch, and the Faraid engine's edge cases run behind an authenticated API. The browser only sees the thin UI shell. | Move all mutations server-side. The HTML is a dumb terminal; the brain is private. |
| 3. Switching cost | Once a family has 18 months of rental records, beneficiary statements, and tenancy agreements in Warisan, leaving means losing their entire estate history. | Make the product the system of record. Export is allowed (trust), but nobody wants to re-enter years of data. |
| 4. Trust & distribution | Estate matters are intimate. Families recommend Warisan to relatives — who are often co-heirs to the same estate. A clone has no trust and no referral loop. | Lean into the emotional, dignified brand. Build the referral loop into the disbursement flow. |
In warisan-property.html there is a WARISAN_LICENSE integrity check and an origin allowlist. Be clear about what this does and doesn't do:
The copier ends up with a pretty but dead shell. To make it work, they'd have to rebuild the entire backend — at which point they're not copying, they're competing, and they're 18 months behind on data.
Bottom line: Speed and data win, not secrecy. Ship faster than anyone can copy, and make your accumulated data impossible to replicate.
warisan-property.html is the front-end MVP of the rental management feature. It demonstrates a single-property free tier with a hard paywall to add a second property, an income vs cost chart, a rental ledger with paid/due/overdue status, cost and maintenance tracking, beneficiary disbursement, tenant management, quick actions, a payment link generator, and a paywall modal.
| Plan | Price | Properties | Key unlocks |
|---|---|---|---|
| Free | RM 0 | 1 | Track income/cost, manual ledger, basic disbursement view |
| Family | RM 19/mo | up to 5 | Auto reminders, beneficiary reports, agreement generator |
| Guided | RM 699 one-time | — | Professional consult + document review |
Shipping velocity is the moat. Here is a concrete 6-month, 12-feature roadmap. Each is scoped to be shippable in ~2 weeks by a small team.
A vibe-coder clones your page on a Friday. By the time they've reverse-engineered the backend, integrated a payment gateway, handled Faraid edge cases, set up notification infra, and earned a single user's trust — you've shipped 4 more features, accumulated thousands of rental records, and your users have 3 months of history they'd never abandon.
They're copying a photograph of a moving train.
How Warisan uses AI: what runs where, what never leaves Malaysia, and how we govern it. This section is the authoritative reference for AI architecture decisions.
The most important architectural decision in the entire AI stack is this: the Faraid engine is deterministic code. It is never an LLM.
Quran 4:11–12 and 4:176 specify fixed mathematical rules. A probabilistic model can hallucinate a share fraction. A rule engine cannot. So the calculation layer — Faraid shares, Asabah residuary, Hajb blocking, NDE computation, Warisan Score points — is pure JavaScript and Python. Zero AI involvement.
What AI does in Warisan is explain, narrate, and guide. It takes the output of deterministic calculations and helps families understand what those numbers mean in plain Bahasa Malaysia.
Every AI task falls into one of three categories. The category determines which model handles it and whether data leaves Malaysia.
| Category A — Never touch an LLM (deterministic code only) | |
|---|---|
| Faraid share calculation | Fixed Quranic rules. LLM hallucination = religious and legal liability. |
| Warisan Score calculation | Fixed point rules. Computed server-side, never AI. |
| NDE computation | Pure arithmetic. Liquidity discount schedule is a lookup table. |
| Document form-filling | Template substitution. No inference needed. |
| Heir blocking (Hajb) rules | Boolean logic tree. Fully deterministic. |
| Category B — AI-assisted, non-sensitive inputs only | Input to AI | Output |
|---|---|---|
| Faraid result explanation | Heir categories + share fractions only | Plain BM paragraph explaining why each heir received their share |
| Warisan Score improvement tips | Score band + missing items | Personalised next-step suggestions |
| Next-steps roadmap narrative | Track + estate size band + heir categories | Prioritised action list with authority routing |
| FAQ and general guidance | User question text only | Answer in BM, EN, or AR |
| Category C — Sovereign model only (future) | Sensitivity | Status |
|---|---|---|
| Estate document parsing (land titles, IC, EPF) | High | Deferred until sovereign model deployed |
| Wasiat draft generation | High | Deferred — legal document, needs lawyer review workflow |
| Beneficiary identity verification | Critical | MyDigitalID JPN integration, no AI involvement |
AI infrastructure scales in four stages triggered by user volume and cost thresholds, not by ambition.
This is the single most important section for PDPA compliance and institutional trust. It must be implemented in code, not just policy. The sanitisation function runs in the Cloudflare Worker before any external API call:
The Cloudflare Worker enforces this before every outbound AI call. There is no code path that bypasses sanitisation. This ships from the first day AI is integrated.
Version-controlled, reviewed before any change, never modified at runtime. Hard limits: never calculate share fractions, never give legal advice, never repeat or store personal data, never produce content that could be construed as a fatwa.
Version control rule: Any change requires a written rationale, a test run against 10 standard queries, and sign-off before deployment.
API keys live in Cloudflare Worker environment variables, never in client-side code. Per-session rate limiting: 20 AI calls per session per hour. Every call is signed with a short-lived HMAC token.
Logging: timestamp, hashed session ID, query category, model used, token counts, latency, prompt version, sanitisation pass — and nothing else. No user data, no query content, no output content is logged. Retained 30 days then deleted.
Fallback chain: self-hosted Qwen3 8B → on error, Anthropic Claude Sonnet 4.6 → on error, pre-written static response. The user never sees a failure.
| Component | Who can change | Process |
|---|---|---|
| System prompt | Founder only | Written rationale + 10-query test + version log |
| Sanitisation function | Founder only | Code review + PDPA impact check |
| Model (provider/version) | Founder only | Security review + data boundary recheck |
| Fallback copy | Anyone | Review for tone and accuracy |
| Rate limits | Founder only | Cost impact analysis first |
PDPA 2010 compliance checklist — confirm before each stage migration:
Incident response timeline: Immediate — disable affected feature, return static fallback. Within 1 hour — identify failure, document. Within 24 hours — fix deployed and tested. Within 72 hours — PDPC breach notification prepared if applicable. Within 1 week — post-mortem written, prompt version incremented.