State Files and Validation
AI Business OS keeps a register of your projects in one file, .claude/state/state.json. The daily commands read it to brief you and write to it to record what happened, so it is the workspace’s memory of what you are working on. This page explains what the file holds, how AI Business OS forms project IDs, and how backups and validation protect it.
The Files
Section titled “The Files”| File | What it is |
|---|---|
.claude/state/state.json |
The project register. Your file, never changed by /update |
.claude/state/state.schema.json |
The schema that describes a valid register |
.claude/state/backups/YYYY-MM-DD.json |
Daily backups, kept on your computer only |
.claude/state/history/YYYY-MM.json |
The session history archive, one file per month |
Scripts/backup-state.sh |
Makes a backup |
Scripts/validate-state.sh |
Checks the register |
Scripts/archive-history.sh |
Moves older session history into the monthly archive |
The same three scripts also ship in Infrastructure/Scripts/prima/, and both copies do the same job. /save uses that copy, and the other commands use the copies in Scripts/.
The register is plain JSON, written with the jq tool through a temporary file, so any agent or editor can read it.
What the Register Holds
Section titled “What the Register Holds”| Field | What it holds |
|---|---|
version |
The version of the register format. Required |
workspace |
The workspace’s name, id, type and githubRepo. Required |
projects |
One entry per project. Required |
nextProjectNumber |
A counter /newproject takes into account when numbering |
sessionHistory |
Short summaries of this calendar month’s sessions, newest first. Earlier months move to the monthly archive |
priorities |
Lists for immediate, thisWeek and upcoming |
pendingItems |
Open items carried between sessions |
recentWork |
Three to five activities from the latest session, replaced by each /night |
selectedCalendars |
The calendars /day reads, each written as an object with a name and, when known, an id |
The workspace type is one of personal, client or internal. The id uses lowercase letters, numbers and hyphens only. /setup fills in the workspace block, and /sync uses githubRepo to check it is pushing to the right repository.
What a Project Entry Holds
Section titled “What a Project Entry Holds”Every project entry needs four fields.
| Field | Values |
|---|---|
id |
The project ID, such as P012 |
name |
The project name, such as Spring Workshop |
status |
in-progress, paused, overdue or archived, and nothing else |
category |
client, product, internal, marketing, research, operations, finance, sales, legal or it |
The optional fields are description, priority (high, medium or low), created, dueDate, lastWorked, stoppedAt, lastAction, pausedReason, tags, path, notes, companyName and contacts. In a workspace with the domain layout, /newproject also records a domain.
Some fields have conditions attached.
- Paused projects. A paused project needs a
pausedReason, and every other project has none. - Client projects. A project in the
clientcategory needs acompanyNameand at least one name incontacts. Full contact details belong in PRIMA CRM if you use it. - Continuity.
stoppedAtrecords where work stopped andlastActionthe last thing completed./nightsets them, andstoppedAtclears when the project is next worked on.
A project entry for an invented workspace looks like this.
{ "id": "P012", "name": "Spring Workshop", "description": "Plan and deliver the spring workshop for Example Consulting's clients", "status": "in-progress", "priority": "medium", "created": "2026-10-14", "dueDate": "2027-03-31", "lastWorked": "2026-10-14", "stoppedAt": null, "lastAction": "Project created", "pausedReason": null, "category": "internal", "tags": ["events", "training"], "path": "Domains/15 Education & Training/P012 Spring Workshop", "domain": "15 Education & Training", "notes": ""}How Project IDs Are Formed
Section titled “How Project IDs Are Formed”/newproject takes the ID format from the IDs already in the register.
- An empty register. The first project is
P001, and numbering continuesP002,P003and so on. - A register in one format.
/newprojectcontinues that format, whatever it is. A workspace that already usesPRJ-0001keeps using it. - A register with two formats.
/newprojectstops, shows you one example of each, and asks which to use. It creates nothing until you answer.
The new number is the highest existing number plus one, or nextProjectNumber if that is higher. AI Business OS never reuses an ID, even after you archive a project, and never changes an existing ID. If the next number needs more digits than the format allows, such as P1000, /newproject stops and tells you. It does not widen the format.
Which Commands Use the Register
Section titled “Which Commands Use the Register”| Command | What it does with the register |
|---|---|
| /setup | Writes the workspace block and the selected calendars |
| /newproject | Adds the project entry and moves nextProjectNumber on |
| /day | Reads projects for the briefing, and can archive, pause or resume a project when you ask |
| /status | Reads projects for the report, and can archive a project and move its folder to Archive/ |
| /night | Records the session summary, lastWorked, stoppedAt and lastAction |
| /save | Records progress mid-session |
| /resume | Reads where you left off |
| /dashboard | Reads the register to build the HTML dashboard |
Backups
Section titled “Backups”Before any command writes to the register, it runs the backup script.
bash Scripts/backup-state.shThe script copies the register to .claude/state/backups/ under the day’s date, such as 2026-10-14.json, and deletes backups older than 30 days.
Session History Archive
Section titled “Session History Archive”The session history holds the current calendar month only. After /save and /night write the register, archive-history.sh moves every entry from an earlier month into the archive file for that month, such as .claude/state/history/2026-07.json, so no entry is ever deleted. Each archived entry keeps its date and summary and gains an archivedFrom field that names the workspace or the project it came from. Run bash Scripts/archive-history.sh --dry-run to see what it would move without changing anything.
Validation
Section titled “Validation”After every write, the command runs the validation script.
bash Scripts/validate-state.shSome problems fail the check, and the command restores the backup and reports the error. Others only print a warning, and /save and /night show every warning in their report so that none goes unseen.
| Check | Result if it fails |
|---|---|
| The file is valid JSON | Fails |
version, workspace and projects are present |
Fails |
The workspace type is personal, client or internal |
Fails |
| Every project ID is unique | Fails |
| Every project ID has the form of letters, an optional hyphen, then three to six digits | Fails |
| Every status is one of the four allowed values | Fails |
The register matches the schema, checked only when the ajv validator is installed |
Fails |
| The workspace name, ID and type are all filled in | Warning |
| No two projects share a name | Warning |
| All project IDs use one format | Warning |
| Every project has a valid category | Warning |
| Every paused project has a reason | Warning |
| Session history holds no entries from an earlier month | Warning |
Every archive file in .claude/state/history/ has an entries list |
Fails |
A clean run ends with a count of projects by status and the line State validation passed. This is the output for the sample register that ships with a new workspace.
JSON syntax validRequired fields present (version: 1.0.0)Project IDs uniqueProject ID format validStatus values validProjects: 3 total (3 active, 0 paused, 0 overdue, 0 archived)INFO: ajv-cli not installed — schema validation skipped
State validation passedRestoring a Backup
Section titled “Restoring a Backup”If the register is damaged, you can ask Claude to restore it from a backup and name the date you want. To do it yourself, follow these steps from the workspace folder.
- List the backups with
ls .claude/state/backups/. - Copy the backup you want over the register, for example
cp .claude/state/backups/2026-10-13.json .claude/state/state.json. - Run
bash Scripts/validate-state.shand check that it passes. - Commit the restored file with
/sync.
You lose any change made to the register after that backup, so check stoppedAt and lastAction on the projects you worked on since.
With PRIMA Project Management
Section titled “With PRIMA Project Management”PRIMA Project Management takes over the state schema, the State Validation rule and the two scripts in Scripts/. See State Files Explained if you have it installed.

