Vedant Naik

Application portfolio

Prepared for Formlabs · Manufacturing Test Software Intern · Fall 2026, Somerville, MA

Test software you can trust needs pipelines, specs, and gates. I build all three.

I'm Vedant, a CS student at UGA and a Software Engineering Intern at Voya Financial, where I own an AI-assisted migration across 3,600+ test files: OpenRewrite for the bulk, Copilot agents for the long tail, MCP for the tools, and a parity gate so nothing silently breaks.

3,600+
JUnit 4 test files in scope
6,000+
test cases, behavior preserved
1.8M+
people served by the product
0
regressions tolerated, count parity

The role, mapped

Every responsibility in the posting, matched

Tools for calibration, validation, and rigorous testing A 6,000+ case migration behind a deterministic gate: green suite plus exact test-count parity, a zero-regression bar. Case study 01 →
Manage requirements across cross-functional engineering teams A build-vs-buy MCP memo argued with verified/inferred evidence tags; UGA Manufacturing Club president, now tech chair. Build vs. buy →
Hardware modifications to printers and test setups SolidWorks CAD and a Bambu Lab 3D printer at home; Python control system work on a Zeus 2Q humanoid. Background →
Own the test-tools lifecycle, design to maintenance The migration owned end to end: skill spec, per-batch metrics, completion procedure; PrimeBook shipped solo, schema to Stripe. Case study 02 →
Data science on production lines for operations SimPy digital twin of a 6-station assembly line at VIPR-Lab: MQTT telemetry in, Streamlit dashboard out. Background →
Improve development and deployment processes continuously CI/CD at STW Robotics cut defects ~30%; atomic, revertible PRs and per-batch metrics on the Voya migration. Background →

Case study 01 · Voya Financial, Benefitfocus division

An AI-assisted migration that cannot silently break anything

The suite behind a product serving 1.8M+ people needed to move from JUnit 4 to 5, with zero tolerance for a test silently going missing. Hand-conversion doesn't scale, scripts miss the subtle cases, and pure LLM runs are costly and non-deterministic, so the pipeline splits the work by character.

Per-batch migration workflow, current state AGENT CONTEXT · LOADED ONCE SKILL.md rulebook · executor + reviewer profiles · MCP semantic tools log metrics in tracker · next slice 01 · INVENTORY list files + count 02 · GREEN? must pass 03 · OPENREWRITE dry-run → review → apply pom diff: mockito 4.x 04 · EXECUTOR AGENT residue · 5-file batches conversion-only edits 05 · GATE count parity 06 · REVIEWER AGENT read-only tools PASS / ISSUES + file:line 07 · COMMIT + PR human only · .java files atomic + revertible RED → DEFER log in tracker · skip resume next slice fail → fix or revert issues → fix · re-gate COMPLETION when 0 JUnit 4 imports remain remove Vintage + JUnit 4 deps final green · final PR

Hover a stage for a summary; click it to open the full description. Each slice ships as one atomic, revertible PR.

deterministic · trusted agentic · long tail human · commit gate error handling · designed-in fail paths
1–8Stage-by-stage detail8 stages
  1. 01 DETERMINISTIC

    Inventory the slice

    List the slice's JUnit 4 files and count them. Cheap, exact, free.

  2. 02 DETERMINISTIC

    Baseline gate: the slice must already be green

    Run the slice's tests and record the passing count. You never migrate a red slice, because you couldn't tell a new failure from a pre-existing one.

    red → defer, log in the tracker, next slice
  3. 03 DETERMINISTIC

    OpenRewrite converts the mechanical bulk

    The JUnit4to5Migration recipe handles roughly 90%: imports, annotations, assertThrows, runner-to-extension swaps, and the argument-order flip. Dry-run first, review the patch, then apply. Exact and identical every time.

  4. 04 AGENTIC

    Copilot executor cleans the residue

    A custom agent converts what determinism can't: custom rules, parameterized tests, house import conventions. It follows the skill's rulebook, works in 5-file batches, and is given the smallest possible job.

  5. 05 DETERMINISTIC

    Test + count-parity gate

    Re-run the slice. It must be green with the same test count as the baseline. However a file was converted, a test that fails to compile or stops running cannot pass this gate.

    fail → fix or revert, never commit a regression
  6. 06 AGENTIC

    Reviewer agent audits the diff

    A second agent that didn't do the work checks the changes against the rules and reports PASS or ISSUES with file and line. It runs with read-only tools, so it structurally cannot edit.

  7. 07 HUMAN

    I review, commit, and open the PR

    The agents never touch git. Every batch is atomic and revertible, which makes the human review gate real and keeps an undo button under everything.

  8. 08 LOOP

    Next slice

    Metrics logged per batch: files converted, OpenRewrite-vs-agent split, test count before and after. The tracker is the zero-regression evidence trail.

