<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bruno Fernandes</title>
    <description>The latest articles on DEV Community by Bruno Fernandes (@brunof94_debug).</description>
    <link>https://dev.to/brunof94_debug</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4167942%2F267ca6c7-8cea-4cb5-939e-0b17c1d30435.png</url>
      <title>DEV Community: Bruno Fernandes</title>
      <link>https://dev.to/brunof94_debug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunof94_debug"/>
    <language>en</language>
    <item>
      <title>Outside in 20: open AI that gives your phone a stopping point</title>
      <dc:creator>Bruno Fernandes</dc:creator>
      <pubDate>Wed, 07 Oct 2026 06:11:50 +0000</pubDate>
      <link>https://dev.to/brunof94_debug/outside-in-20-open-ai-that-gives-your-phone-a-stopping-point-2427</link>
      <guid>https://dev.to/brunof94_debug/outside-in-20-open-ai-that-gives-your-phone-a-stopping-point-2427</guid>
      <description>&lt;p&gt;&lt;em&gt;Entry for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;You have twenty minutes and somewhere familiar to go: a courtyard, a nearby park, or another outdoor place you already know. Opening your phone to decide what to do can become the activity itself.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Outside in 20&lt;/strong&gt;, or &lt;strong&gt;Saia em 20&lt;/strong&gt; in Portuguese, to give that interaction a stopping point. Enter your preferences, mobility constraints, and a place you know. Get a short outdoor activity, an instruction card, and a timer. Prepare the card, put the phone away, and return when you want to reflect.&lt;/p&gt;

&lt;p&gt;The app asks for no GPS access and does not discover destinations. An optional reflection stays on the device. English and Portuguese instructions come from a curated catalogue; open AI matches your preference to an eligible activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://brunof94-debug.github.io/saia-em20-week1/" rel="noopener noreferrer"&gt;Open Outside in 20&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flzrf7eaypmpket185ks8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flzrf7eaypmpket185ks8.jpg" alt="Outside in 20 with its terracotta, sand and deep blue interface" width="800" height="794"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Browser demonstration. Forest photograph: Wolfgang Hasselmann, Unsplash.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Try a preference about noticing colours, listening to birds, or taking a gentle walk. You can inspect the matching details, save a self-contained HTML pocket card, and start the timer. Reloading restores the selected plan and its original end time.&lt;/p&gt;

&lt;p&gt;The first AI setup needs an internet connection and a substantial download. Prepare it before heading outside. The saved pocket card has no scripts or external assets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Brunof94-debug/saia-em20-week1" rel="noopener noreferrer"&gt;Public repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ten automated tests pass.&lt;/strong&gt; They check meaningful application boundaries, including activity eligibility and safe handling of text. The public &lt;a href="https://github.com/Brunof94-debug/saia-em20-week1/actions/runs/37581580997" rel="noopener noreferrer"&gt;GitHub Actions run&lt;/a&gt; completed successfully. It installs locked dependencies, runs tests, builds and checks the app, uploads the browser bundle, and publishes the verified result to GitHub Pages.&lt;/p&gt;

&lt;p&gt;Actual model execution has separate &lt;a href="https://github.com/Brunof94-debug/saia-em20-week1/blob/main/docs/evidence/wasm-only-inference.json" rel="noopener noreferrer"&gt;browser evidence&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;My first approach used SmolLM2-135M with constrained output. It produced valid activity IDs, but repeatedly chose &lt;strong&gt;A&lt;/strong&gt;, even when the preference described a different activity. A successful format check was hiding a recommendation failure.&lt;/p&gt;

&lt;p&gt;I switched to &lt;strong&gt;multilingual-e5-small&lt;/strong&gt;, an open embedding model that turns text into comparable numerical representations. The &lt;a href="https://huggingface.co/intfloat/multilingual-e5-small" rel="noopener noreferrer"&gt;original intfloat model&lt;/a&gt; uses the MIT licence. The app runs its Xenova q8 conversion through &lt;a href="https://huggingface.co/docs/transformers.js/en/index" rel="noopener noreferrer"&gt;Transformers.js&lt;/a&gt;, using WebAssembly on the person's device.&lt;/p&gt;

&lt;p&gt;The flow has four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Filter activities by mobility and goal using deterministic rules.&lt;/li&gt;
&lt;li&gt;Encode the preference with &lt;code&gt;query:&lt;/code&gt; and eligible descriptions with &lt;code&gt;passage:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Average and normalize the representations, then rank by cosine similarity.&lt;/li&gt;
&lt;li&gt;Resolve the selected ID into curated bilingual instructions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The model cannot override the eligibility filters or invent a route. Displayed scores describe similarity; they are &lt;strong&gt;not confidence percentages&lt;/strong&gt; or guarantees that an activity suits a particular place.&lt;/p&gt;

&lt;p&gt;On October 7, browser checks distinguished Portuguese requests about colours and bird/leaf sounds, and English requests about textures and gentle walking. A conflicting walking request also stayed within the seated filter.&lt;/p&gt;

&lt;p&gt;After switching the deployment to a WASM-only runtime, I repeated the Portuguese colour check. It selected B with &lt;strong&gt;144 ms of inference&lt;/strong&gt; and &lt;strong&gt;2,500 ms total&lt;/strong&gt;, with model assets already cached. The evidence records the model revision and ranking. These are observations from one test environment, not cross-browser benchmarks or a broad quality evaluation.&lt;/p&gt;

&lt;p&gt;The model and tokenizer require approximately &lt;strong&gt;135.4 MB&lt;/strong&gt;, plus application/runtime assets. Cached inference depends on completed setup and browser storage that has not been cleared or evicted. The downloadable card provides a simpler way to carry the selected activity offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Openness changes where this decision happens. Preferences are processed locally rather than sent to a remote model API. The model, filters, and catalogue can be inspected and changed independently.&lt;/p&gt;

&lt;p&gt;That separation made the engineering correction possible: I could replace the generator that kept selecting A with a model designed for matching descriptions, while keeping the activity flow. The repository pins the model revision so that choice is reproducible.&lt;/p&gt;

&lt;p&gt;This suits Touch Grass: prepare briefly, then carry an activity instead of an ongoing conversation. I have not conducted an outdoor trial, user study, or interviews. Whether it actually helps people spend less time on their phones still needs testing outside the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;Codex&lt;/strong&gt; for implementation, interface iteration, documentation, validation, and writing support. The &lt;a href="https://github.com/Brunof94-debug/saia-em20-week1/blob/main/docs/AI-DEVELOPMENT.md" rel="noopener noreferrer"&gt;development log&lt;/a&gt; explains the model change, timer persistence fix, cache decisions, and real browser checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Overall prize&lt;/strong&gt;, and &lt;strong&gt;Best Use of GitHub Copilot through GitHub Actions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05#best-use-of-github-copilot"&gt;published category&lt;/a&gt; explicitly includes automating a project with GitHub Actions. My entry uses that route: the linked successful workflow verifies and packages the application. Development assistance came from Codex; the sponsor integration is GitHub Actions.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
