<?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: Harshul</title>
    <description>The latest articles on DEV Community by Harshul (@harshullodha).</description>
    <link>https://dev.to/harshullodha</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%2F4117836%2F02b16e71-d37d-4fc8-a22d-5a7016816a72.png</url>
      <title>DEV Community: Harshul</title>
      <link>https://dev.to/harshullodha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshullodha"/>
    <language>en</language>
    <item>
      <title>Building a privacy-first face-analysis tool without turning it into a diagnostic system</title>
      <dc:creator>Harshul</dc:creator>
      <pubDate>Sun, 27 Sep 2026 15:49:48 +0000</pubDate>
      <link>https://dev.to/harshullodha/building-a-privacy-first-face-analysis-tool-without-turning-it-into-a-diagnostic-system-cdf</link>
      <guid>https://dev.to/harshullodha/building-a-privacy-first-face-analysis-tool-without-turning-it-into-a-diagnostic-system-cdf</guid>
      <description>&lt;p&gt;When software accepts a face photo, the product boundary matters as much as the model. A useful tool can explain visible, presentation-oriented signals without pretending to make medical, identity, or personality judgments. That boundary is the design problem behind iLook.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the product is designed to explain
&lt;/h2&gt;

&lt;p&gt;iLook is a privacy-first, non-medical AI face-analysis tool for a photo a user chooses to provide. Its explanations cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;face-shape context&lt;/li&gt;
&lt;li&gt;visible facial-symmetry signals&lt;/li&gt;
&lt;li&gt;Golden Ratio phi comparisons&lt;/li&gt;
&lt;li&gt;subjective presentation feedback in clear language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The product is intentionally framed around observable presentation signals. It does not need to turn a photo into a diagnosis to be useful. The core web experience is free, so someone can explore the explanations before deciding whether the developer surfaces are relevant to a project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the product boundary matters
&lt;/h2&gt;

&lt;p&gt;Face-related software is easy to overstate. A responsible implementation should make the input explicit, describe what the output represents, and avoid implying that an estimate is a fact about a person. That means using language such as “visible symmetry signal” or “face-shape context” rather than claiming medical or identity conclusions.&lt;/p&gt;

&lt;p&gt;The same principle applies to product UX: let the user choose the image, explain what will be analyzed, and present the result as an interpretation rather than an authority. Clear scope makes the tool easier to evaluate and easier to integrate.&lt;/p&gt;

&lt;h2&gt;
  
  
  A developer-facing surface
&lt;/h2&gt;

&lt;p&gt;In addition to the web experience, iLook exposes REST and OpenAPI surfaces, with MCP and A2A interfaces for consent-based integrations. That makes it possible to prototype a workflow around machine-readable results instead of scraping a page. A team can keep the user-facing explanation in the loop while still connecting the analysis to a product experiment or internal tool.&lt;/p&gt;

&lt;p&gt;The practical checklist is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep consent and image choice visible in the flow.&lt;/li&gt;
&lt;li&gt;Describe only the signals the system actually returns.&lt;/li&gt;
&lt;li&gt;Separate observable output from subjective feedback.&lt;/li&gt;
&lt;li&gt;Keep integrations documented and easy to inspect.&lt;/li&gt;
&lt;li&gt;Treat privacy and non-medical scope as product requirements, not footnotes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can explore the free web experience at &lt;a href="https://www.ilook.fit/" rel="noopener noreferrer"&gt;iLook AI Face Analysis&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building a Privacy-First Face-Analysis API with REST, MCP, and A2A</title>
      <dc:creator>Harshul</dc:creator>
      <pubDate>Wed, 09 Sep 2026 15:54:39 +0000</pubDate>
      <link>https://dev.to/harshullodha/building-a-privacy-first-face-analysis-api-with-rest-mcp-and-a2a-2bi7</link>
      <guid>https://dev.to/harshullodha/building-a-privacy-first-face-analysis-api-with-rest-mcp-and-a2a-2bi7</guid>
      <description>&lt;p&gt;Teams building image-aware products usually discover the same problem: the demo is easy, but the contract around the demo is not. A useful system has to explain exactly what it measures, what it refuses to infer, how clients can integrate it, and how a result can be inspected later.&lt;/p&gt;

&lt;p&gt;This post describes the design I am using for iLook, a privacy-first browser tool for exploring visible facial geometry in a user-provided photo. The goal is not identity, ranking, or diagnosis. The goal is a clear, bounded report that a person can understand and a developer can consume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a narrow, testable scope
&lt;/h2&gt;

&lt;p&gt;A face-analysis service should begin with an explicit scope statement. For iLook, the service works with visible geometry in the supplied image and can explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;approximate face-shape proportions&lt;/li&gt;
&lt;li&gt;symmetry signals and measurement confidence&lt;/li&gt;
&lt;li&gt;relative distances and ratios&lt;/li&gt;
&lt;li&gt;Golden Ratio phi context as an educational reference&lt;/li&gt;
&lt;li&gt;structured presentation notes that are not medical advice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not identify a person, build a biometric profile, infer sensitive traits, or make a medical or high-impact decision. These boundaries are product requirements, not just copy for a landing page. They affect the data model, error handling, retention policy, and review process.&lt;/p&gt;

