Creating a project
--path is what connects the project to a folder. Since 0.16.0 that folder is how base knows which project a file belongs to: touching a file inside it loads the project’s own rules, with no trigger needed. A project without a path still exists, it just has no way to notice you are working on it.
base project list shows each project’s path, its parent and whether it is nested, and its next step with how old that step is.
The gotcha. If you omit --path and the protocol configuration is not enabled, the project has no folder at all. base project list --unscoped finds these later, and they are usually a mistake rather than a choice.
Milestones and tasks
base task tag <slug> --add urgent attaches free-form labels, and base task list --label urgent --label backend narrows to tasks carrying all of them. Repeating --label intersects rather than unions.
Editing instead of recreating
--next-action is the field that decides whether a project is resumable. A project with a status and no next action tells you it is alive and nothing else. Since 0.16.0 a next step carries its age, and base doctor lists the ones older than [doctor] stale_next_days (14), with the command that rewrites each. Steps written before 0.16.0 carry no date and are listed as undated.
A project inside another
--parent links a project to the one it sits inside. --nested true says work in the inner project also carries the outer project’s rules; --nested false, the default, says it does not. Each project carries its own setting, and base project add takes both flags too. A parent must be a registered project, a link that would close a loop is refused, and --parent none removes the link. base never guesses the link from folders.
With --nested true, a file in the inner project brings the inner project’s rules first, then the outer project’s, labelled [FILE MATCH: portal (parent of portal-api)]. A tight budget drops the parent’s rules first.
When a folder moves
base project update billing-service --path ~/services/billing does the same since 0.16.0: the path is stored absolute and the project’s domain trigger moves with it.
The gotcha. Do this whenever a folder moves, even if the project still “works”. The failure is silent and looks like base having stopped caring about that project.
Finding each project’s real folder
--suggest lists every project whose folder is missing, not a folder, too broad, or contradicted by its own docs, with a suggested folder and the evidence; a project with two candidates gets both. It writes nothing. --apply sets the folders in a list you reviewed, and any bad line refuses the whole file.
Renaming a project
--yes it renames the project and its same-named domain together, in the global tier and in the workspace you stand in: the records, the decisions, tasks, milestones and rules keyed by the old name, a handoff’s project field, and the domain’s name in domains.toml. It backs up every file it writes first.
The old name keeps working: --domain billing-servce, base project get billing-servce and the rest reach the renamed project and print billing-servce is now billing-service. Prompt keywords are never changed, so the old spelling stays a keyword if it was one.
One project, two workspaces
--yes.
Finding a project you cannot find
base project list shows the current workspace only. A project missing from it is usually a project that now lives in another workspace, not a project that is gone. Check --all before concluding anything.
Deleting, and what goes with it
--yes.
The gotcha.
project delete --force takes the decisions and rules as well, and those are usually the part you would actually miss. The tasks are replaceable; the reasoning behind a choice made eight months ago is not.
Bringing state back in line
--dry-run first, always. It decides from filesystem activity, so a project you have been working on outside its registered folder looks dormant when it is not.
Deferred work
Work nobody has touched in a while can stop crowding session start without being archived. It is off until you turn it on:[defer] enabled = true, a handoff, fork, task or milestone untouched for a set number of days (10 by default, per kind under [defer.days], or [defer] global_days for all) stops showing at session start and stays listed. Each deferred list gives every row the command that brings it back; base handoff show and base fork show bring one back too, and so does touching it. Projects already deferred under [protocol]; base project deferred lists them with the date each was deferred.
Before you turn it on. Records from before 0.16.0 never had their activity clock kept, so a lot of live work would look cold at once. base defer migrate previews which records it would reset and writes nothing; base defer migrate --apply resets them, --limit <N> and --older-than <D> stage it, and --rollback restores every tier it wrote from the snapshot it took first.
Next
Multiple sessions
Coordinating when more than one session is working the same project.
Projects reference
Every flag on every command here.