<?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: Ashish Pagariya</title>
    <description>The latest articles on DEV Community by Ashish Pagariya (@ashish_pagariya06).</description>
    <link>https://dev.to/ashish_pagariya06</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%2F4106819%2Ff43cd002-dc5f-47b6-9865-53c109d7e91c.png</url>
      <title>DEV Community: Ashish Pagariya</title>
      <link>https://dev.to/ashish_pagariya06</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashish_pagariya06"/>
    <language>en</language>
    <item>
      <title># TrustForge: A Hackathon Judging System That Shows Its Work</title>
      <dc:creator>Ashish Pagariya</dc:creator>
      <pubDate>Thu, 01 Oct 2026 18:35:27 +0000</pubDate>
      <link>https://dev.to/ashish_pagariya06/-trustforge-a-hackathon-judging-system-that-shows-its-work-46ki</link>
      <guid>https://dev.to/ashish_pagariya06/-trustforge-a-hackathon-judging-system-that-shows-its-work-46ki</guid>
      <description>&lt;p&gt;When we started building TrustForge for DogFood 2026, I assumed the judging dashboard would be the hard part. It turned out to be the easy part. What actually took thinking was a question I hadn't planned for: how do you explain a hackathon result after it's already been published?&lt;/p&gt;

&lt;p&gt;Most judging platforms store scores and pick a winner. We wanted the process behind the winner to be inspectable too, and that one decision ended up shaping almost everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we stayed with a monolith
&lt;/h2&gt;

&lt;p&gt;My first instinct was to split it all up: auth, judging, assignment, scoring, audit and notifications, each as its own service. It sounds scalable, but for a hackathon it would have been a lot of overhead for no real gain.&lt;/p&gt;

&lt;p&gt;So TrustForge is one Spring Boot app with clearly separated modules (authentication, authorization, submissions, judging, normalization, anomalies, audit, results), and a separate React frontend that talks to versioned REST APIs. I cared less about "monolith vs microservices" than about keeping the boundaries explicit without taking on distributed-systems problems we didn't have.&lt;/p&gt;

&lt;p&gt;Everything runs through one pipeline, and it became the mental model for the whole project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SubmissionVersion → Assignment → Evaluation → NormalizationRun
      → Anomaly → AuditEvent → ResultSnapshot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  "Assign judges to projects" is not a simple requirement
&lt;/h2&gt;

&lt;p&gt;On paper it's one line. In practice you have to handle judge capacity, minimum coverage per project, declared conflicts, workload balance, and the fact that rerunning the algorithm should give the same answer.&lt;/p&gt;

&lt;p&gt;We also didn't want an assignment to just say &lt;code&gt;Judge A → Project 12&lt;/code&gt;. We wanted it to carry its reasoning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Judge A → Project 12
Eligible: yes | Conflict: none | Capacity: 12/20
Coverage: satisfied | Fairness: 0.94
Algorithm: v1.2 | Seed: 8f91c7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seed and algorithm version matter more than they look. If an organizer reruns the assignment and gets something completely different, you can't debug it and you definitely can't explain it. Every run records both, and the acceptance tests check that declared conflicts are excluded and coverage is met.&lt;/p&gt;

&lt;h2&gt;
  
  
  Judges don't use the same scale
&lt;/h2&gt;

&lt;p&gt;Say Judge A usually gives 8.5, 9, 9.5, 10 and Judge B usually gives 6, 6.5, 7, 7.5. If you just average, Judge A's habits carry more weight, even though neither judge is wrong. The numbers look comparable, but they aren't.&lt;/p&gt;

&lt;p&gt;So we added per-judge normalization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;z = (score - judge mean) / judge standard deviation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We kept the raw score. Normalization is an interpretation of the data, and I didn't want to throw away the original evidence just because we'd built a transformed version. A judge with zero standard deviation is handled explicitly instead of crashing into a divide-by-zero, and missing evaluations are left missing, never filled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scoring formula was wrong, and it looked fine
&lt;/h2&gt;

&lt;p&gt;This is probably the most useful thing I learned on the project.&lt;/p&gt;

&lt;p&gt;Our methodology says the result combines normalized judging with community voting. While reviewing the implementation, we noticed the two inputs weren't on compatible scales. One was a z-score and the other was a raw vote count. Adding them directly gives you something that looks sophisticated and quietly lets one side dominate.&lt;/p&gt;

&lt;p&gt;That made us ask what "80% judging, 20% community" actually means. It only means something if both signals are mapped to the same range first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final = (judging, scaled 0–100) × 0.80
      + (community, scaled 0–100) × 0.20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The takeaway went beyond this one formula: a score can look reasonable in the UI and still be mathematically off, so check the units, the ranges, the edge cases, and whether the code matches the documented method. It's also why the results page shows the methodology instead of just a final number.&lt;/p&gt;

&lt;h2&gt;
  
  
  An audit table isn't the same as a trustworthy audit log
&lt;/h2&gt;

&lt;p&gt;A normal audit table tells you what's stored. It doesn't tell you whether someone edited the history.&lt;/p&gt;

