Debug Code with Antigravity CLI
Supervise Antigravity CLI as it repairs and verifies a Python task tracker.
Introduction
30 Second Summary
A coding assistant can sound certain while changing the wrong file. Visible evidence makes a fix trustworthy.
In this project, you will supervise Antigravity CLI as it repairs a broken Python task tracker. Failing tests expose the defect before you verify the repair yourself.
What You'll Build
Your final demo shows the repaired tracker reporting the correct completed count with its full test suite green.
By the end of this project, you'll have:
- A controlled defect you can reproduce as Completed: 1 before two failing tests reveal the status-handling gap.
- A review-first agent workflow that keeps the implementation plan, tool approvals, plus diff review under your control.
- An independently verified repair that passes four tests before reporting Total: 3, Completed: 2, plus Open: 1.
- Secret Mission: Add a blocked-status test before directing the agent to implement a Blocked: 1 summary.
Are there any prerequisites?
You need a personal Google account with Google AI Pro plus Antigravity access. You also need Google Chrome, Python 3, plus a Linux terminal.
Before We Start
This first checkpoint helps you commit to a controlled debugging lab where you supervise an AI agent through planning, reviewed actions, and independent verification.
Set Up the Antigravity Workspace
An AI agent can inspect local files or propose changes. A trusted folder with review-based permissions keeps that access visible before any project files change.
This setup confirms Python 3 in your Linux terminal. It also prepares Google Chrome to authenticate with your personal Google AI Pro account.
Then you will install Antigravity CLI version v1.5.1. You will start it inside an empty workspace with review controls active.
In this step, get ready to:
- Confirm the local prerequisites.
- Install Antigravity CLI version v1.5.1.
- Create a trusted workspace with review-based permissions.
Confirm Python and Chrome are ready
The task tracker uses the Python 3 standard library. Checking the interpreter now confirms that the later app commands have a working runtime.
- Check Python 3 in your Linux terminal by running this command:
python3 --version
What does this command check?
This command asks the installed Python 3 interpreter to print its version. A version in the output confirms that the interpreter is available from your terminal.
You will see a Python 3 version in the output. That is your first readiness check complete.
Python version missing?
Make sure you entered the command in your Linux terminal. Confirm that every character matches the command above.
Still blocked? Help me find the working Python 3 command on my Linux computer.
Antigravity uses browser authentication when it cannot find a saved session. Chrome needs access to the personal Google account that carries your Google AI Pro plan.
- Open your Linux desktop's application search.
- Type Google Chrome to find the browser.
- Press Enter to start Chrome.
- Open the Chrome profile control.
- Confirm that your personal Google account linked to Google AI Pro is selected.
- Complete sign-in if Chrome asks for it.
Your local prerequisites are now confirmed. Chrome is ready to handle the Antigravity sign-in flow.
Install Antigravity CLI
The CLI provides the planning interface plus the approval flow used throughout this lab. The project uses version v1.5.1 so the commands match the documented workflow.
- Check whether Antigravity CLI is already installed by running this command:
agy --version
What does this command check?
This check asks the installed CLI to identify its release. Use the output to choose the matching installation path below.
Find the outcome that matches your terminal.
✔️ I see v1.5.1
Your CLI already matches the project version. That removes one setup task from your path.
ⓧ I see an older version
Your existing CLI needs the current release used by this project.
- Install the current Linux release by running this command:
curl -fsSL https://antigravity.google/cli/install.sh | bash
What does this command do?
This official installer downloads the current Antigravity CLI release for Linux. A fresh terminal loads the command path created by the installer.
- Close the current terminal after the installer finishes.
- Start a fresh Linux terminal from your desktop's application search.
ⓧ Command not found
Antigravity CLI is not available from your terminal yet. The official Linux installer adds it.
- Install Antigravity CLI by running this command:
curl -fsSL https://antigravity.google/cli/install.sh | bash
What does this command do?
This official installer downloads the current Antigravity CLI release for Linux. A fresh terminal loads the command path created by the installer.
- Close the current terminal after the installer finishes.
- Start a fresh Linux terminal from your desktop's application search.
- Verify the available CLI version by running this command:
agy --version
What does this verification prove?
The command resolves the CLI from your current terminal session. Its output identifies the version that the rest of the lab uses.
You will see version v1.5.1 in the output. Your agent interface is now installed.
CLI version still unavailable?
Confirm that you opened a fresh terminal after the installer completed. A terminal left open during installation may not have the updated command path.
Need another pair of eyes? Help me troubleshoot my Antigravity CLI installation.
Create and trust the workspace
A workspace boundary limits which local folder Antigravity can inspect. Review settings then keep file edits plus terminal commands under your approval.
- Create the lab workspace inside your home folder by running this command:
mkdir -p "$HOME/agentic-debugging-lab" && cd "$HOME/agentic-debugging-lab"
What does this command do?
The first command creates the $HOME/agentic-debugging-lab folder if needed. The second command moves your terminal into that folder.
The workspace now exists without project files. Antigravity will treat this folder as the boundary for the debugging lab.
On its first launch, Antigravity may open your default browser if it finds no saved session. The terminal continues into the interactive interface after authentication.
- Launch Antigravity inside the workspace by running this command:
agy
What does this command do?
The launcher opens the Antigravity terminal interface in your current folder. That current folder becomes the workspace the agent can inspect.
- Complete browser authentication with your personal Google account if a sign-in page opens.
- Return to the terminal after authentication completes.
- Approve trust for $HOME/agentic-debugging-lab only when the workspace prompt appears.
You will see your signed-in account plus the interactive prompt. That confirms Antigravity is running inside the trusted lab workspace.
- Open the interactive settings editor by entering this command:
/config
Why configure review controls?
The settings editor controls when Antigravity must pause for your approval. Review-based defaults let you inspect proposed actions before they affect the workspace.
- Set Tool Permission to request-review.
- Set Artifact Review to asks-for-review.
The settings editor now shows both review policies. File operations plus terminal commands stay inside a supervised flow.
The final switch controls whether Antigravity can spend purchased AI credits after the baseline quota. Keeping it off means this lab stops at the included quota.
- Turn Use AI Credits off.
Your workspace now has the intended permission boundaries. You remain in control of edits plus command execution.
The settings persist after you leave the interface. Returning to the shell lets you verify the installed version before reopening the trusted workspace.
- Return to your host shell by entering this command:
/exit
What does this command do?
This command closes the Antigravity terminal interface. Your shell remains inside $HOME/agentic-debugging-lab.
Before you run the final checks, what version plus workspace do you expect to see? Your prediction is the benchmark for the next two commands.
- Confirm the installed version by running this command:
agy --version
What should this confirm?
The output confirms that your terminal resolves the installed Antigravity CLI release. It should identify version v1.5.1.
You will see version v1.5.1 in the terminal. The installation matches the project workflow.
- Reopen the trusted workspace by running this command:
agy
What should this confirm?
The launcher reads your current folder plus the saved authentication session. It opens the interactive prompt inside the trusted workspace.
You will see your signed-in account plus the interactive prompt for $HOME/agentic-debugging-lab. Your supervised agent workspace is ready.
Your trusted workspace is running with review controls active. Next, you will create the deliberately broken tracker that gives the agent an objective debugging target.
Run the Broken Task Tracker
Your trusted Antigravity CLI workspace is ready. A coding agent is easiest to judge when you capture a repeatable baseline before it touches the files.
In this step, you will build a small Python tracker with a plausible defect. A four-test suite will turn that defect into objective evidence.
In this step, get ready to:
- Create task data with mixed status formatting.
- Build the naive tracker plus its four-test suite.
- Run the tracker plus its tests to capture a baseline.
Create the task data
The tracker needs a small JSON dataset that produces predictable results. These three records give every later run the same input.
- Return to the Antigravity prompt from the previous step.
- Restore your host shell by entering:
/exit
What does this command do?
The /exit command closes the interactive Antigravity interface. Your Linux shell returns to the trusted $HOME/agentic-debugging-lab workspace.
- Start the text editor available on your Linux machine.
- Create tasks.json inside $HOME/agentic-debugging-lab using the editor's new-file action.
- Paste this data into tasks.json:
[
{"title": "Write report", "status": "done"},
{"title": "Review pull request", "status": "Done"},
{"title": "Plan sprint", "status": "todo"}
]
What does this data represent?
- The first task uses the lowercase status done.
- The second task uses the title-cased status Done.
- The third task uses the open status todo.
- Save tasks.json.
- Count the top-level task objects in your editor.
You should see three task objects. Each object should contain a title plus a status.
Does the JSON look different?
Check that the file begins with [ and ends with ]. Confirm that a comma separates each task object.
Still stuck? Help me compare my tasks.json file with a valid three-task JSON array.
Build the naive tracker and tests
The implementation loads the saved tasks. It calculates a summary before printing three totals.
- Create task_tracker.py inside $HOME/agentic-debugging-lab using your editor's new-file action.
- Paste this implementation into task_tracker.py:
import json
def task_summary(tasks):
total = len(tasks)
completed = sum(task.get("status") == "done" for task in tasks)
return {
"total": total,
"completed": completed,
"open": total - completed,
}
def load_tasks(path):
with open(path, encoding="utf-8") as task_file:
return json.load(task_file)
def main():
summary = task_summary(load_tasks("tasks.json"))
print("Total:", summary["total"])
print("Completed:", summary["completed"])
print("Open:", summary["open"])
if __name__ == "__main__":
main()
What does this code do?
- The task_summary() function counts all tasks. It calculates completed tasks through a direct status comparison.
- The load_tasks() function reads the records from tasks.json.
- The main() function prints the total count. It also prints the completed count plus the open count.
- Save task_tracker.py.
- Confirm that your editor lists task_tracker.py beside tasks.json.
Does the tracker file show an error?
Check the indentation inside each function. Confirm that every opening bracket has a matching closing bracket.
Need another pair of eyes? Help me find a syntax or indentation difference in task_tracker.py.
The first two unit tests describe how completed statuses should behave. They give the tracker explicit targets for capitalization plus surrounding whitespace.
- Create test_task_tracker.py inside $HOME/agentic-debugging-lab using your editor's new-file action.
- Paste the first two tests into test_task_tracker.py:
import unittest
from task_tracker import task_summary
class TaskSummaryTests(unittest.TestCase):
def test_counts_mixed_case_statuses(self):
summary = task_summary([
{"status": "done"},
{"status": "Done"},
{"status": "todo"},
])
self.assertEqual(summary["completed"], 2)
self.assertEqual(summary["open"], 1)
def test_trims_status_whitespace(self):
summary = task_summary([{"status": " done "}])
self.assertEqual(summary["completed"], 1)
What do these tests protect?
- The test_counts_mixed_case_statuses() method expects done plus Done to count as completed.
- The test_trims_status_whitespace() method expects spaces around done to be ignored.
- Save test_task_tracker.py.
- Confirm that your editor lists test_task_tracker.py beside the other two files.
Are the first tests misaligned?
Keep both test methods indented inside TaskSummaryTests. Keep each assertion indented inside its test method.
Need help checking the structure? Help me inspect the indentation in my first two unit tests.
Two defensive tests complete the suite. They define safe behavior when a task has no status or stores a non-string value.
- Place your cursor on the blank line after self.assertEqual(summary["completed"], 1) in test_task_tracker.py.
- Paste the remaining tests plus the test runner below that line:
def test_missing_status_is_open(self):
summary = task_summary([{"title": "Unclassified"}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
def test_non_string_status_is_open(self):
summary = task_summary([{"status": None}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
if __name__ == "__main__":
unittest.main()
What do the final tests protect?
- The test_missing_status_is_open() method expects a task without a status to remain open.
- The test_non_string_status_is_open() method expects a None status to remain open.
- The final guard starts the test runner when the file runs directly.
- Save test_task_tracker.py.
- Confirm that the file contains four methods whose names begin with test_.
Do you see fewer than four tests?
Check that the two new methods sit inside TaskSummaryTests. Confirm that the final if block starts at the left edge.
Still unsure? Help me verify that test_task_tracker.py contains four discoverable tests.
Run the baseline checks
A program can run successfully while returning an incorrect answer. The app output gives you the first piece of evidence.
Before you run the tracker, how many completed tasks do you think its direct status comparison will count?
- Run the tracker from $HOME/agentic-debugging-lab using this command:
python3 task_tracker.py
What should you see?
The tracker prints Total: 3. It also prints Completed: 1 plus Open: 2.
The completed count falls short because the direct comparison matches lowercase done only. The title-cased Done value is excluded.
🙋♀️ Does the tracker fail to run?
Confirm that your terminal is inside $HOME/agentic-debugging-lab. Check that all three files are saved in that folder.
If Python reports a syntax problem, compare the referenced line with the code above. Help me diagnose why task_tracker.py does not run.
The test suite checks the observed result against four explicit requirements. Two edge cases already work with the naive implementation.
Before you run the suite, which tests do you expect the direct comparison to satisfy?
- Run all four tests from $HOME/agentic-debugging-lab using this command:
python3 -m unittest -v test_task_tracker
What should you see?
The test_missing_status_is_open test passes. The test_non_string_status_is_open test also passes.
The test_counts_mixed_case_statuses test fails. The test_trims_status_whitespace test fails too.
The suite summary reports two passing tests plus two failures. That split isolates case handling plus whitespace handling as measurable gaps.
You now have a dependable baseline. Every future agent claim can be checked against these same four tests.
Does the suite show a different result?
Confirm that the terminal command names test_task_tracker without the .py extension. Compare each assertion with the saved test code.
If the number of discovered tests is below four, inspect the indentation plus every test_ method name. Help me understand why my unittest result differs from the expected baseline.
✔️ Awesome, I've got everything!
Your three files are saved. The tracker prints one completed task while the four-test suite reports two passing tests plus two failures.
ⓧ I'd like to double check the full code
Compare your tasks.json with this complete reference.
[
{"title": "Write report", "status": "done"},
{"title": "Review pull request", "status": "Done"},
{"title": "Plan sprint", "status": "todo"}
]
What should this file contain?
This reference contains exactly three task objects. Their status values are done, Done, plus todo.
Compare your task_tracker.py with this complete reference.
import json
def task_summary(tasks):
total = len(tasks)
completed = sum(task.get("status") == "done" for task in tasks)
return {
"total": total,
"completed": completed,
"open": total - completed,
}
def load_tasks(path):
with open(path, encoding="utf-8") as task_file:
return json.load(task_file)
def main():
summary = task_summary(load_tasks("tasks.json"))
print("Total:", summary["total"])
print("Completed:", summary["completed"])
print("Open:", summary["open"])
if __name__ == "__main__":
main()
What should this file contain?
This reference defines task_summary(), load_tasks(), plus main(). Its direct comparison preserves the intended defect.
Compare your test_task_tracker.py with this complete reference.
import unittest
from task_tracker import task_summary
class TaskSummaryTests(unittest.TestCase):
def test_counts_mixed_case_statuses(self):
summary = task_summary([
{"status": "done"},
{"status": "Done"},
{"status": "todo"},
])
self.assertEqual(summary["completed"], 2)
self.assertEqual(summary["open"], 1)
def test_trims_status_whitespace(self):
summary = task_summary([{"status": " done "}])
self.assertEqual(summary["completed"], 1)
def test_missing_status_is_open(self):
summary = task_summary([{"title": "Unclassified"}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
def test_non_string_status_is_open(self):
summary = task_summary([{"status": None}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
if __name__ == "__main__":
unittest.main()
What should this file contain?
This reference contains four test methods. Two expose the current defect while two protect already-correct behavior.
Your controlled defect now has visible output plus objective tests. Next, you will ask Antigravity to investigate the evidence before it edits anything.
Review the Agent's Implementation Plan
The task tracker now shows a wrong completion count. Its test suite also exposes the defect with two failures.
Antigravity CLI uses plan mode to separate investigation from implementation. A review at this point exposes the agent's assumptions while every project file remains unchanged.
In this step, get ready to:
- Reconfirm the review guardrails from your workspace setup.
- Ask Antigravity to inspect the existing project in plan mode.
- Review the implementation plan before allowing any file edits.
Confirm the review guardrails
Review-based tool permissions keep you in control of every proposed action. The settings from earlier must continue protecting this planning turn.
- Switch back to the Linux terminal from earlier.
- Return to the trusted $HOME/agentic-debugging-lab workspace by running this command:
cd "$HOME/agentic-debugging-lab"
What does this command do?
This returns your terminal to the isolated workspace that contains the broken tracker. Antigravity treats this folder as the context for the planning turn.
- Launch the interactive Antigravity terminal interface by running this command:
agy
What happens here?
Antigravity CLI starts inside the current workspace. The interactive prompt gives you access to planning commands without leaving the terminal.
- Open the settings editor by entering this command at the Antigravity prompt:
/config
Why check the settings again?
The settings editor confirms that Antigravity still requires your review before sensitive tool actions. This prevents the planning turn from silently becoming an implementation turn.
- Confirm Tool Permission shows request-review.
- Confirm Artifact Review shows asks-for-review.
- Confirm Use AI Credits remains off.
- Return to the interactive prompt after confirming the settings.
You remain in control of every read request, terminal command, and proposed edit.
Request a plan without edits
A bounded planning instruction tells the agent what evidence to inspect. It also defines which files must remain untouched.
- Request the investigation by pasting this instruction into the Antigravity prompt:
/plan Inspect task_tracker.py, test_task_tracker.py, and tasks.json. Run the tests to identify the root causes. Do not edit any files. Produce a minimal implementation plan that keeps test_task_tracker.py unchanged.
How does this prompt constrain the agent?
- The /plan command keeps the turn focused on investigation.
- The three named files bound the agent's inspection scope.
- The no-edit instruction preserves the current project state.
- The test-file constraint protects the objective success criteria.
- Review each proposed file-read request individually.
- Approve each read request after confirming that it targets one of the three named project files.
- Compare the proposed test command with this expected command before approving it:
python3 -m unittest -v test_task_tracker
What does this command prove?
This reruns the existing four-test suite against the unchanged implementation. The failures give the agent direct evidence of the two normalization gaps.
Before you approve the test command, do you expect the result to match the failures you observed earlier?
- Approve the proposed test command.
You'll see two passing tests plus two failures. The mixed-case test fails alongside the whitespace test.
- Reject any proposed file edit during this planning turn.
- Wait for Antigravity to finish drafting the plan.
Agent proposing an edit?
- Reject the proposed edit.
- Resubmit the same planning instruction if the turn stops without producing an artifact.
Still unsure about a proposed action? Help me keep Antigravity in planning mode.
Audit the implementation artifact
An implementation plan is the contract for the next turn. Its scope should connect each failing behavior to one minimal implementation change.
Before you open the artifact, do you expect the plan to preserve every existing project file?
- Open the Artifact Review panel by entering this command:
/artifact
What is the Artifact Review panel?
The Artifact Review panel displays the agent's proposed implementation plan before you permit code changes. It gives you a concrete scope to accept or challenge.
- Confirm the plan proposes a helper named normalize_status(task).
- Confirm the plan handles missing statuses with task.get("status", "").
- Confirm the plan protects non-string values with isinstance(status, str).
- Confirm the plan trims status whitespace with strip().
- Confirm the plan normalizes status casing with casefold().
- Confirm the plan uses the helper inside task_summary(tasks).
- Confirm the plan preserves test_task_tracker.py.
- Confirm the final plan step reruns the existing four-test suite.
That is the key judgement call handled. The agent now has a bounded repair plan backed by the same failing tests you observed.
The planning turn leaves all three project files unchanged.
✔️ Awesome, I've got everything!
Great. Your reviewed plan exists while tasks.json, task_tracker.py, and test_task_tracker.py remain unchanged.
ⓧ I'd like to double check the full code
Compare each project file with these unchanged versions.
Your tasks.json file should still contain these three tasks.
[
{"title": "Write report", "status": "done"},
{"title": "Review pull request", "status": "Done"},
{"title": "Plan sprint", "status": "todo"}
]
Why is this file unchanged?
The title-cased completed status remains in the data because it represents a valid input the implementation must handle.
Your task_tracker.py file should still contain the deliberately naive comparison.
import json
def task_summary(tasks):
total = len(tasks)
completed = sum(task.get("status") == "done" for task in tasks)
return {
"total": total,
"completed": completed,
"open": total - completed,
}
def load_tasks(path):
with open(path, encoding="utf-8") as task_file:
return json.load(task_file)
def main():
summary = task_summary(load_tasks("tasks.json"))
print("Total:", summary["total"])
print("Completed:", summary["completed"])
print("Open:", summary["open"])
if __name__ == "__main__":
main()
Why is the defect still present?
This step reviews the proposed repair before implementation begins. The direct status comparison stays in place until you approve the next turn.
Your test_task_tracker.py file should still contain the four original tests.
import unittest
from task_tracker import task_summary
class TaskSummaryTests(unittest.TestCase):
def test_counts_mixed_case_statuses(self):
summary = task_summary([
{"status": "done"},
{"status": "Done"},
{"status": "todo"},
])
self.assertEqual(summary["completed"], 2)
self.assertEqual(summary["open"], 1)
def test_trims_status_whitespace(self):
summary = task_summary([{"status": " done "}])
self.assertEqual(summary["completed"], 1)
def test_missing_status_is_open(self):
summary = task_summary([{"title": "Unclassified"}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
def test_non_string_status_is_open(self):
summary = task_summary([{"status": None}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
if __name__ == "__main__":
unittest.main()
Why preserve the tests?
These tests define the behavior the implementation must satisfy. Keeping them unchanged prevents the agent from manufacturing a passing result by weakening the checks.
Your implementation plan is scoped to the observed defect while the evidence remains intact. Next, you can let the agent apply that plan under the same review controls.
Approve the Fix and Verify Tests
Your reviewed Antigravity CLI plan has exposed the exact scope of the repair. The failing tests now define the result that the agent must reach.
This step turns that plan into a controlled implementation. Every proposed action stays behind review. The test suite gives you a measurable result.
In this step, get ready to:
- Submit the bounded implementation instruction.
- Approve only the planned task_tracker.py change.
- Confirm the four-test suite passes independently.
Submit the approved implementation request
A bounded implementation request turns the reviewed plan into clear constraints. It also gives the agent an objective stopping point.
- Return to the Antigravity prompt from the Artifact Review panel.
- Paste this implementation instruction into the prompt:
Implement the approved plan. Do not modify test_task_tracker.py or tasks.json. Run python3 -m unittest -v test_task_tracker and continue until all four tests pass.
Why This Request Stays Bounded
- The approved plan defines the implementation change.
- The instruction protects test_task_tracker.py from edits.
- The instruction protects tasks.json from edits.
- The test command defines the success condition.
- Press Enter to submit the instruction.
Review each proposed action
Approving an agent edit can feel risky. Your current review settings keep every proposed change visible.
Your Approval Boundary
The proposed task_tracker.py diff should add normalize_status(task). The helper reads the status with task.get("status", "").
A non-string status should return "". A string status should return status.strip().casefold().
The completion count should use normalize_status(task) == "done". The open value should remain total - completed.
- Inspect the file path in each proposed edit.
- Compare the proposed task_tracker.py change with the approved behavior above.
- Approve the minimal task_tracker.py edit.
- Reject any proposed edit to test_task_tracker.py.
- Reject any proposed edit to tasks.json.
- Approve the proposed test command.
The Antigravity test run should show each of the four named tests ending in ok. The suite should finish with OK.
That is the bounded repair working. Antigravity has reached the objective defined by the unchanged tests.
Tests Still Failing?
- Confirm the approved helper checks isinstance(status, str) before calling string methods.
- Confirm task_summary(tasks) calls normalize_status(task) when counting completed tasks.
- Confirm the protected test file still matches its original contents.
Still stuck? Help me compare the approved status-normalization plan with my failing tests.
Verify the result independently
The agent's test run proves what happened inside its supervised session. An independent run confirms the same project files work from your host shell.
Agent Stopped Before Testing?
- Ask Antigravity to run the test command from your implementation request.
- Approve the test command when it appears for review.
Need a hand? Help me prompt Antigravity to run the approved test suite.
- Return to the host shell by entering this command:
/exit
What Does This Command Do?
The /exit command closes the Antigravity interface. It restores the Linux shell where you launched the agent.
Before you run the suite, consider whether the host shell will match Antigravity's result.
- Run the unchanged four-test suite independently with this command:
python3 -m unittest -v test_task_tracker
What Does This Command Check?
- The python3 -m unittest portion runs Python's standard test runner.
- The -v flag displays each test by name.
- The test_task_tracker value selects your tracker test module.
You should see all four tests report ok. The independent suite ends with OK.
You now have independent evidence that the repair works. The result comes from the project files themselves.
Independent Test Run Failing?
- Confirm your shell is still inside $HOME/agentic-debugging-lab.
- Confirm task_tracker.py contains the approved helper.
- Confirm test_task_tracker.py still contains the original four tests.
Still seeing a failure? Help me diagnose why the tests pass in Antigravity but fail in my Linux shell.
✔️ Awesome, I've got everything!
Your independent test run ends with OK. Your protected test data remains unchanged.
ⓧ I'd like to double check the full code
The complete task_tracker.py should match this reference.
import json
def normalize_status(task):
status = task.get("status", "")
if not isinstance(status, str):
return ""
return status.strip().casefold()
def task_summary(tasks):
total = len(tasks)
completed = sum(normalize_status(task) == "done" for task in tasks)
return {
"total": total,
"completed": completed,
"open": total - completed,
}
def load_tasks(path):
with open(path, encoding="utf-8") as task_file:
return json.load(task_file)
def main():
summary = task_summary(load_tasks("tasks.json"))
print("Total:", summary["total"])
print("Completed:", summary["completed"])
print("Open:", summary["open"])
if __name__ == "__main__":
main()
What Should This File Contain?
The helper converts string statuses into a trimmed casefolded value. It safely maps missing statuses to an empty string.
The summary uses that normalized value for completed tasks. The loading and printing behavior remains unchanged.
The complete tasks.json should still match this reference.
[
{"title": "Write report", "status": "done"},
{"title": "Review pull request", "status": "Done"},
{"title": "Plan sprint", "status": "todo"}
]
What Should This Data Preserve?
This JSON input keeps the original three tasks. Its mixed letter case continues to exercise the repaired normalization logic.
The complete test_task_tracker.py should still match this reference.
import unittest
from task_tracker import task_summary
class TaskSummaryTests(unittest.TestCase):
def test_counts_mixed_case_statuses(self):
summary = task_summary([
{"status": "done"},
{"status": "Done"},
{"status": "todo"},
])
self.assertEqual(summary["completed"], 2)
self.assertEqual(summary["open"], 1)
def test_trims_status_whitespace(self):
summary = task_summary([{"status": " done "}])
self.assertEqual(summary["completed"], 1)
def test_missing_status_is_open(self):
summary = task_summary([{"title": "Unclassified"}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
def test_non_string_status_is_open(self):
summary = task_summary([{"status": None}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
if __name__ == "__main__":
unittest.main()
What Should These Tests Protect?
- The first test checks mixed letter case.
- The second test checks surrounding whitespace.
- The third test checks a missing status.
- The fourth test checks a non-string status.
The repair now has two layers of evidence from the same unchanged tests. Next up, you will audit the agent's diff against the behavior you just verified.
Audit the Evidence
Your four tests now pass after the agent's minimal repair.
Passing tests are strong evidence. A human audit still checks for unnecessary edits or weakened tests.
You will inspect the implementation evidence in Antigravity CLI. You will then verify the repaired tracker from the Linux terminal.
In this step, get ready to:
- Review the implementation diff for scoped changes.
- Compare the agent's explanation with the changed code.
- Complete independent verification outside the agent.
Review the implementation diff
A diff isolates the lines added or removed during an implementation turn. This gives you direct evidence of the agent's scope.
- Return to the Antigravity CLI prompt from earlier.
- Open the interactive diff viewer by entering:
/diff
What does this command open?
- The /diff command opens Antigravity's interactive diff viewer.
- The viewer separates added lines from removed lines.
- The implementation turn should contain changes only in task_tracker.py.
- Select the turn that implemented the repair.
- Inspect the added normalize_status(task) helper in task_tracker.py.
- Inspect the changed completed calculation in task_summary(tasks).
- Confirm tasks.json has no changes.
- Confirm test_task_tracker.py has no changes.
You should see a small implementation change in task_tracker.py. The data file and test suite remain untouched.
Diff viewer did not open?
- Check that you entered /diff in Antigravity's interactive prompt.
- Switch back to the trusted workspace session from earlier if your Linux shell handled the text.
Still stuck? Help me open and inspect the Antigravity diff for my implementation turn.
Challenge the agent's explanation
An agent's explanation is a claim about the implementation. Each claim should point to a specific line in the diff.
- Ask Antigravity to explain the original normalization defect.
- Ask how the new type check prevents a method error.
- Compare its case-handling explanation with status.strip().casefold().
- Compare its whitespace explanation with strip().
- Compare its non-string explanation with isinstance(status, str).
- Confirm missing statuses fall back to an empty string through task.get("status", "").
How does the evidence connect?
- The empty-string fallback keeps a missing status in the open count.
- The type check stops string methods from running on values such as None.
- The strip() call removes surrounding whitespace.
- The casefold() call supports case-insensitive matching.
Verify outside the agent
Independent verification separates the agent's report from the result produced by your own shell. This closes the loop with evidence you generated yourself.
- Return to the host shell with this command if Antigravity is still on screen:
/exit
What does this command do?
The /exit command closes the Antigravity interface. Your original host shell returns inside the trusted workspace.
Before you run the suite, do you expect your terminal to confirm the same result reported by the agent?
- Run the four tests independently with this command:
python3 -m unittest -v test_task_tracker
How does this check work?
The command runs the test_task_tracker test module with verbose output. Each named test reports its own result.
You should see all four named tests report ok. The suite ends with OK.
Tests do not end with OK?
- Confirm your shell is inside $HOME/agentic-debugging-lab.
- Confirm test_task_tracker.py still contains the four original tests.
- Compare task_tracker.py with the audited file below.
Need another pair of eyes? Help me diagnose why my four task tracker tests do not pass.
Before you run the tracker, what completion count should the mixed-case data produce?
- Run the repaired tracker independently with this command:
python3 task_tracker.py
What does this check prove?
The command loads the three records from tasks.json. It sends those records through the repaired summary logic.
You should see Total: 3, Completed: 2, and Open: 1.
Tracker still reports one completed task?
- Confirm task_summary(tasks) calls normalize_status(task).
- Confirm normalize_status(task) returns status.strip().casefold() for string values.
- Confirm tasks.json still contains one done status and one Done status.
Still seeing the wrong count? Help me compare my tracker implementation with the expected summary logic.
Strong work. Your evidence now covers the edit scope, the independent tests, and the real tracker output.
✔️ Awesome, I've got everything!
Great. Your audited files remain scoped to the intended repair.
ⓧ I'd like to double check the full code
- Compare your final task_tracker.py with this audited version.
import json
def normalize_status(task):
status = task.get("status", "")
if not isinstance(status, str):
return ""
return status.strip().casefold()
def task_summary(tasks):
total = len(tasks)
completed = sum(normalize_status(task) == "done" for task in tasks)
return {
"total": total,
"completed": completed,
"open": total - completed,
}
def load_tasks(path):
with open(path, encoding="utf-8") as task_file:
return json.load(task_file)
def main():
summary = task_summary(load_tasks("tasks.json"))
print("Total:", summary["total"])
print("Completed:", summary["completed"])
print("Open:", summary["open"])
if __name__ == "__main__":
main()
Why this file matters
The normalize_status(task) helper safely normalizes string statuses. The summary uses that normalized value to count completed tasks.
- Compare your unchanged tasks.json with this data.
[
{"title": "Write report", "status": "done"},
{"title": "Review pull request", "status": "Done"},
{"title": "Plan sprint", "status": "todo"}
]
Why this data matters
This JSON data preserves the mixed-case input that exposed the original defect. Two records should count as completed after normalization.
- Compare your unchanged test_task_tracker.py with this test suite.
import unittest
from task_tracker import task_summary
class TaskSummaryTests(unittest.TestCase):
def test_counts_mixed_case_statuses(self):
summary = task_summary([
{"status": "done"},
{"status": "Done"},
{"status": "todo"},
])
self.assertEqual(summary["completed"], 2)
self.assertEqual(summary["open"], 1)
def test_trims_status_whitespace(self):
summary = task_summary([{"status": " done "}])
self.assertEqual(summary["completed"], 1)
def test_missing_status_is_open(self):
summary = task_summary([{"title": "Unclassified"}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
def test_non_string_status_is_open(self):
summary = task_summary([{"status": None}])
self.assertEqual(summary["completed"], 0)
self.assertEqual(summary["open"], 1)
if __name__ == "__main__":
unittest.main()
Why this suite matters
The four tests preserve the objective success criteria. They cover mixed case, surrounding whitespace, missing statuses, and non-string statuses.
Secret mission
Add a Blocked Count Test First
Your repaired tracker counts completed work, but blocked work is still invisible. Define the missing behavior with a failing test, supervise the smallest implementation change, then prove the result with an audited diff and independent commands.
Clean Up Your Resources
Clean Up Your Resources
The lab files live only in your local $HOME/agentic-debugging-lab folder. No cloud resources were created.
With Use AI Credits off, future Antigravity CLI sessions stay within the included quota. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- The trusted workspace at $HOME/agentic-debugging-lab containing your task tracker files.
Keep everything running
No action is needed while you continue using the lab. Your reviewed files remain available for another agent workflow.
- Keep the $HOME/agentic-debugging-lab folder intact for future test runs.
- Keep Use AI Credits off to prevent paid overages during future sessions.
Pause - I'll come back to this later
Pausing ends the current interactive session. Your trusted workspace remains ready for your next debugging run.
- Enter /exit at the Antigravity prompt if the interactive session is still open.
- Close the terminal window after the host shell returns.
- Leave the $HOME/agentic-debugging-lab folder in place.
Delete - I don't want to use this again
Deleting the lab can feel final, so this option targets only the project folder. Your installed system tools remain available for other projects.
- Copy any evidence you want to keep to a location outside $HOME/agentic-debugging-lab.
- Enter /exit at the Antigravity prompt if the interactive session is still open.
- Remove the local lab folder by running these commands:
cd "$HOME"
rm -rf "$HOME/agentic-debugging-lab"
What do these commands remove?
The first command moves your shell outside the lab folder. The second command removes the lab folder plus its contents.
The exact quoted path keeps the deletion scoped to $HOME/agentic-debugging-lab.
🙋♀️ Lab folder still present?
- Check that the command uses the exact $HOME/agentic-debugging-lab path shown above.
- Review any permission message printed by the terminal before trying the command again.
Help me safely diagnose why the lab folder was not deleted.
Nice Work!
Nice Work!
You did it! You built a reproducible Python debugging lab around a controlled defect. Objective tests now prove the repaired tracker works.
You've learned how to:
- Build a controlled Python debugging fixture around a plausible wrong result. Use four objective tests to expose the status normalization defect.
- Use Antigravity CLI to review an Implementation Plan before edits. Keep every tool action behind individual approval.
- Repair status handling with a reusable normalization helper. Audit the implementation through /diff. Perform independent verification outside the agent to confirm all four original tests pass.
- Secret Mission: Add a blocked-status test before implementation. Extend the tracker to report Blocked: 1 while blocked tasks remain open.
Ready to quiz yourself?