The fault tolerance is concentrated at stage 5. The agents can slip and the recipe can miss a case, but nothing broken can get past a deterministic, unskippable gate.

per-batch looppseudocode
for slice in tracker.next():
    base = mvn_test(slice)                # must be green first
    if base.red:
        tracker.defer(slice); continue    # log + skip, never fix here

    openrewrite.dry_run(slice).review().apply()
    executor.clean_residue(slice, skill)  # agentic, 5-file batches

    out = mvn_test(slice)
    assert out.green
    assert out.count == base.count        # no test silently dropped

    reviewer.audit(slice.diff)            # read-only: PASS / ISSUES
    human.review_commit_pr(java_only)     # agents never touch git
    tracker.log_metrics(slice)
The whole loop in fourteen lines; the two asserts are the acceptance criteria every batch must clear.

Case study 01, continued · the MCP layer

Build vs. buy on MCP, decided with evidence

Scaling the agent side needed semantic tools, not text search. MCP, the Model Context Protocol, is how agents get tool and function calling against real systems, so I evaluated buy vs. build and made the call.

Buy: Moderne's local MCP server

18 tools, wired into Copilot

Wired into Copilot in JetBrains via manual mcp.json: semantic search, structural matching, and recipe execution as agent tools. Org policy and licensing gates mapped.

Build: a minimal custom server

3 tools on the TypeScript MCP SDK

A stdio server scoped on the TypeScript MCP SDK over the free OpenRewrite plugin: 1 to 3 days, building on a prior scaffold of mine.

The recommendation

Keep the free path running, decide on facts

Run the $0 scripted path now, price the vendor seat in parallel, build only if in-agent tool calling is confirmed. Security-reviewed first: stdio, no telemetry, no phone-home.

every claim in the memo is tagged → [VERIFIED] [INFERRED] [NEEDS INTERNAL CHECK]
</>File excerpts · server design sketch and tagged memo2 files
custom-openrewrite-mcp · index.tsdesign sketch
// The 3-tool alternative scoped in the memo:
// TypeScript MCP SDK, stdio transport, over the free
// Apache-2.0 rewrite-maven-plugin.
const server = new McpServer({ name: "openrewrite" });

server.registerTool("list_recipes", {},
  async () => parse(await mvn("rewrite:discover")));

server.registerTool("dry_run",
  { recipeId: z.string(), modulePath: z.string() },
  async ({ recipeId, modulePath }) => {
    await mvn("rewrite:dryRun -Drewrite.activeRecipes="
      + recipeId, modulePath);
    return readDiff(modulePath
      + "/target/rewrite/rewrite.patch");
  });

// run_recipe modifies source, so it is gated:
// refuses without an explicit apply: true flag.
server.registerTool("run_recipe", guarded(applyHandler));

await server.connect(new StdioServerTransport());
Design sketch from the build-vs-buy memo, not shipped code: dry-run by default, the write path gated, every tool a thin wrapper over a deterministic Maven goal.
MCP research memoexcerpt · sanitized
Licensing: raw OpenRewrite (rewrite-maven-plugin) is
Apache-2.0; no license or token needed for
private repos.                            [VERIFIED]

Security: mod mcp runs as a stdio subprocess, makes
no network calls by default, sends no
telemetry.                                [VERIFIED]
License signature is checked against a key packaged
in the CLI - no phone-home.               [VERIFIED]

Org gate: the "MCP servers in Copilot" policy is off
by default on Business plans.  [NEEDS INTERNAL CHECK]

Recommendation: keep the $0 scripted path running;
greenlight the ~1-3 day custom build only if in-agent
tool calling is a confirmed requirement.  [INFERRED]
Every claim in the memo carries an evidence tag, so the reader always knows what was verified against docs, what was inferred, and what still needs an internal check.

Case study 02 · the skill surface agents build from

Intent in the runbook, requirements in the skill, acceptance criteria in the gate

The migration runs on written specs, not vibes: engineers and agents execute from the same three artifacts.

The skill

junit5-migration, on the open Agent Skills standard

The runtime rulebook: full mapping, Java 8 and Mockito ceilings, batch rules, hard nevers. Company SOPs isolated so it ports by swapping one section.

The agents

Executor and reviewer, separated by design

The executor converts in 5-file batches and can't commit; the reviewer runs read-only. Separation of duty by configuration, not promise.

The runbook

A living spec anyone can pick up

Definition of Done, disposition policy, PR conventions, rollback, risk register, metrics tracker. Anyone can pick it up and run it.

</>File excerpts · the skill and the reviewer agent2 files
junit5-migration / SKILL.mdexcerpt · sanitized
---
name: junit5-migration
description: Migrates this repo's remaining JUnit 4 tests to
  JUnit 5, following the company SOPs and case notes below.