&lt;p&gt;So we chained the audit events with SHA-256, starting from a &lt;code&gt;GENESIS&lt;/code&gt; value, where each event's hash includes the previous one. Each record stores the previous hash, current hash, actor, action, entity, timestamp, request ID and payload. Verification recomputes the whole chain from the start.&lt;/p&gt;

&lt;p&gt;We also wrote a test that deliberately edits an earlier payload and confirms verification fails. I trust that test far more than one that only checks the happy path returns &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security lives on the backend
&lt;/h2&gt;

&lt;p&gt;It's easy to treat a hidden button as access control. &lt;code&gt;if (user.role === "ORGANIZER") showButton()&lt;/code&gt; is a UX choice, not a security boundary. The backend decides what's allowed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organizer:&lt;/strong&gt; assignment management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judge:&lt;/strong&gt; their own assigned evaluations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Participant:&lt;/strong&gt; the public gallery and voting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In acceptance testing, a judge trying to reach organizer-only assignments got a &lt;code&gt;403&lt;/code&gt;. Access tokens expire, refresh tokens rotate, and reusing an old refresh token after rotation gets rejected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker, and the difference between "written" and "run"
&lt;/h2&gt;

&lt;p&gt;Docker didn't magically solve deployment. The more useful lesson was keeping the design of the deployment separate from the verification of it.&lt;/p&gt;

&lt;p&gt;The repo has a Compose setup with PostgreSQL, Redis, the Spring Boot API, and Nginx serving the React frontend, with health checks gating the startup order. But our acceptance environment didn't have Docker, so we didn't call Compose verified. The acceptance report has two buckets: &lt;code&gt;VERIFIED&lt;/code&gt; and &lt;code&gt;NOT VERIFIED / BLOCKED BY ENVIRONMENT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's a small documentation choice, but it's one of the easiest ways to stop a project looking more finished than it is. "I wrote the config" and "I ran the config" are not the same sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The acceptance suite became part of the product
&lt;/h2&gt;

&lt;p&gt;We didn't want the demo to rest on "trust me, it works." The smoke test covers the seeded gallery, login, dashboard, assignment coverage, normalization, audit verification, results, certificate verification, and role isolation. The live run passed ten checks against the local API. We added focused tests for deterministic normalization, audit tamper detection, assignment conflicts and capacity, and duplicate voting.&lt;/p&gt;

&lt;p&gt;Somewhere along the way the suite stopped being just a test suite and became another way of stating what TrustForge promises.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd change
&lt;/h2&gt;

&lt;p&gt;A runnable demo can make the underlying model look finished, and ours isn't. The demo uses a deterministic in-memory store as a replaceable persistence layer. PostgreSQL and Flyway are part of the deployment design, but the demo shouldn't be mistaken for a production persistence setup.&lt;/p&gt;

&lt;p&gt;If I built it again, I'd:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move the judging model fully into PostgreSQL&lt;/li&gt;
&lt;li&gt;Persist assignment runs and normalization datasets&lt;/li&gt;
&lt;li&gt;Make result snapshots immutable at the database level&lt;/li&gt;
&lt;li&gt;Build a real pairwise ranking model in place of the current read-model placeholder&lt;/li&gt;
&lt;li&gt;Add property-based tests around assignment and scoring&lt;/li&gt;
&lt;li&gt;Make the final weights and normalization ranges explicit in code and tests&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are hidden gaps. They're documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it changed for me
&lt;/h2&gt;

&lt;p&gt;Before this, my question for a feature was "does it work?" TrustForge added two more: can someone understand why it worked, and can they verify that explanation without taking my word for it?&lt;/p&gt;

&lt;p&gt;Those questions changed the architecture, the tests and the UI. They also changed how I think about trust in software: you can't bolt it on at the end. Reproducibility, explainability, versioning, testability and auditability have to be there from the first decision.&lt;/p&gt;

&lt;p&gt;So the idea behind TrustForge is simple: don't just publish the result, preserve the process that produced it.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>java</category>
    </item>
    <item>
      <title>I Built a Privacy Scanner With Zero Dependencies —SafeSearch</title>
      <dc:creator>Ashish Pagariya</dc:creator>
      <pubDate>Wed, 02 Sep 2026 20:48:48 +0000</pubDate>
      <link>https://dev.to/ashish_pagariya06/i-built-a-privacy-scanner-with-zero-dependencies-safesearch-18al</link>
      <guid>https://dev.to/ashish_pagariya06/i-built-a-privacy-scanner-with-zero-dependencies-safesearch-18al</guid>
      <description>&lt;p&gt;DESCRIPTION&lt;/p&gt;

&lt;p&gt;SafeShare is a simple security tool that helps prevent accidental sharing of sensitive information. It scans text and files and looks for things like API keys, Bearer tokens, JWTs, passwords, and other credentials that should not be publicly shared.&lt;/p&gt;

&lt;p&gt;The idea came from a common problem: developers can accidentally expose sensitive information while sharing code, logs, screenshots, configuration files, or uploading projects to GitHub. SafeShare acts as an extra check before that happens.&lt;/p&gt;

