Inspiration

Banks, insurers and governments still run on COBOL, Fortran, C and assembly written decades ago. The people who wrote it are retiring, and rewriting it is risky because nobody can fully say what the old code does. AI can turn COBOL into Java in seconds, but that doesn't help much on its own: no engineer will ship a rewrite they can't check. We wanted to build modernization that comes with evidence, so a reviewer can see what each agent did, which business rules it kept, and proof that the new code behaves exactly like the old code.

What it does

AgentBox is a multi-agent workspace for modernizing legacy software. You upload a zip of a legacy system, then watch four agents work on it live:

  1. Analyzer: packages the zip into a Docker image (writing a Dockerfile for the detected languages if there isn't one), lists every file and its dependencies (copybooks, called programs, JCL, DDL), and compiles every program inside a locked-down sandbox. Programs that compile and need nothing from outside the sandbox are marked verifiable; the rest are deferred, with the reason. NVIDIA Nemotron then reads each program with tools, pulls out its business rules (given / when / then, tied to legacy line numbers), and picks a target language, a first slice and a migration order.
  2. Translator: rewrites a program from the first slice in the target language (Python, Java, TypeScript, JavaScript, C or Go) and maps each business rule to lines in the new code.
  3. Verifier: has Nemotron design test inputs from the business rules, runs the legacy program in its own container to record the expected outputs, then runs the modern code on the same inputs. Outputs and exit codes have to match.
  4. Debugger: fixes failing cases in up to 5 attempts. It only sees the "debug" cases. A separate "holdout" set is never shown to it, so passing those shows the fix actually generalizes and isn't fitted to the tests. A final shadow rerun checks that the result is stable.

Every step (status, code versions, test cases, results, changes, debug attempts, rule status, agent logs) streams into SpacetimeDB, and the React dashboard shows it in real time: the modernization workspace, agent activity, validation investigation and generated documentation.

How we built it

  • Backend / state: a SpacetimeDB module in TypeScript on Maincloud, with 14 tables, a run state machine, heartbeats, worker presence, a watchdog and reducers that only registered writers can call. The NVIDIA API key lives only in the database's environment, and agents reach Nemotron through a writer-only nemotron_chat procedure, so the key never touches a worker, the repo or a container.
  • Agents: a Node.js / TypeScript worker running tool-calling loops on NVIDIA Nemotron 3.5. Each agent's answer is checked against a schema, and bad answers go back to the model to fix. Answers are cached by content hash, so re-running the same zip is fast and gives the same result.
  • Sandbox: every legacy and modern program runs in Docker with --network none, a read-only filesystem, all capabilities dropped, no-new-privileges, and memory, CPU and process limits. Zip extraction checks for zip-slip, symlinks and size bombs.
  • Language profiles: COBOL (GnuCOBOL), C (GCC), Fortran (gfortran) and x86 assembly (NASM/GAS). Each profile covers file extensions, a dependency scanner, a toolchain and a syntax-check command.
  • Frontend: React, TypeScript and Vite, designed in Figma, using SpacetimeDB's generated client bindings for live subscriptions.
  • Sample: a COBOL payroll program (input validation, overtime at 1.5x over 40 hours, 10/20/30% marginal tax brackets, totals, return code 4 on bad records) that we used to test the pipeline end to end.

Challenges we ran into

  • Reasoning tokens: Nemotron 3.5 is a reasoning model, and its thinking tokens count against max_tokens. Early calls ran out of tokens before producing an answer, so we had to tune token budgets and turn thinking off for quick calls.
  • Time limits: SpacetimeDB procedures time out at 180 s, so agent calls had to be split into short turns, with retries and heartbeats so a stuck run gets noticed.
  • Getting reliable structured output: the model sometimes left out required fields (for example a business rule with no title). We added validation and a repair loop instead of trusting the first answer.
  • Defining "the same behavior": we had to pick a strict, written comparison rule (normalize line endings and trailing whitespace, and require matching exit codes) and keep holdout tests away from the Debugger so passing actually means something.
  • Running untrusted legacy code safely: generating Dockerfiles for old toolchains and building programs inside a sandbox with no network.

Accomplishments that we're proud of

  • A full pipeline (Analyzer, Translator, Verifier, Debugger) where the proof comes from running the real legacy program, not from an LLM judging its own work.
  • The holdout-test design, which keeps the Debugger from just fitting the tests.
  • Keeping security tight under hackathon time pressure: no network in the sandbox, and the API key never leaves the database.
  • A live dashboard backed by SpacetimeDB, where every agent action can be reviewed.
  • Unit tests for the analyzer, dockerization and modernize logic.

What we learned

  • With LLM agents, verification is the product. Running the old code to get the expected outputs was worth more than any prompt tweak.
  • How to use SpacetimeDB as more than a database: reducers, scheduled watchdogs, procedures that make outbound calls, and live subscriptions for the UI.
  • How reasoning models behave in tool loops (token budgets, validation, caching), and how much legacy COBOL is really just business rules hidden in fixed-format code.

What's next for AgentBox

  • Modernizing programs with external dependencies (DB2, CICS, VSAM files) by mocking those services in the sandbox, so "deferred" programs can be verified too.
  • Moving past the first slice to whole-system migration in the order the Analyzer chose, with shadow traffic before cutover.
  • More legacy languages (PL/I, RPG) and target languages.
  • Human-in-the-loop review: approving or rejecting rule mappings and code changes directly from the dashboard.

Built With

Share this project:

Updates

Submission history