I built a Bible verse picker with no generative AI. Here is how it chooses, and how it got it wrong
I'm a solo developer. Veil is a small free web app: you write one line about what is weighing on you, and it returns a Bible verse, a short meditation, a prayer and one small thing to try today. The part people ask about is "no generative AI", so here is what that means and why I chose it. Why not

I'm a solo developer. Veil is a small free web app: you write one line about what is weighing on you, and it returns a Bible verse, a short meditation, a prayer and one small thing to try today.
The part people ask about is "no generative AI", so here is what that means and why I chose it.
Faith writing has a failure mode I did not want: a confident verse reference that does not exist, or a comforting line that was never in the text. Someone who writes one honest sentence is not going to fact-check the answer. So every verse, meditation and prayer in Veil was written in advance. The app only chooses.
Choosing sounds safer than generating. It is not.
1. The wrong person's prayer. Early on, someone who wrote that her husband throws things when he is angry and she is scared could be shown a prayer for someone who lost their temper. Both texts sat under "anger". That is the wrong person to pray as. The fix was a rule: never attach a situation the writer did not state, and a fallback candidate must share at least one real clue with the input.
2. Jealousy sent down the abuse track. On the day I'm writing this I found that "My coworker got promoted before me. I said congratulations, but inside I kept feeling jealous." was routed to an abuse-support response. Two causes. The word "me" in "before me" was read as something done to the writer. And when my rules were undecided, the small classifier said "victim" and my code simply trusted it.
The fix: if the writer owns the feeling or the action ("I kept feeling jealous"), the classifier's "victim" guess is ignored. A rule that positively detects harm still wins, so "my husband came home drunk and shoved me" still gets the protective response.
3. My tests could not see it. The test harness ran the matcher without the on-device model, so the second bug never appeared there. It only showed up in a real browser. I now check matching changes in the browser too.
It will sometimes miss. There is a "Not quite" button for that. If you try it, tell me which sentence it handled badly. That is the most useful feedback I can get.
Try it without signing up: veildaily.com