Saving links doesn't make you smarter. Learning from them does.

Personal Project·2026–now·Web App · PWA·view project ↗

Problem

IwasthatpersonwithhundredsofsavedlinksI'dneveropenagain.Isavedarticles,videos,references.ButwhenIneededsomething,I'dendupsearchingforatitleIbarelyremembered,infoldersIbarelyorganized.ThetoolIusedorganizedwhatIsaved.Theproblemwasitdidn'thelpmelearnfromitorfinditwhenIactuallyneededit.

SoIbuiltCoisas.spacearoundonequestion:whatifthecontentyousavedcouldsurfaceitselfwhenyouneedit,withoutyouhavingtorememberitexisted?

The AI stack

Categorizationrunsongpt-4o-miniviaOpenRouterattemperature0.2.Ifoundthattemperaturethroughtesting:highertemperaturesintroducedcategorydrift,thesamelinkcategorizeddifferentlyonrepeatsaves.0.2givestheconsistencythatacategorizationfeatureneedstobetrusted.

Theconversationalretrievallayerusesthecategoryasascopedcontextsignal,aRAG-likeapproachfastenoughforconsumerUXandaccurateenoughtobeuseful.Itestedwithfulldocumentembeddinganditwasslowerthantheactualquerypatternsjustified.

Whencontextisthin,retrievalfallsbackthroughthreelevels:visiblecontentfromtheactivecategory(last3days),thenallcontentfromthatcategory,thenallcontentregardlessofcategory.Thefallbackstrategykeepsresponsesgroundedevenforuserswhojuststarted.

TheFocoTimematchingalgorithmusessemanticAI,so"LearnReact"surfaceslinksabouthooks,components,andJSX,includinglinksthatnevermentionReactinthetitle.ResultsarecachedinKVwithhash-basedinvalidation:whenanewlinkissaved,thehashchanges,cacheinvalidates,andthenextmatchrequestregenerates.

The design decisions

Streamingwasnon-negotiableforme.Anycategorizationthatrequiredwaitingwouldbreakthesavehabit.Theproductonlyworksifsavingfeelsinstant.Thelinkappearsimmediatelyinthegridwithapendingstate,categorizationcompletesinthebackground,statusprogressesfrompendingtoprocessedtoread.

Iscopedtheconversationalinterfacebycategoryonpurpose.Open-endedchatoverallsavedcontentproducedirrelevantanswersintesting,sonarrowingthecontextwasthedecisionthatmadethefeaturework.Whenusersswitchcategorieswhileachatisopen,aninlinewarningappearswithtwooptions:keepthecurrentcontextorre-groundtheconversationinthenewcategory.

The/resumircommandusesFibonacci-basedprogressivedisclosure:thefirstcallreturns5links.Userscanaskformore,andthesequenceexpandsto8,13,21,34.Usersdiscoverwhattheyhaveatthepacetheyneed.

The failure mode

Whenthemodelcan'tcategorizealinkconfidently(paywalledpages,ambiguouscontent,brokenURLs),thelinklandsinanUncategorizedstatewithamanualoverrideoption.Thelinkisalwaysthere,alwaysaccessible.TheAIisanadditivelayerontopofthedata,sowhenitfails,thelinkstaysavailable.

TheAIproviderlayerhasafallback:ifOpenRouterreturnsa402(creditsexhausted),thesystemautomaticallyroutestoOpenAIwitha1-hourretrywindow.ServicestatusistrackedinKV:provider,lasterror,failedattempts,lastsuccesstime.Usersneverseeaproviderswitch.

Contentextractionusessilentfailure:ifittimesoutat10seconds,thelinkstillworkswithitsmetadata.Iprioritizedresponsespeedhere,becausealinkinthegridalreadyservestheuser,evenwithoutthefullcontentextracted.

Row-levelsecurityisenforcedatthedatabaselevelandintheapplicationlayer.EveryuserdatatablehasRLSpoliciesboundtoauth.uid().Noapplicationbugcanleakoneuser'sdatatoanother.

What's next

IwanttoadddeepreadingviaFirecrawl,extractingactualcontentfromsavedlinksbeyondthemetadata.AndGmailOAuthtopullnewslettersandthreadsdirectlyintothelibrary,turningtheinboxintoalearningfeed.WhatI'mmostexcitedaboutisthereadinglayer,becausethat'swhatwillmaketheAIresponsesgenuinelyuseful,groundedinwhatyouactuallyread.

previous read

Resense

Resense is a product that uses AI to turn any data a team already has (CSVs, PDFs, text, images) into Synthetic Users, with RAG and embeddings. It also generates insights with weighted cause-and-effect connections. I used AI across the whole process, from research to testing.