&lt;p&gt;PROBLEM STATEMENT&lt;/p&gt;

&lt;p&gt;Sensitive information is often exposed accidentally during development. A developer might copy a token into a message, commit a secret to GitHub, or share a configuration file containing credentials.&lt;/p&gt;

&lt;p&gt;Many existing security tools can be complicated to set up or depend on multiple external packages. For a small and focused security check, I wanted something lightweight that could run locally with minimal setup.&lt;/p&gt;

&lt;p&gt;SOLUTION&lt;/p&gt;

&lt;p&gt;SafeShare scans the provided content and checks it against patterns for different types of sensitive information. When something suspicious is detected, the tool identifies what was found and assigns an appropriate severity level.&lt;/p&gt;

&lt;p&gt;The scanning happens locally, so the content does not need to be sent to an external service just to perform the basic security check.&lt;/p&gt;

&lt;p&gt;KEY FEATURES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects Bearer authentication tokens&lt;/li&gt;
&lt;li&gt;Detects JWTs&lt;/li&gt;
&lt;li&gt;Detects API keys and other credential-like patterns&lt;/li&gt;
&lt;li&gt;Helps identify passwords and sensitive values&lt;/li&gt;
&lt;li&gt;Provides severity levels for detected risks&lt;/li&gt;
&lt;li&gt;Can scan text and files&lt;/li&gt;
&lt;li&gt;Runs locally&lt;/li&gt;
&lt;li&gt;Has zero external dependencies&lt;/li&gt;
&lt;li&gt;Includes automated tests for the detection system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WHAT MAKES IT DIFFERENT&lt;/p&gt;

&lt;p&gt;The main focus of SafeShare is simplicity. It does not try to be a complete enterprise security platform. Instead, it focuses on one practical problem: catching sensitive information before it gets shared.&lt;/p&gt;

&lt;p&gt;Another important part of the project is that it uses zero external dependencies. This keeps the project lightweight, reduces setup requirements, and makes it easier to understand and run.&lt;/p&gt;

&lt;p&gt;TECHNOLOGY USED&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Regular Expressions&lt;/li&gt;
&lt;li&gt;Node.js built-in File System APIs&lt;/li&gt;
&lt;li&gt;Node.js built-in testing tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HOW IT WORKS&lt;/p&gt;

&lt;p&gt;The user provides text or a file to SafeShare. The tool scans the content using detection patterns designed for different types of credentials and sensitive information.&lt;/p&gt;

&lt;p&gt;If a possible secret is found, SafeShare reports the type of information detected along with its severity. This gives the user an opportunity to remove or secure the information before sharing the content.&lt;/p&gt;

&lt;p&gt;TESTING&lt;/p&gt;

&lt;p&gt;I also created automated tests to check whether SafeShare can correctly identify different types of sensitive information.&lt;/p&gt;

&lt;p&gt;The tests include cases such as Bearer tokens and JWTs, along with other credential patterns. This helps make sure that changes to the detection logic do not accidentally break existing functionality.&lt;/p&gt;

&lt;p&gt;PRIVACY&lt;/p&gt;

&lt;p&gt;SafeShare is designed with local processing in mind. Sensitive content can be checked locally instead of being uploaded to a third-party service for scanning.&lt;/p&gt;

&lt;p&gt;This is especially useful when working with private source code, configuration files, logs, or other information that should not leave the user's system.&lt;/p&gt;

&lt;p&gt;PROJECT GOAL&lt;/p&gt;

&lt;p&gt;The goal of SafeShare is not to replace professional security scanners. The goal is to provide a lightweight first layer of protection that can catch obvious credential leaks quickly and with almost no setup.&lt;/p&gt;

&lt;p&gt;FUTURE IMPROVEMENTS&lt;/p&gt;

&lt;p&gt;Some improvements I would like to add in the future include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More credential detection patterns&lt;/li&gt;
&lt;li&gt;Better handling of false positives&lt;/li&gt;
&lt;li&gt;Support for additional file formats&lt;/li&gt;
&lt;li&gt;Configurable detection rules&lt;/li&gt;
&lt;li&gt;Git pre-commit integration&lt;/li&gt;
&lt;li&gt;CI/CD integration&lt;/li&gt;
&lt;li&gt;More detailed security reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PROJECT OUTCOME&lt;/p&gt;

&lt;p&gt;SafeShare demonstrates that a useful security-focused tool can be built using a small amount of code and built-in Node.js functionality. The project currently detects several common types of exposed credentials, provides severity information, and has automated tests to validate its core functionality.&lt;/p&gt;

&lt;p&gt;GITHUB&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ashuuakk06/SafeShare" rel="noopener noreferrer"&gt;https://github.com/ashuuakk06/SafeShare&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DEMO VIDEO&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/xdCAfbfUNfI?si=durWKlty9wn2q2-C" rel="noopener noreferrer"&gt;https://youtu.be/xdCAfbfUNfI?si=durWKlty9wn2q2-C&lt;/a&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>software</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