allowed-tools: shell
---

## Mapping (excerpt)
@Test(expected = E.class)      ->  assertThrows(E.class, () -> ...)
@Rule ExpectedException        ->  assertThrows
@RunWith(Parameterized.class)  ->  @ParameterizedTest + @MethodSource

Critical - the silent one: the assertion message moves from
FIRST to LAST. assertEquals("msg", expected, actual) ->
assertEquals(expected, actual, "msg"). This compiles either
way, so the build will not catch it.

### Never
- Never change a test's assertions, logic, or coverage.
- Never run git commit or git push - the human commits.
The rulebook the executor loads at runtime. Company SOPs live in their own section, so the generic mechanics port to the next repo unchanged.
junit5-migration-reviewer.agent.mdexcerpt · sanitized
---
name: junit5-migration-reviewer
description: Read-only reviewer. Audits each migration batch
  against the rules. Reports only; never edits.
tools: ["read", "search"]
---

You are an oversight reviewer for JUnit 4 -> JUnit 5 changes.
Your ONLY job is to review. You never edit code, never run
commands, and never fix anything - you report findings only.

Output a verdict - PASS or ISSUES - with the file and line
for each problem.

You cannot run the build, so never claim the suite is green.
If correctness depends on test results, say the human must
confirm with mvn test.
Separation of duty enforced in configuration, not by promise: with tools: ["read","search"] the reviewer structurally cannot edit, and it is told not to claim results it cannot verify.

Case study 03 · making it safe to run

Validation gates, rollback paths, human checkpoints

Generative systems propose, deterministic systems verify, humans hold the commit rights. Tooling that rewrites thousands of tests only works when the validation gate is the most trusted part of the system.

Evaluation

An unskippable acceptance gate

Compile + full green + count parity vs. baseline, every batch. Validated by the gate, not by trust.

Separation of duties

Editor, auditor, committer: three roles

The editor never reviews, the reviewer can't edit, only the human commits.

Observability

Metrics as the evidence trail

Per-batch monitoring and logging: files converted, recipe-vs-agent split, counts before and after.

Access & scope

Least privilege for tools and diffs

Conversion-only diffs, production code untouchable, agents blocked from git.

Responsible sourcing

Diligence before integration

License and no-telemetry checks before any tool touches the IDE.

Responsible data handling

Sanitized by default

Sanitized by default: no internal identifiers, credentials, or customer data in anything shareable.

Case study 04 · Voya internal AI competition

ClearPath: a blocker-triage copilot for the whole company

Built in Microsoft 365 Copilot Agent Builder for Voya's intern AI competition: paste rough blocker notes, get copy-ready output. Works in reverse on vague issues you receive.

The product is the spec

The product is the instructions

7.4K characters of system instructions: an adaptive seven-section output contract, a grounding knowledge doc, starter prompts.

Accuracy rules as guardrails

Organizes information, never invents it

Uses only what the user provided, never invents causes or metrics, labels assumptions, marks unknowns TBD.

Built for adoption

Companywide by design

One-step workflow designed for companywide reuse; adoption was a design constraint, not an afterthought.

</>File excerpt · the accuracy rules1 file
ClearPath · agent instructionsexcerpt · sanitized
# Accuracy Rules
- Use only information the user provided. Never invent
  facts, causes, owners, approvers, timelines, dates,
  metrics, or resolutions.
- Separate confirmed facts from assumptions, and label
  assumptions.
- State missing information as missing; mark unknowns
  as unknown or TBD.
- If notes contain credentials, personal information, or
  customer data, use neutral placeholders such as
  [Employee], [Team], [System] and recommend the user
  replace them before sharing.
Guardrails written into the system instructions themselves: the agent is constrained to organize what it was given, never to fabricate, and to push sanitization back to the user.

Background

Earlier systems work

VIPR-Lab · UGA research

Digital twin of an assembly line

SimPy digital twin of a 6-station assembly line, Streamlit dashboard, MQTT.

STW Robotics · internship

Humanoid robot control system

Python control work on the Zeus 2Q humanoid; CI/CD; roughly 30% defect reduction.

PrimeBook · founder build

A SaaS running a real business

Multi-tenant booking platform built solo for my own detailing company; agent-assisted from day one, with AGENTS.md as the standing spec coding agents build from.

UGA Manufacturing Club

Tech lead

Own the club's website and technical infrastructure.

Working stack

Python SQL SimPy MQTT Streamlit SolidWorks Java TypeScript CI/CD Git Maven OpenRewrite REST / JSON APIs Prompt & tool design MCP (TypeScript SDK) GitHub Copilot agents & skills M365 Copilot Agent Builder