initialize-atlas
Bind a project to its vault Workspace and ensure that workspace is scaffolded correctly. Idempotent and self-healing — safe to run repeatedly.
Primary agent only. If you were dispatched as a subagent, stop here.
1. Resolve the vault
The vault is always the atlas vault; its location is the ATLAS_PATH environment variable — there is no registry and no per-repo vault config.
- If
ATLAS_PATHis set and the directory exists, use it as the vault root. - If
ATLAS_PATHis unset, ask the user toexport ATLAS_PATH=<their atlas vault root>(offer~/vaults/atlasas the conventional default), then continue.
Scaffold the vault skeleton if missing (see resources/vault-structure.md):
.norn/config.yaml— norn is the vault-write authority for Atlas knowledge and consolidation, so the vault must carry a norn config. If missing, seed it fromtemplates/norn-config.yaml; never overwrite an existing config.artifacts/scratch/(nogenerated/; Session Summaries live in Mimir).Workspaces/shared/withuser.md(User Profile) andmemory.md(Shared Memory). Create each missing one through norn so it carries its dedicated schema type from birth (NOW=$(date +%Y-%m-%dT%H:%M)):norn -C "$ATLAS_PATH" new "Workspaces/shared/user.md" \ --field title="User Profile" --field description="<one line>" \ --field type=user-profile --field workspace=shared \ --field created="$NOW" --field modified="$NOW" --body-from-stdin --yes < <body> # memory.md → --field type=shared-memorySeed
user.md/memory.mdbodies lightly; a short user-profile interview can filluser.mdlater. If an older profile exists, offer to copy and curate it into the two files rather than migrating in place.
2. Resolve the workspace name
- Use the
<workspace>argument if given; else infer from the repo directory name and confirm. - A Workspace maps 1:1 to a project, bound by name + path.
3. Elevator-pitch description
Get a 2–3 sentence description of the project, in priority order:
- From an existing Workspace Brief (if re-initializing).
- From the repo's
CLAUDE.md/AGENTS.md. - Else scan the repo and infer one.
Confirm it with the user (offer to edit). It becomes the Brief's description and opening paragraph.
3b. Workspace type
Pick the Brief's workspace_type — the vault's workspace-note rule requires it, and it has no safe default. Propose the best fit from the repo, then confirm with the user (on re-init, keep the existing value unless it's wrong):
workspace_type |
When it fits |
|---|---|
| product | A single shippable system (app, site, service, infra) with one roadmap and task board. |
| library | Reusable code consumed by other projects — no standalone runtime, a single publishable surface. |
| monorepo | One repo housing multiple products, each with its own roadmap and task board. |
| incubator | Holding area for early ideas/sketches/tests before they graduate to their own workspace or are dropped. |
4. Scaffold / heal the workspace
Under $ATLAS_PATH/Workspaces/<workspace>/, ensure these exist — create only what's missing; never overwrite existing content:
<workspace>.md— Workspace Brief. Compose the body fromtemplates/workspace-brief.md(substitute{{WORKSPACE}},{{ELEVATOR_PITCH}}), then create it through norn:norn -C "$ATLAS_PATH" new "Workspaces/<workspace>/<workspace>.md" --field title=<workspace> --field description="<elevator pitch>" --field type=note --field kind=workspace --field workspace="[[<workspace>]]" --field status=active --field workspace_type=<workspace_type> --field domain=Workspaces --field created="$NOW" --field modified="$NOW" --body-from-stdin --yes < <body>. Thestatus/workspace_type/domainfields and the wikilinkworkspacesatisfy the vault'sworkspace-noterule (status=activefor a new binding;workspace_typefrom §3b;domainis alwaysWorkspaces). After creating it, stamp an initialbrief_baselineinto its frontmatter — its own scaffolded size — so a brand-new workspace starts within budget andstart-sessiondoesn't recommend a consolidation that has no logs to process. Measure it the same wayconsolidate-workspacedoes (code-point count, notwc -m):python3 -c 'import pathlib,sys; print(len(pathlib.Path(sys.argv[1]).read_text(encoding="utf-8")))' "<brief path>", then stamp it with norn (pin the vault — norn resolves from$NORN_ROOT/cwd, neverATLAS_PATH):norn -C "$ATLAS_PATH" set "Workspaces/<workspace>/<workspace>.md" --field-json brief_baseline=<chars> --yes(anunknown fieldwarning is benign).consolidate-workspacerefreshes it on every groom thereafter.glossary.md— Generated by thedomain-modelingskill (replacesCONTEXT.mdif present). If that skill isn't installed, create a placeholder through norn (norn -C "$ATLAS_PATH" new "Workspaces/<workspace>/glossary.md" --field title="Glossary" --field description="Domain terms for <workspace>" --field type=note --field kind=glossary --field workspace="[[<workspace>]]" --field created="$NOW" --field modified="$NOW" --body-from-stdin --yes) with a note to rundomain-modeling.decisions/,notes/,archive/
Local override. If the repo sets
decisions = "local"(or a path) in.atlas.toml, scaffolddecisions/+glossary.mdat that in-repo target instead of in the vault workspace.
If everything already exists and is consistent, report: "Your workspace is already initialized to <full path> and everything looks correct." Otherwise apply only the missing pieces and say what you added.
5. Write the Project Binding
Write .atlas.toml at the repo root:
workspace = "<workspace>"
# decisions = "local" # optional: keep decisions/glossary in-repo instead of the vault workspace
Ask whether to commit it to git (default: no — ensure it's in .gitignore).
6. Permissions (harness-specific)
Ensure the agent can read/write the vault paths. In Claude Code, add the vault globs to .claude/settings.local.json. Re-running initialize-atlas under a different harness adds that harness's needs.
7. Finish
- Fresh init: hand off to start-session to load the new context.
- Heal: just report what changed.