&lt;p&gt;A practical threat model asks four questions before implementation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What data is received, and is it necessary for the requested result?&lt;/li&gt;
&lt;li&gt;What is retained after the result is returned?&lt;/li&gt;
&lt;li&gt;Which outputs could be misunderstood as a judgment rather than a measurement?&lt;/li&gt;
&lt;li&gt;How can a client tell that a result is partial or low confidence?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Writing these answers down makes later API and UI decisions much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  A useful response is explainable, not merely numeric
&lt;/h2&gt;

&lt;p&gt;A single score is difficult to audit. A better response separates observations from interpretation. An illustrative response shape might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"complete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"face_shape"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oval"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.82&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"symmetry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"balanced"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.74&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"proportions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"width_to_height"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.81&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phi_context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"note"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Educational comparison; not a quality score"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"limitations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Lighting and camera angle can change visible measurements"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Results describe the supplied image, not a person's identity"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important detail is the presence of confidence and limitations beside every meaningful signal. If the image is tilted, heavily shadowed, or cropped, the system should say so instead of hiding uncertainty behind a precise-looking number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep transport separate from the analysis model
&lt;/h2&gt;

&lt;p&gt;REST and OpenAPI are a useful baseline because they work in browsers, scripts, and conventional backend systems. The transport layer should accept an image reference or upload, validate size and type, and return a job or a result with a stable schema version.&lt;/p&gt;

&lt;p&gt;The analysis model should not know whether the request came from REST, an MCP client, or an A2A message. That separation makes it possible to add new clients without duplicating safety checks. It also makes testing simpler: the same fixture image can be sent through every adapter and compared against the same expected structure.&lt;/p&gt;

&lt;p&gt;For a production integration, document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authentication and rate limits&lt;/li&gt;
&lt;li&gt;accepted image formats and maximum dimensions&lt;/li&gt;
&lt;li&gt;synchronous versus asynchronous behavior&lt;/li&gt;
&lt;li&gt;error codes for invalid, unsupported, or low-quality images&lt;/li&gt;
&lt;li&gt;retention and deletion behavior&lt;/li&gt;
&lt;li&gt;schema versioning and deprecation policy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MCP and A2A are adapters, not shortcuts
&lt;/h2&gt;

&lt;p&gt;MCP can make a bounded analysis capability discoverable to an assistant. A good tool definition states the input, output, and limits in plain language. For example, a tool might be named &lt;code&gt;analyze_visible_face_geometry&lt;/code&gt; and return the same structured result as REST. The description should explicitly say that the tool reports visible geometry from the supplied image and does not identify people or infer sensitive attributes.&lt;/p&gt;

&lt;p&gt;A2A is useful when one agent needs to request work from another service. The agent-facing contract should carry the same schema version, confidence values, and limitations. An orchestrator can then decide whether to show the result, ask for a better image, or stop because the requested operation is outside scope.&lt;/p&gt;

&lt;p&gt;The rule I use is simple: protocol adapters may change the envelope, but never the safety contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the edges, not only the happy path
&lt;/h2&gt;

&lt;p&gt;The most valuable tests are usually not the perfect front-facing image. Include fixtures for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;low light and strong backlight&lt;/li&gt;
&lt;li&gt;partial occlusion and side angles&lt;/li&gt;
&lt;li&gt;multiple faces when the workflow expects one&lt;/li&gt;
&lt;li&gt;very small or very large images&lt;/li&gt;
&lt;li&gt;unsupported formats and corrupt uploads&lt;/li&gt;
&lt;li&gt;repeated requests and network retries&lt;/li&gt;
&lt;li&gt;prompt injection text embedded in an image or filename&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For every fixture, assert both the result and the refusal behavior. A system that returns a confident-looking answer for an unusable image is harder to trust than one that clearly reports a limitation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the user-facing explanation part of the API
&lt;/h2&gt;

&lt;p&gt;Developers often treat explanations as UI copy added at the end. That is backwards. The explanation should be generated from the same structured fields that the API exposes, so the browser view, REST client, MCP tool, and A2A agent do not drift apart.&lt;/p&gt;

&lt;p&gt;That is the design direction behind &lt;a href="https://www.ilook.fit/" rel="noopener noreferrer"&gt;iLook&lt;/a&gt;: a privacy-first way to explore visible facial geometry with a readable report and machine-readable integration paths. The product is free to try, and the useful constraint is that every result should remain understandable, bounded, and easy to question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing checklist
&lt;/h2&gt;

&lt;p&gt;Before shipping an image-analysis capability, verify that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the scope is written in one paragraph and reflected in the schema&lt;/li&gt;
&lt;li&gt;uncertainty is visible beside measurements&lt;/li&gt;
&lt;li&gt;the same result model is used by REST, MCP, and A2A adapters&lt;/li&gt;
&lt;li&gt;deletion and retention behavior are documented&lt;/li&gt;
&lt;li&gt;unsafe or ambiguous inputs produce explicit limitations&lt;/li&gt;
&lt;li&gt;examples teach users how to integrate without implying more certainty than the system has&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small, honest contract is more valuable than a large list of impressive outputs. It gives developers something they can test, users something they can understand, and reviewers a clear way to see whether the product is behaving as designed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>privacy</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
