You have a folder with a README and one commit. Now the code starts, and the rule for this lesson is the one from building turn by turn: get an ugly version working end to end before you improve anything.
Step 2: the ugly version
Create index.html and app.js. A form with a text field and an Add button adds a habit to a list on the page. Each habit has one checkbox for today. Record each tick as the day in YYYY-MM-DD form, in my local time zone. Keep everything in memory for now: no saving, no styling.
No saving and no styling are deliberate. Saving is the next turn. Styling is three turns away. This turn is only about the path from typing a habit to ticking it.
Run it
Open index.html in your browser. Add two habits. Tick one. Reload the page.
Both habits are gone. That is correct for this step: the prompt said in memory only. If they survived, the agent did more than you asked, and the diff will show where.
Read the diff
You do not need to understand every line. Look for two things.
How the name reaches the page. Find the line that puts the habit’s name into the list. If it uses innerHTML with the name in it, a habit called <b>Read</b> turns bold instead of showing the brackets: the browser is treating what you typed as code. Ask for textContent instead. It is a one-line fix and a habit worth having.
How today’s date is made. If you see toISOString(), that is the date in UTC, not where you are. Depending on your time zone, a tick late in the evening or early in the morning lands on the wrong day, and your streak breaks for no visible reason. Ask for the date to be built from the local year, month and day.
Quick check
The code makes today's date with toISOString(). What goes wrong?
Commit it
Checkpoint: step 2 in the reference repository. It uses textContent for the name and builds the day from the local date, with a comment saying why. Your version will look different. The behaviour should not.
Step 3: make it remember
Save the habits in localStorage so they survive a reload. If what is stored is missing or broken, start with an empty list instead of crashing.
The second sentence matters. Saved data is something your code reads back later, and by then it may have been cleared, half-written or edited by hand. A page that crashes on bad data is a page that shows a blank screen the day it happens, with nothing to tell you why.
Run it
Add a habit, tick it, reload. Still there. Close the tab, open the file again. Still there.
Now break it on purpose. Open your browser’s developer tools, find the storage panel and the Local Storage entry for the page, and change the saved value to nonsense, a word with no brackets. Reload. You should get an empty list, not a blank page and not an error.
Read the diff
localStorage only stores text, so the habits have to be turned into text on the way in and back on the way out. You will almost certainly see JSON.stringify when saving and JSON.parse when loading. Check that the parsing sits inside something that catches errors, a try block, because JSON.parse on nonsense throws, and an uncaught throw stops the script.
Also check what is saved: the list of habits and the days they were ticked. Nothing else should be there.
Last, check the name it is saved under, the storage key. It should be specific to this app. Every page on the same site shares one storage area, so a generic key like data is one another app could overwrite.
Commit it
Checkpoint: step 3 in the reference repository. The loader returns an empty list for anything it cannot read, and saving is wrapped too, so a browser that blocks storage still gets a working page that simply does not remember.
If a turn goes wrong
Do not patch a bad turn with another turn. Throw it away by going back to your last commit, then ask again with a sharper prompt. The commit you made after step 2 is exactly what makes that a single command instead of an afternoon of untangling.
What you have now
A page that works, remembers, and looks terrible. That is the right place to be. The next lesson adds the parts that make it worth opening every day, one turn each.
My agent added styling in step 2 anyway. Is that a problem?
Only in that the diff is bigger than it needed to be. You can keep it, or ask the agent to take it out so this commit does one thing. What matters is that you noticed, because the next unrequested extra may not be harmless.
Do I need a local server to open index.html?
No. For this project, opening the file directly in the browser works. If your browser refuses to save anything when the page is opened as a file, the published version in the last lesson will behave normally.
Why does the agent keep wanting to add a framework?
Because many examples it learned from use one. Your not-doing list says plain HTML, CSS and JavaScript, so point at it and decline. A framework would add a build step and dependencies this project does not need.