Repository navigation
Working With ChatGPT
This document describes an agile process I use to interact with ChatGPT to build software.
You must have a very clear written description of your software application requirements.
ChatGPT struggles when writing software to implement large or complex requirements. The more granular the requirements, the more efficient ChatGPT is in delivering working software. Therefore, prior to jumping into implementation of large and complex requirements, I invest as much time as necessary to decompose the requirements.
Once I provide a clear written description of my software application requirements, ChatGPT does an excellent job decomposing them into implementable chunks; we call both the large requirements and their smaller pieces Bites. I've collaborated with ChatGPT to decompose large requirements down to three levels.
I plan to work with ChatGPT to rename Bites to Epics / Stories / Bites.
When the requirement is part of a large requirement that you have already collaborated with ChatGPT to decompose into smaller requirements, ChatGPT has the smaller requirement details in memory, and a simple reference to it is sufficient when requesting ChatGPT for its implementation.
Below is an example of such a decomposition:
Bite 33 — Production Data Protection and Recovery Hardening Template for a ChatGPT patch submission:
- √ Bite 33.1 — Production Environment and Destructive-Operation Guardrails
- Bite 33.2 — Backup Creation, Retention, and Verification
- Bite 33.3 — Off-Host Backup Protection
- Bite 33.4 — Restore Tooling and Recovery Verification
- Bite 33.5 — Migration / Deployment Recovery Gate
- Bite 33.6 — Recovery Rehearsal and Operational Runbook
Prior to asking ChatGPT to implement the software for Bite 33, I asked it to consider decomposing it into smaller chunks. ChatGPT provided me a list; we iterated on ChatGPT's recommendations and reached the breakdown shown above.
A very important practice is to READ EVERYTHING that ChatGPT writes in its iterations with you very carefully, even though ChatGPT is wordy; invariably, I find that ChatGPT makes assumptions not aligned with mine, leading to iterations between me and ChatGPT that reach solutions that meet my expectations and are technically sound.
I use four terminals:
Mostly, I run the backend on this terminal; when the backend is not running, I use it to run database validation scripts;
Mostly, I run the frontend on this terminal; when the frontend is not running, I use it to run frontend validation scripts;
Its main purpose is to run git and local application validation; occasionally I use it for general commands;
Its main purpose is to SSH into the servers
I use the following Browser Tabs, where I:
- Local ERS - Run the app in my local development environment; I keep this on split screen, separate from all others;
- Wiki - Document the app and show the manual tests while I run them on the Local ERS tab;
- Code - Where I manage the branches;
- Issues - Where I manage the issues;
- Pull Requests - Where I manage the app pull requests;
- Actions - Where I monitor the app branch integration and deployment scripts;
- ChatGPT - Where I interact with ChatGPT
- Others as necessary
I use the Sublime Text editor, with the following tabs:
- Branch Details.txt
- Request.txt
- Defect.txt
- Use Case.txt
- Test Error.txt
- Credentials-<>.txt
- Work.txt
The general format to request ChatGPT to provide software to address a requirement is:
Header: <<request description>>
Branch: <<branch name>>
SHA: <<SHA, from gitzip output>>
ZIP: attached
Where:
- Header: Describes the type of request and identifies the target sub-bite;
-
Branch: Copy the
branch namefrom thegitzipcommand output; -
SHA: Copy the
branch SHAfrom thegitzipcommand output; - ZIP: attached
Where I keep the details of the branch I'm working on
- Bite: The name of the main bite I'm working on;
- Issue: The number of the sub-issue I'm working on;
- Sub-bite: The name of the sub-bite I'm working on;
- Sub-Issue: The number of the sub-issue I'm working on;
Request the software to implement a new sub-issue, or the manual tests to validate a sub-issue. The requests are formatted as follows:
- New Feature Template: Please provide the software to implement and test "<>."
- Manual Test Request Template: Please provide the manual tests written in very specific language and steps, in an .md file, to validate <>
Record errors found while executing manual tests or using the application, and ask ChatGPT to provide the software to fix them; note that I do not create issues for these defects unless ChatGPT chooses to postpone them. The request is formatted as follows:
- **Header**: Please provide the software changes to address the following defect while testing in my Local environment;
- **Branch**: Copy the `branch name` from the `gitzip` command output;
- **SHA**: Copy the `branch SHA` from the `gitzip` command output;
- **ZIP**: attached
- Description:
- Steps to Reproduce:
- Observed Behavior:
- Expected Behavior:
Record missing functionality found while executing manual tests or using the application, and ask ChatGPT to provide the software to implement it; note that I do not create issues for these use cases unless ChatGPT chooses to postpone it. The request is formatted as follows:
- **Header**: Please provide the software changes to address the following USE CASE:
- **Branch**: Copy the `branch name` from the `gitzip` command output;
- **SHA**: Copy the `branch SHA` from the `gitzip` command output;
- **ZIP**: attached
- Use Case: I, as <<my role>>, when <<where you want the behavior>>, want <<the behavior>>
Record test errors, observed locally or by GitHub during CI/CD, and ask ChatGPT to provide the software to fix them; note that I do not create issues for these test errors unless ChatGPT chooses to postpone it. The request is formatted as follows:
- Simple Scripts: ChatGPT asks me to run immediately after installing the patch;
-
The
makelocalscript: that runs all automated tests locally; - CI/CD: errors while integrating and deploying branches;
Error testing in the local environment
Header: <<request description>>
Branch: <<branch name>>
SHA: <<SHA, from gitzip output>>
ZIP: attached
<<paste the script and its output here>>
I run this script before requesting the manual tests to validate the patch.
Error testing in the local environment
Header: <<request description>>
Branch: <<branch name>>
SHA: <<SHA, from gitzip output>>
ZIP: attached
Error log: Attached
The Error log is produced by the makelocal script.
Anytime a deployment fails, I copy the error details from the repository's Actions tag and paste it here.
Error deploying to <<target branch name>>
Header: <<request description>>
Branch: <<branch name>>
SHA: <<SHA, from gitzip output>>
ZIP: attached
<<paste the error details from the repository's Actions tag here>>
I use this tab to record the users' credentials required for manual tests. This comes in handy during test execution.
Test Identities
Email / Login Password Tenant memberships NAME
--------------------------------- ----------------- -------------------- ------------------
manual30g.identity-m@example.test Demo-31.4-Brasil! MANUAL30G_MANUAL30G Marina MixedSettlement
I use it to capture free-form text
Use Case
Test Error
Record test errors, locally or with GitHub during CI/CD, and ask ChatGPT to provide the software to fix them; note that I do not create issues for these test errors unless ChatGPT chooses to postpone it. The request is formatted as follows: Local Test I run the makelocal script on Terminal 3, which runs the go test, vitest, and playwrite/e2e tests and logs the results to the /tmp/ers-local-check.log file. In this case, I attach the ZIP and LOG files to the ChatGPT request
Error testing in the local environment
Branch: <<branch name>>
SHA: <<branch SHA>>
ZIP: Attached
Error log: Attached
CI/CD Test At the moment, I do not capture the CI/CD test errors in any file; instead, I copy the error from the GitHub Actions output and paste it below the Branch description section:
Error running CI or CD:
Branch: <<branch name>>
SHA: <<branch SHA>>
ZIP: Attached
<<paste error here>>
Credentials Bite <>
ChatGPT includes a description of the credentials required to run the manual tests for each sub-issue. I capture these credentials to facilitate login in the various users required to validate the sub-issue.
Email / Login Password
-------------------------------- ------------------------
manual30g.identity-a@example.test Manual-30C-Password!
manual30g.identity-b@example.test Manual-30C-Password!
I might add more information if necessary. I also use a utility to preserve credentials, Lastpass, which accelerates login in new users.
Work
This is a catch all tab, used to record information I think I might need later.
This is the macOS file management tool, which I rely on to keep a window with two tabs:
- ~/Downloads - so I can drag the zip file I just created to my ChatGPT request
- /tmp - so I can drag the LOG file I just created to my ChatGPT request
I periodically move all the ~/Downloads files to the trash.
Once ChatGPT and I agree on the breakdown to implement a slice of logic, I use the Github Issue / New to add an Issue capturing the Main Issue, ChatGPT calls it the Main Bite:
-
Header: The name of the major requirements, e.g, "Bite 33 — Production Data Protection and Recovery HardeningTemplate".
- Note that I prefix the Main Bite's Issue Header with the Bite number;
- In the ERS case, ChatGPT came up with around 20 Main Bites, and then we added Main Bites as we discovered requirements implementing the original Main Bites.
-
Description: The list of all sub-bites to be implemented at the top, and all the details ChatGPT provided about their breakdown.
- Note that I prefix the sub-bites names with their bite numbers, as for instance Bite 33.1 — Production Environment and Destructive-Operation Guardrails
I capture all the pertinent ChatGPT comments linked the the requirements and its sub-requirements below the sub-issues list
Next, I implement one sub-bite at the time, from top to bottom, marking its predecessor as completed, as shown above.
I learned that creating all the sub-bites' sub-issues at once clutters my issue list without adding any value! Using this approach I have to work with only two issues: i) the main issue, and ii) the sub-issue in progress.\
- Navigate to the main-bite's main issue
- Generate the sub-issue
- Copy the name of the next sub-bite;
- Click on Create sub issue;
- Paste the name of the next sub-bite as the new sub-issue's Header;
- Add a Description, if you want it;
- Add you as the assignee
- Add Labels: enhancement, P1
- Save it;
- Note that, all sub-issues that I completed are marked as complete, whereas the newly created sub-issue in marked as open;
- Click on the newly created sub-issue link, in the Main Issue's list of sub-issue links;
- While in the sub-issue, I:
- Click on Create branch
- While in the Create a branch for this issue modal dialog, I
- Validate that:
- The Branch name is correctly formed, <<Issue #>><<bite #>>>
- The Repository destination is the one I'm working on (EnterpriseRemoteSystems);
- The Branch source is the expected branch; the default should be development;
- Click on Create branch
- Copy the command line instructions in the Checkout in your local repository modal;
- Validate that:
- While on Terminal 3, I
- Paste and execute the instructions to checkout the just created feature brach:
- While in the Create a branch for this issue modal dialog, I
- Click on Create branch
$ git fetch origin
$ git checkout <<branch name>>
We are ready to interact with ChatGPT to help us implement the sub-bite captured in the sub-issue.
Prompt ChatGPT to Write the issue
- Use gitzip to produce the branch name, its SHA, and save the branch's zip (gitzip)
- Assemble the Software Feature Request, see below:
- Copy this assembled message
- Paste the software feature request into the ChatGPT chat window;
- Drag the branch's zip to the ChatGPT chat window;
- Press the ChatGPT chat window Go button
- Wait for the ChatGPT response
Deploy ChatGPT Response
- ChatGPT includes its response in the Deliverables section of its reply, You will find to elements:
- A link to download the patch- click on the link
- Instructions to install the patch- install the patch
- Download the patch
- Follow the instructions to install it
- There are two set of tests you might have to run to validate the patch'
- Patch Related Tests - Read ChatGPT's response Validation results section and run the tests, if any, it asks you to run.
- Application tests - I run the makelocal script which runs i. go test ./... , local (vitest ), and e2e (playwrite ), and log the results to ~/Downlodads/ers-local-check.log ;
Process
Create the working feature branch
- Open the the Main Bite Github Issue;
- Use the Github Create sub-issue link to create the Main Bite sub-issue
- Click on the Main Bite's Issue link to the just created sub-issue
- Use newly created sub-issue Create a branch link to add the sub-issue working feature branch
- Double check the proposed Branch name shown in the Create a branch for this issue dialog box; rarely you will need to change it;
- Click on the Create branch green button;
- Copy the statements in the Checkout in your local repository dialog box
- Paste and execute them in the BL terminal prompt
- Copy the branch set up instructions offered by Github
- Paste and execute
- You now have Prompt ChatGPT for the software for the new feature:
- Run gitzip on the BL window
- $ gitzip
- Branch: 930-bite-332-backup-creation-retention-and-verification
- SHA: 05e9eff3b56c5a1308c17c131e188633e4e0e3b6
- Output: /Users/rodrigosilveira/Downloads/930-bite-332-backup-creation-retention-and-verification-05e9eff3.zip
- Created:
- /Users/rodrigosilveira/Downloads/930-bite-332-backup-creation-retention-and-verification-05e9eff3.zip
- Copy the Branch and the SHA
- Open the Text Editor's Request window
- Paste the Branch and the SHA over the existing ones
- Copy the name of the Issue associated with this branch
- Paste it over the previous Issue name
- Copy the whole thing
- Paste it in the ChatGPT prompt line
- Drag the just created ZIP file in the Downloads folder to the ChatGPT prompt line
- Press go ... Let ChatGPT do its work
creation of sub-issues, one at a time. As you can see in the example above, I completed Bite 31.1 and moved to implement Bite 33.2. If you look at Issue Bite 33, you will see a couple of sub-issues, 33.1 close and 33.2 open.
Do not add all the sub-issues at once, they clutter the environment.
Software Feature request
Header: Please provide the software to implement and test "Bite 33.6.6A — Production Application Administrator Emergency Access Recovery" Branch: <<branch name, from gitzip output>> SHA: <<SHA, from gitzip output>> ZIP: attached ChatGPT Software Submission
This is a format ChatGPT and I agree for ChatGPT to submit its proposed software changes. It is important to understand it as well as to read and agree with all submissions.
- SHA confirmation
- Diagnosis and implementation- How ChatGPT interpreted the request; read it and agree with it!
- Deliverables- Includes a link to download the patch, and the git commands to install it
- What changed- The files and logic used to implement the request. Read and understand it.
- Validation results- Sometimes it includes instructions for me to perform a quick validation
- Glossary- Any new concepts worthy of documentation
Request Title
I have a few options:
- New Requirement Request
- Requirement for Manual Tests
- Use Case Requirement
- Defect Fix Requirement New Requirement Request Note
- Please provide the software to implement and test "Bite 33.1 — Production Environment and Destructive-Operation Guardrails"
- Branch: 930-bite-332-backup-creation-retention-and-verification
- SHA: 8508b23ef6223d7eab039611cfd821eb55d7e78b
- ZIP: Attached Requirement for Manual Tests Use Case Requirement Defect Fix Requirement
Branch Name
Branch SAH
ZIP Attached (always)
Log Attached (when necessary)
Request details
Submission
Following are the sections I ask ChatGPT to include all their patch submissions:
- SHA confirmation - ChatGPT ensures that the SHA matches the ZIP; this is VERY important since ChatGPT will build the patch based on the attached ZIP file
- Diagnosis
- Patch
- What changed
- Validation
- Glossary impact
Scripts
gitzip
This is an executable script I have on a folder, which is included in the environment PATH
# Prints current branch name, commit hash,status of the current git repository,
# and saves it as a zip file.
# git branch --show-current
# git rev-parse HEAD
# git status --short
# rm ~/Downloads/branch.zip
# git archive --format=zip -o ~/Downloads/branch.zip HEAD
#!/usr/bin/env bash
set -euo pipefail
# Make sure we're inside a Git repository.
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
echo "ERROR: Not inside a Git repository." >&2
exit 1
}
# Refuse to archive if there are uncommitted changes.
STATUS="$(git status --short)"
if [[ -n "$STATUS" ]]; then
echo "ERROR: Working tree is not clean."
echo
echo "$STATUS"
echo
echo "Commit or discard these changes before creating the ERS source archive."
exit 1
fi
# Get current branch and committed SHA.
BRANCH="$(git branch --show-current)"
FULL_SHA="$(git rev-parse HEAD)"
SHORT_SHA="$(git rev-parse --short=8 HEAD)"
if [[ -z "$BRANCH" ]]; then
echo "ERROR: HEAD is detached; no branch name is available." >&2
exit 1
fi
# Make the branch name filename-safe.
SAFE_BRANCH="${BRANCH//\//-}"
OUTPUT="$HOME/Downloads/${SAFE_BRANCH}-${SHORT_SHA}.zip"
if [ -e "$OUTPUT" ]; then
rm "$OUTPUT"
echo "Existing $OUTPUT removed."
fi
echo "Branch: $BRANCH"
echo "SHA: $FULL_SHA"
echo "Output: $OUTPUT"
echo
git archive \
--format=zip \
--output="$OUTPUT" \
HEAD
echo "Created:"
echo "$OUTPUT"
makelocal
This is an executable script I have on a folder, which is included in the environment PATH.
#!/usr/bin/env bash
set -euo pipefail
make local-check 2>&1 | tee /tmp/ers-local-check.log
$ git fetch origin git checkout 943-bite-335-migration-deployment-recovery-gate From github.com:RodrigoMattosoSilveira/EnterpriseRemoteSystems
- [new branch] 943-bite-335-migration-deployment-recovery-gate -> origin/943-bite-335-migration-deployment-recovery-gate branch '943-bite-335-migration-deployment-recovery-gate' set up to track 'origin/943-bite-335-migration-deployment-recovery-gate'. Switched to a new branch '943-bite-335-migration-deployment-recovery-gate'
$ gitzip Branch: 943-bite-335-migration-deployment-recovery-gate SHA: c0db8c2944318b0959ef23e95d23c6577a777413 Output: /Users/rodrigosilveira/Downloads/943-bite-335-migration-deployment-recovery-gate-c0db8c29.zip
Created: /Users/rodrigosilveira/Downloads/943-bite-335-migration-deployment-recovery-gate-c0db8c29.zip
the patch
$ git apply --check
~/Downloads/943-bite-335-migration-deployment-recovery-gate-d4ad0ef5-fix-backup-contract.patch
rodrigosilveira@RMS-DEVELOPMENT[/Users/rodrigosilveira/projects/EnterpriseRemoteSystems]
$ git apply
~/Downloads/943-bite-335-migration-deployment-recovery-gate-d4ad0ef5-fix-backup-contract.patch
$ gitclean 'I'm .zshenv I'm ~/rmsrc/zsh/.zshenv From github.com:RodrigoMattosoSilveira/EnterpriseRemoteSystems
- [deleted] (none) -> origin/943-bite-335-migration-deployment-recovery-gate Deleting local branch: 943-bite-335-migration-deployment-recovery-gate Deleted branch 943-bite-335-migration-deployment-recovery-gate (was 806f2ec). Skipping excluded branch: development Skipping excluded branch: production Skipping excluded branch: test Done. Current branches:
- development production test remotes/origin/304-implement-i18n-infrastructure remotes/origin/933-test remotes/origin/HEAD -> origin/production remotes/origin/dev-pre-i18n-2207 remotes/origin/development remotes/origin/i18b-dev-05aug-currentacct remotes/origin/i18n-dev-05aug remotes/origin/i18n-dev-05aug-expenses remotes/origin/i18n-dev-05aug-planning remotes/origin/production
$ git fetch origin git checkout 945-bite-336-recovery-rehearsal-and-operational-runbook From github.com:RodrigoMattosoSilveira/EnterpriseRemoteSystems
- [new branch] 945-bite-336-recovery-rehearsal-and-operational-runbook -> origin/945-bite-336-recovery-rehearsal-and-operational-runbook branch '945-bite-336-recovery-rehearsal-and-operational-runbook' set up to track 'origin/945-bite-336-recovery-rehearsal-and-operational-runbook'. Switched to a new branch '945-bite-336-recovery-rehearsal-and-operational-runbook' rodrigosilveira@RMS-DEVELOPMENT[/Users/rodrigosilveira/projects/EnterpriseRemoteSystems] $ gitzip Branch: 945-bite-336-recovery-rehearsal-and-operational-runbook SHA: 4184842a89397d68f66caba0f4189bfb290b55e5 Output: /Users/rodrigosilveira/Downloads/945-bite-336-recovery-rehearsal-and-operational-runbook-4184842a.zip Created: /Users/rodrigosilveira/Downloads/945-bite-336-recovery-rehearsal-and-operational-runbook-4184842a.zip
Work Area
Steps to implement a main bite:
- Add its main-issue, representing the main bite; it includes references to each of its sub-bites;
- For each sub-bite:
- Add its sub-issue;
- Add the sub-issue branch;
- Check out branch;
- Request ChatGPT to submit the software patch to implement the sub-bite;
- Apply the patch;
- Check in the patch
- Test the patch locally
- Request ChatGPT to submit the manual tests to validate the software patch;
- Execute the manual tests
- Merge the sub-issue branch into the development branch
- END Implement main-bite Steps:
- Record its main-issue:
- Header: The name suggested by ChatGPT, prefixed with the bite number.
- Description:
- Top - A list of the sub-bites' headers, with their names prefixed with their bite number;
- Below - The ChatGPT discussion about the main bite; it could be lengthy, it is worth capture and read it;
- For each sub-bite:
- Record its sub-issue:
- Description:
- Top - A list of the sub-bites' headers, with their names prefixed with their bite number;
- Below - The ChatGPT discussion about the main bite; it could be lengthy, it is worth capture and read it;
- Description:
- Record its sub-issue:
# Prints current branch name, commit hash,status of the current git repository,
# and saves it as a zip file.
# git branch --show-current
# git rev-parse HEAD
# git status --short
# rm ~/Downloads/branch.zip
# git archive --format=zip -o ~/Downloads/branch.zip HEAD
#!/usr/bin/env bash
set -euo pipefail
# Make sure we're inside a Git repository.
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
echo "ERROR: Not inside a Git repository." >&2
exit 1
}
# Refuse to archive if there are uncommitted changes.
STATUS="$(git status --short)"
if [[ -n "$STATUS" ]]; then
echo "ERROR: Working tree is not clean."
echo
echo "$STATUS"
echo
echo "Commit or discard these changes before creating the ERS source archive."
exit 1
fi
# Get current branch and committed SHA.
BRANCH="$(git branch --show-current)"
FULL_SHA="$(git rev-parse HEAD)"
SHORT_SHA="$(git rev-parse --short=8 HEAD)"
if [[ -z "$BRANCH" ]]; then
echo "ERROR: HEAD is detached; no branch name is available." >&2
exit 1
fi
# Make the branch name filename-safe.
SAFE_BRANCH="${BRANCH//\//-}"
OUTPUT="$HOME/Downloads/${SAFE_BRANCH}-${SHORT_SHA}.zip"
if [ -e "$OUTPUT" ]; then
rm "$OUTPUT"
echo "Existing $OUTPUT removed."
fi
echo "Branch: $BRANCH"
echo "SHA: $FULL_SHA"
echo "Output: $OUTPUT"
echo
git archive \
--format=zip \
--output="$OUTPUT" \
HEAD
echo "Created:"
echo "$OUTPUT"$ gitzip
Existing /Users/rodrigosilveira/Downloads/991-bite-3366a-gate-b-standardized-containerized-recovery-environment-845efc72.zip removed.
Branch: 991-bite-3366a-gate-b-standardized-containerized-recovery-environment
SHA: 845efc72e873874312c5f295e15740076387ed53
Output: /Users/rodrigosilveira/Downloads/991-bite-3366a-gate-b-standardized-containerized-recovery-environment-845efc72.zip
Created:
/Users/rodrigosilveira/Downloads/991-bite-3366a-gate-b-standardized-containerized-recovery-environment-845efc72.zip
#!/usr/bin/env bash
set -euo pipefail
make local-check 2>&1 | tee /tmp/ers-local-check.logExamine the ers-local-check.log file it creates; it is useful when submiting error descriptions to ChatGPT.