Module 2: Legacy Codebase Modernization¶
Duration: ~75 minutes
Goal: Migrate a legacy application safely using Antigravity CLI primitives — strict permissions gating, agent self-onboarding, parallel subagent analysis, hooks as guardrails, and /rewind as your safety net.
Exercise PRDs: .NET Modernization · Java Upgrade
📖 Sources: Permissions · Strict Mode · Subagents · Skills · Hooks · cli-features · cli-using
Why Legacy Modernization Is Hard¶
The risk in large migrations isn't the code changes — it's the unknowns. You don't know what you'll break until it's broken. The three failure modes are:
- Scope creep — the agent refactors things you didn't ask it to touch
- Context collapse — after a long session, the agent loses track of your migration constraints
- No rollback — a wrong change cascades before you can stop it
AGY's primitives address all three directly.
2.1 — Strict Permissions: Read Before You Write 15 min¶
The AGY equivalent of "Plan Mode" is strict permissions — a hard gate that denies all file writes and shell commands until you explicitly permit them.
Lock Down Before You Explore¶
Set the level to strict:
In strict mode the agent can read files, search the web, and reason — but cannot write, delete, or execute anything. It's a hard wall, not a soft prompt.
📖 Source: Strict Mode · Permissions
Now Investigate Freely¶
With writes locked, give the agent an unconstrained read mandate:
Analyze this entire codebase for a migration. Map:
1. Framework versions and dependency tree (check package.json / pom.xml / .csproj)
2. Architectural patterns in use (MVC, layered, hexagonal)
3. All deprecated API usage (javax.* imports, legacy auth patterns, XML config)
4. Configuration files and external property sources
5. Test frameworks and coverage gaps
6. Migration risks ordered by severity
What's happening: The agent reads every file it needs, traces imports and call chains, and builds a mental model — all with zero risk of modification. This is your reconnaissance phase.
Review the Plan in Your Editor¶
Once the agent produces a migration plan, open it in your editor to refine it:
This drops you into $EDITOR with the current agent output. Edit constraints, add team-specific requirements, strike out scope you don't want. The agent incorporates your edits when you save and exit.
📖 Source: cli-using — Keybindings — uid 3_276–3_280: "Edit prompt inside your default shell editor"
Unlock Writes — But Only for What You Approved¶
Once the plan is signed off, restore write access selectively:
In request-review mode, the agent asks for approval before every write or shell command. You see exactly what it wants to do before it does it.
The flow:
strict(investigate) → approve plan →request-review(execute with oversight) →always-proceedonly for trusted, well-tested final steps.
2.2 — AGENTS.md: Encoding Migration Standards 10 min¶
Context collapses over long sessions. AGENTS.md is how you prevent it — it's injected into every session automatically, no matter how long the conversation runs.
Agent Self-Onboarding¶
The most powerful pattern is having the agent write its own AGENTS.md from what it found during investigation. It encodes what it learned as guardrails for its own subsequent work.
Based on your codebase analysis, write an AGENTS.md that:
1. Documents current state (Spring Boot 2.6, Java 8, javax.* namespaces)
2. Defines target state (Spring Boot 3.3, Java 21, jakarta.* namespaces)
3. Sets migration rules:
- Migrate one module at a time — never touch more than one bounded context per session
- Every migrated class must have a passing test before moving on
- Preserve all existing API contracts — no breaking changes to callers
- Commit after each completed phase with a structured message
4. Flags the specific risks you identified in your analysis
5. Lists files that are off-limits in this phase
Write this to AGENTS.md in the project root.
Why self-onboarding works: The agent is writing instructions for itself. Every migration decision it makes from this point forward is checked against constraints it authored. This is a self-reinforcing loop — better context produces better changes, which surface more patterns, which improve context.
Modular Context with @file Imports¶
For large projects, keep AGENTS.md lean and import detailed specs:
# AGENTS.md
@./docs/migration/architecture-target.md
@./docs/migration/api-contracts.md
@./docs/migration/phase-1-checklist.md
📖 Source: cli-using — AGENTS.md import syntax
Rules Files for Hard Constraints¶
For non-negotiable requirements, use .agents/rules.md — these are injected as system prompt directives, not just context:
# .agents/rules.md
- NEVER delete migration files (MIGRATION.md, phase-*.md)
- NEVER modify files outside the current migration module's directory
- ALWAYS run the test suite before declaring a phase complete
- ALWAYS commit with message format: "migrate(phase-N): <description>"
📖 Source: cli-using —
.agents/rules.mdsystem prompt directives
2.3 — Subagents: Parallel Analysis Teams 15 min¶
Large migrations have multiple independent concerns — security, performance, API contracts, test coverage. Running them sequentially is slow and wastes the agent's context window. Use subagents to parallelize.
Spawn a Parallel Analysis Team¶
I need three parallel analyses before we start migrating. Please spawn:
1. A security-analysis subagent: scan every auth and session-handling class
for OWASP Top 10 issues. Read-only. Report back with file paths and line numbers.
2. A dependency-map subagent: trace all inter-module dependencies and identify
which modules can be migrated independently vs which have shared state.
Produce a migration-order recommendation.
3. A test-coverage subagent: list every public method in the auth module with
no test coverage. Produce a test-gap report.
Run all three concurrently. I'll review the reports before we start Phase 1.
Monitor from the Subagents Panel¶
The panel shows all running subagents with status: running, done, killed. Watch all three finish simultaneously.
Teleports you to the next subagent waiting for your approval — useful if one hits a permission boundary and needs a go-ahead.
Fast-approve a subagent permission request from the main conversation without leaving your current context.
📖 Source: cli-features — Subagents — uid 5_278–5_316
Custom Subagent Definition¶
Create a read-only security scanner in .agents/agents/security-scanner.md:
---
model: gemini-3.1-flash-lite-preview
tools:
allow:
- read_file
- list_directory
- grep_search
# No write_file, no run_command — this agent is read-only
---
You are a security analyst specializing in migration risk assessment.
Your job is to identify vulnerabilities in legacy code that could be
amplified during a modernization effort.
Focus on:
- Authentication and session management anti-patterns
- SQL injection vectors in legacy data access layers
- Hardcoded credentials or secrets in configuration files
- Deprecated cryptographic primitives (MD5, SHA-1, DES)
- Unvalidated redirects or file path traversal risks
Always report: file path, line number, severity (HIGH/MEDIUM/LOW), and remediation.
Never modify any file. Never execute any command.
📖 Source: Subagents · cli-features — uid 5_274: fine-grained permissions JSON format
2.4 — Skills: Reusable Migration Expertise 10 min¶
Skills are instruction sets the agent reads and activates when relevant. For repeatable migrations (Java 8→21, .NET Framework→.NET 8, Express→Fastify), encode the pattern once as a skill.
Browse Available Skills¶
Create a Migration Skill¶
Create ~/.gemini/antigravity/skills/java-migration/SKILL.md:
---
name: java-migration
description: >
Guides Java 8 to Java 21 + Spring Boot 3.x migration. Activates when
the user mentions javax.*, Spring Boot 2.x, or Java upgrade. Provides
phase-by-phase migration steps, jakarta.* namespace rules, and
mandatory test-gate requirements between phases.
---
## Java 8 → 21 Migration Protocol
### Phase 0 — Inventory (always first)
- Run: grep -r "javax\." src/ | grep -v test | sort | uniq -c | sort -rn
- Identify all Spring Boot starter versions in pom.xml
- Check for removed APIs: sun.misc.*, com.sun.*, internal packages
### Phase 1 — Dependency Upgrade
- Update Spring Boot parent to 3.3.x
- Replace javax.* with jakarta.* (use: sed -i 's/javax\./jakarta\./g')
- Update Hibernate to 6.x — @Entity annotation semantics changed
- Gate: mvn clean verify must pass before Phase 2
### Phase 2 — Configuration Migration
**Goal:** Migrate XML/property-file config to type-safe structured config.
**Steps:**
1. Identify all config sources (XML, .properties, environment variables)
2. Map to typed configuration classes
3. Replace with framework-native config (Spring Boot `@ConfigurationProperties`, .NET `IOptions<T>`)
4. Add validation annotations
5. Remove legacy config loading code
**Validation:** All tests pass with new config loading path.
📖 Source: Skills · cli-features — /skills — uid 5_251–5_253
2.5 — Hooks: Automated Guardrails 10 min¶
For enterprise migrations, you want automated gates — not just manual review. Hooks fire on CLI events and can block, warn, or log tool use before it happens.
Pre-Tool Hook: Block Writes Outside Migration Scope¶
Create .agents/hooks/scope-guard.sh:
#!/bin/bash
# AGY CLI hook event: PreToolUse
# Blocks writes to files outside the current migration module
TOOL_NAME="$1"
FILE_PATH="$2"
MIGRATION_MODULE="${MIGRATION_MODULE:-src/auth}" # Set before starting each phase
if [[ "$TOOL_NAME" == "write_file" || "$TOOL_NAME" == "edit" ]]; then
if [[ "$FILE_PATH" != *"$MIGRATION_MODULE"* ]]; then
echo "BLOCK: Write to $FILE_PATH is outside migration scope ($MIGRATION_MODULE)" >&2
exit 1 # Non-zero exit blocks the tool call
fi
fi
Register in settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "write_file|edit",
"command": ".agents/hooks/scope-guard.sh"
}
]
}
}
Post-Tool Hook: Auto-Run Tests After Every File Write¶
#!/bin/bash
# AGY CLI hook event: PostToolUse
# Runs tests automatically after every source file write
TOOL_NAME="$1"
FILE_PATH="$2"
if [[ "$TOOL_NAME" == "write_file" && "$FILE_PATH" == *".java" ]]; then
echo "Running test gate after $FILE_PATH was modified..."
mvn test -pl "$(dirname $FILE_PATH | sed 's|src/main/java||')" -q 2>&1
if [[ $? -ne 0 ]]; then
echo "⚠️ Tests failed after writing $FILE_PATH — consider /rewind"
fi
fi
📖 Source: Hooks
2.6 — /rewind and /fork: Your Safety Net 5 min¶
/rewind — Roll Back the Conversation¶
If the agent goes off-track, you don't need to start over. /rewind rolls back conversation history:
This opens a history picker. Select the turn to revert to. The agent's understanding of the codebase resets to that point — useful if it's accumulated incorrect assumptions during a long session.
📖 Source: cli-features — uid 5_220–5_226: "
/rewind(alias/undo) — roll back conversation history"
/fork — Explore Without Risk¶
Before attempting a risky migration step, fork the conversation:
This creates a parallel workspace. You can try the risky approach in the fork. If it works, great. If it doesn't, close the fork and continue from the main conversation — which never changed.
📖 Source: cli-using — uid 3_219–3_224: "
/forkto spin up a separate workspace"
/resume — Pick Up Long Migrations¶
Large migrations span multiple days. When you return:
This opens a session picker showing your previous migration sessions with timestamps and conversation names. Select the right one to continue exactly where you left off.
📖 Source: cli-features — uid 5_213–5_219
Rename sessions to keep migrations organized:
2.7 — Print Mode: Non-Interactive Migration Pipeline 5 min¶
For CI/CD gates or overnight migration runs, use print mode to pipe migration tasks without interaction:
# Dry-run: analyze and report issues — no writes
agy -p "Review the migration changes in the last commit. \
Check for: javax.* references that weren't updated, \
missing jakarta.* imports, and test files that weren't \
updated to match renamed packages. \
Output a structured report with file paths and line numbers."
# Chain: analyze → generate migration report → save
agy -p "Scan src/auth/ for javax.persistence.* usage" | \
agy -p "Convert this javax.persistence usage report into \
a step-by-step migration plan with exact sed commands" > migration-plan.md
📖 Source: cli-getting-started —
agy --help: "-p: Short alias for --print"
Hands-On Exercise¶
Exercise 8: Legacy Modernization¶
Files: ex08_dotnet_modernization.md · ex09_java_upgrade.md
Duration: 45 min
Objective: Walk through a full migration using the AGY primitives from this module.
Choose your track:
Track A: Plan-First (Strict → Investigate → Execute)¶
- Set
/permissionstostrict— lock all writes - Give the agent a full investigation mandate (Section 2.1)
- Use
ctrl+gto open the plan in your editor and add team constraints - Write an AGENTS.md encoding the migration rules (or have the agent write it)
- Add a
.agents/rules.mdwith hard non-negotiables - Switch to
request-review— begin Phase 1 with oversight - Use
/rewindif the agent drifts outside scope - Rename the session:
/rename "Migration — Phase 1 complete"
Track B: Subagent-First (Parallel Analysis → Context → Execute)¶
- Spawn three parallel subagents: security scan, dependency map, test coverage
- Monitor via
/agents— usectrl+jandctrl+kfor approvals - Aggregate their reports into an AGENTS.md (have the agent synthesize)
- Install the
java-migrationskill (Section 2.4) - Use
/forkbefore the riskiest step — try it there first - Use print mode to generate a post-phase report
Summary: AGY Primitives for Legacy Modernization¶
| Primitive | What It Does | When to Use |
|---|---|---|
/permissions strict | Hard read-only gate — no writes or commands | Investigation phase |
/permissions request-review | Agent asks before every write | Controlled execution |
ctrl+g | Open plan in $EDITOR for collaborative editing | Plan refinement |
| AGENTS.md | Persistent migration standards across sessions | Always — encode constraints |
.agents/rules.md | Hard system-prompt directives | Non-negotiable guardrails |
| Subagents | Parallel analysis teams | Multi-concern investigations |
/agents + ctrl+j + ctrl+k | Monitor and approve subagent work | During parallel runs |
| Hooks (PreToolUse) | Block writes outside migration scope | Automated guardrails |
| Hooks (PostToolUse) | Auto-run tests after every change | Test gate automation |
/rewind | Roll back conversation if agent drifts | Mid-session course correction |
/fork | Try risky steps in an isolated branch | Before high-risk changes |
/resume | Pick up multi-day migrations | Returning to a session |
/rename | Label sessions by phase | Session management |
agy -p | Non-interactive migration pipeline | CI gates, overnight runs |
| Skills | Reusable migration playbooks | Repeatable migration patterns |
Next Step¶
→ Continue to Module 3: Building AGY Agents with the SDK
→ Cheatsheet — all commands in one place